From 4d48f9d23713d94b861da7b5d41baf2a41334994 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Sat, 12 Aug 2023 20:17:29 +0200 Subject: [PATCH] Squashed 'external/sdl/SDL/' changes from b8d91252c6..ec0042081e ec0042081e Add .gitattributes file a5d9db0cd0 cmake: build tests for UWP b7889a7389 winrt: use windowsio in non-libc mode ea8757a748 Make testaudiostreamdynamicresample compatible with emscripten 1a7a74fb2e cmake: build emscripten tests as html page 64d570f027 Add minimal http server for emscripten test apps 8e898c4a21 SDL_test does not parse --samples argument 91cd5478be audio: Fix resampler overflowing input buffer. f290c85b22 testaudiocapture: Make sure we convert captured audio to output format. b75c751dfc rwlock: Make generic implmentations work on single-threaded platforms. 80850af7ce The controller update complete events are no longer disabled by default 3f486224a9 Fixed refresh rate calculation for KMSDRM 342ec51131 Fix overflow when doing SDL_sscanf("%hd", ...) 9129e1d557 Fixed crash when setting the default cursor twice 8e99a4f4f5 Undo variable rename be67f0de10 Fixed crashes related to the default cursor on WinRT and KMSDRM 94b3f78c44 Fix out of bound read of 'has_hat' array 94f48f19b0 Use more specific build destinations when creating an xcframework dabd45997e Back out change supporting multiple names for binding elements efe15588d5 Relabel back paddles as left or right be884f0c95 ci: disable visionos.yml by renaming the file ac094d00f5 ci: add workflow_dispatch event to visionos workflow 9be9e2292b build: Consistently use pathlib APIs in cmake/xxd.py a9f6950657 Fixed deadlock shutting down Android sensors d9f09e77f2 Actually make the sensors magical! 690eae7d22 Implement visionOS support e385d6da0a Fixed build warning 6b93e788fa Improved sensor thread-safety 4ee0e5a984 Fixed thread-safety warnings 12deed91f8 Added information on how to enable thread-safety analysis 5735d2b03b coreaudio: Fixed assertion when device fails/quits mid-iteration. 1022fd6e04 testaudio: the test framework opens an audio device at startup; close it. 0714da37a4 audio: Fix audio stream callback calculations when future buffer has space. 917e036f6f MSVC has __declspec(deprecated) 279ff8909f Changed example code to avoid potential divide by zero 8a1afc9b10 Fixed Android not sending controller event timestamps 463c456b98 Fill the correct member with the joystick ID in SDL_EVENT_JOYSTICK_UPDATE_COMPLETE 55cf1abaa6 test: Don't flag testsurround as suitable for non-interactive use a2d594269c Fixed pixel format compatibility with SDL2 79a190aa23 Fixed setting invalid bpp for FOURCC formats in SDL_GetMasksForPixelFormatEnum() 8fdebdd3e0 Sync SDL3 wiki -> header b903ccf945 SDL_rwops read/write functions return size_t again c03f5b4b69 Fixed rounding up in SDL_PrintFloat 75a020aa6b Only query serial number and firmware versions from Sony PS5 controllers fa189d302e Added the Victrix Pro FS for PS4/PS5 to the controller list 26205b659d Fixed PS4/PS5 touchpad for third party controllers 6af0448af9 include: fixed a typo in SDL_RenderGetMetalCommandEncoder docs. f3cb46b083 SDL_thread.h: do not conflict with sdl2-compat::sdl3_include_wrapper.h 080b1dfbdb Revert "Improved fallback for SDL_COMPILE_TIME_ASSERT() (thanks @icculus!)" 9d453daa23 Improved fallback for SDL_COMPILE_TIME_ASSERT() (thanks @icculus!) 1fb2419882 Removed reference to renamed function e7d56dd0b2 audio: Renamed new API SDL_UnpauseAudioDevice to SDL_ResumeAudioDevice. 2b0c0f5b6b Don't pass NULL to strncmp 778e8185cd Fix size of memcpy in SDL_AudioDeviceFormatChangedAlreadyLocked And add diagnostic that allows to find this kind of issue in clang-tidy 4bb426abad Sync SDL3 wiki -> header 3a752ce650 Reapply "Changed 'freesrc' parameter from int to SDL_bool" to SDL_wave.c 2ba03b4db0 fix build after previous commit. 0026adffd4 apply force_align_arg_pointer attribute to correct version of SDL_RunApp 77446e2029 Unaligned stacks on i686-w64-mingw32 may lead to crashes d3bcc3f057 Fixed build errors when OpenGL isn't enabled 35ad68e126 Sync SDL3 wiki -> header 70323a8350 Add a function to display the system menu for a window be5f66c84e testaudio: Fixed soundboard icon, which had a colorkey issue. c0a88930bf Sync SDL3 wiki -> header 18c59cc969 Merge the SDL3 audio subsystem redesign! 99b0e31788 The Steam Controller D-Pad is only pressed when the button is pressed down 103073d694 Set NSBluetoothAlwaysUsageDescription for testcontroller ca02bb6c8c We don't need testdropfile-Info.plist e063f662e9 Enable the controller update complete events 06bea1eb55 Added a gamepad mapping for the G-Shark GS-GP702 5ca3c50bf0 testaudio: Fix compiler warning. 1b1f02c5aa testaudio: Apparently compilers don't like this possibly being NULL now...? 2de9253b6c test: Added testaudio fb3ab3f113 SDL_video.c: move ngage video before offscreen. 843572d993 Don't mark autorelease keys as virtual 648de4f9b8 Fixed duplicate key press/release events on iOS a8abe612ed Only pass keypresses up the responder chain when text input is active c3288d113e Synchronize on-screen keyboard state with text input active state 5fb92ef2f7 Fixed whitespace f5ea6ae18d Revert "Stop beep when running iOS apps on ARM-based Macs" 546508b9b4 Allow test programs to run at full resolution on iPads 68a4bb01e0 Allocate displays as an array of pointers instead of an array of objects 07578fde3d Fixed crash if a display is enumerated twice a509771a87 fix ios CI workflow after commit e4460e897f 72ce76905a The scheme isn't always the same as the framework name (e.g. xmp_lite vs xmp-lite) e4460e897f By default Xcode expects the framework target name to be the name of the project. ac683773dc Added missing tests to the "All" target 7dd56eaafe Removed unnecessary reference to testoverlay-Info.plist e1c7f524ef Reduce the number of times SDL3 is duplicated in the xcframework script 65538011ca Make Xcode targets more specific efe114c300 Revert "Renamed the xcframework target from "SDL.xcframework" to "xcframework"" 73ed1d21a9 Renamed the xcframework target from "SDL.xcframework" to "xcframework" 76b4d8a0d8 Build the Framework instead of a static library for iOS and tvOS d1bf979160 Removed unnecessary setting from the "Create DMG" target c94cb3a5d8 Simplified the Xcode project to a single Framework target ea60474c65 cmake: don't build SDL3-static Apple framework 8f00d7856d Sync SDL3 wiki -> header d4a867a256 Rename SDL_GetPath to SDL_GetUserFolder 71099149b8 Fall back to Xlib if XRandR isn't available b7f32f74ce Note the removal of the SDL_RENDERER_TARGETTEXTURE flag 0eda582160 testaudiostreamdynamicresample: Load sample.wav correctly. 87eae9a0a1 aaudio: We need a mixbuf on capture devices, too. fb68e84646 wayland: Fix memory leaks b0edd23c00 testsurround: Log available audio output devices at the start. ae3090c387 androidaudio: Move Init/bootstrap code to bottom of source code. 18fc0db9e5 aaudio: Rearranged source code to match other backends. 2507c1d68b aaudio: Disconnect playing devices if error callback fires. 32a3fc3783 aaudio: Use the callback interface. b49ce86765 audio: Fixed compiler warning on Android NDK. 1c074e8d97 android: Fixed audio device detection. 82ce05ad01 pulseaudio: Be more aggressive with hotplug thread synchronization. 5cbdf1168e androidaudio: Fixed incorrect JNI call (thanks, @madebr!) 660054f3dc include: Correct comment about audio device hotplug events. ab68428a64 aaudio: Fixed for older SDKs and Android releases. 5ff87c6d4a android: Reworked audio backends for SDL3 audio API. 54af687210 testautomation_audio.c: Patched to compile. :/ 5e82090662 testautomation_audio.c: Apparently we aren't updating test code for C99 atm. 7f4488f625 wasapi: More fixes for Clang warnings. 29a0c689c9 wasapi: Patched to compile with Clang. 4aa95c21bc pspaudio: Patched to compile. 9a2a0a1463 ps2audio: Delete errant character that got inserted before previous commit. 2c578bd0d5 qnxaudio: Rewrite for SDL3 audio APIs. 455eef4cd9 audio: Use AtomicAdd for device counts, don't treat as a refcount. 095ea57f94 pspaudio: Patched to compile. d7cf63db67 ps2audio: Patched to compile. 027b9e8787 coreaudio: (maybe) patched to compile on iOS. 4836c2db07 pspaudio: Patched to compile. 86ca412436 n3dsaudio: Patched to compile. 66bcee2ca9 testaudiostreamdynamicresample.c: Fixed MSVC compiler warning. dbf993d358 vitaaudio: patched to compile. 5707e14716 audio: Fix up some things that broke when rebasing the branch against main. 6567285eae SDL_migration.cocci: Fix up SDL_(Pause|Unpause)Audio. 0b6255551e test: Fixed incorrect SDL_OpenAudioDevice call in testautomation. 107fd941cd vitaaudio: Clean up correctly in CloseDevice. 9fa4a6ef87 netbsdaudio: Minor fix. b0d89868c6 n3dsaudio: Updated (but untested!) for SDL3 audio API. ba27176106 vitaaudio: Untested attempt to move Vita audio to SDL3's audio API. 0b58e96d9e wasapi: Patched WinRT to compile. d6b4f48488 visualc: Turn on multiprocessor compilation. c58d95c343 wasapi: Reworked for new SDL3 audio API, other win32 fixes. dc04f85646 audio: whoops, that should be an int. be0dc630b7 audio: Fixed incorrect assertion 77b3fb06ee directsound: First shot at updating for SDL3 audio API. 4399b71715 audio: Generalize how backends can lookup an SDL_AudioDevice. 2fb122fe46 audio: backends now "find" instead of "obtain" devices by handle. c3f5a5fc72 dummyaudio: SDL3ify style 7d65ff86e2 diskaudio: Adjusted for later SDL3 audio API redesign changes. 4ba9c2eade dummyaudio: Configurable delay, other SDL3 API fixes. fb395d3ad7 sndio: Updated to the SDL3 audio API. 1a55282051 dsp: Some minor logic fixes 6bc85577d7 netbsdaudio: Updated for SDL3 audio API. 0f6e59312b netbsdaudio: Removed email address from source code. 51ae78c0af haikuaudio: Updated for SDL3 audio API. fc7ed18ca1 emscriptenaudio: don't forget to finalize the audio thread 4233c41ce2 pulseaudio: Removed unnecessary variable. a0528cd5ed emscriptenaudio: Updated for SDL3 audio API. 79cc29ba35 wave: Don't check if format->channels > INT_MAX, it's a Uint16. 1bfe97c235 pspaudio: Updated for SDL3 audio API. 121a2dce15 audio: Make sure `device->hidden` is NULL after CloseDevice 3d6ba0cafd ps2audio: Removed free of buffer that hasn't been allocated yet. 00ed6f8827 test: Fixed compiler warnings for unused vars. 6f12f68ec9 ps2audio: SDL3ified the style 4993743a02 ps2audio: Renamed `_this` to `device` 74568cdb2b ps2audio: Updated (but untested) for SDL3 audio API. c83b68ef26 jack: renamed `_this` to `device`. 3f4f004794 audio: Remove an assertion that no longer makes sense. 86243b2589 jack: Use ProvidesOwnCallbackThread. 18906a32b8 jack: First shot at updating for SDL3 audio API. a2b488359e dsp: Removed debug logging 6fd71185cd dsp: Updated for new SDL3 audio API. 3482d1215a alsa: Don't ever block in CaptureFromDevice. 65d296ef1a audio: Use SDL_powerof2 instead of reinventing it. 409b544505 alsa: Updated for new SDL3 audio API 0999a090a7 audio: More tweaking of `device->thread_alive` f94ffd6092 audio: Fixed logic error 4deb2970c9 alsa: Renamed `_this` to `device` 0fb9e4baae audio: Remove no-longer-used SupportsNonPow2Samples c653e57768 coreaudio: rewritten for SDL3 audio redesign! 533777eff5 audio: SDL_sysaudio.h comment conversion. 8473e522e0 audio: unify device thread naming. 258bc9efed audio: PlayDevice now passes the buffer, too, for convenience. e518149d14 audio: Fixed locking in SDL_AudioDeviceDisconnected 22afa5735f audio: FreeDeviceHandle should pass the whole device, for convenience. 9e3c5f93e0 coreaudio: Change `_this` to `device` e969160de0 audio: unset a freed variable to NULL 1fc01b0300 audio: Try to definitely have a default device set up. b60a56d368 audio: take first reported device if no default was specified. a8323ebe68 audio: Better handling of ProvidesOwnCallbackThread backends. 1dffb72c1d pipewire: Hooked up default device change notifications. a93fcf2444 audio: fixed flushed stream reporting bytes but not being able to get them. ad6c1781fc pulseaudio: Minor cleanups. cfc8a0d17d pipewire: First shot at moving to the new SDL3 audio interfaces. 13202642a3 aaudio: Fixed capitialization, plus some minor cleanups. 3e9991b535 audio: Make sure we don't write to a NULL pointer. 943351affb pulseaudio: GetDefaultAudioInfo isn't a thing anymore. 11dfc4d737 test: Update testautomation_audio for SDL3 audio API. 29afc2e42b test: Update testresample for SDL3 audio API. 3a02eecced test: Update testsurround for SDL3 audio API. e1c78718d4 test: testaudiocapture is updated for the SDL3 audio API. f48cb716c2 pulseaudio: a couple minor tweaks. dac25fe9eb audio: Seperate audio capture into Wait/Read operations. 3e10c0005d audio: Capture devices should respect logical device pausing. 7e700531c5 audio: Allow SDL_OpenAudioDevice to accept a NULL spec. bb1cbbd33a test: Update testaudioinfo for SDL3 audio API. 883aee32c5 audio: Let default formats differ for output and capture devices. 62cf24eeb9 pulseaudio: Listen for server events in addition to sources and sinks. 924f370bd7 pulseaudio: Fix deadlock in HotplugThread. 5d4e9e5f80 test: Updated testaudiostreamdynamicresample to SDL3 audio API. f883b9fc64 test: Updated testaudiohotplug to SDL3 audio API. 2be5f726d4 audio: Removed debug logging. 323ecce123 docs: Added migration note about SDL_AUDIODEVICEREMOVED. 47b0321ebf test: Removed loopwavequeue.c; obsolete in SDL3. 0e5a1d4f29 pulseaudio: Removed debug logging. f598626e46 test: loopwave shouldn't use an audiostream callback. eee407caf8 docs: migration guide note that SDL_LoadWAV has a different return type. b03c493fc4 test: Updated testmultiaudio to new SDL3 audio API fe1daf6fb5 audio: Mark disconnected default devices as "zombies". cdd2ba81de audio: Fixed adding new physical devices to a double-linked list. db39cbf208 audio: Allow SDL_GetAudioDeviceFormat() to query the default devices. ee10bab3cd audio: An enormous amount of work on managing default devices. c7a44eea83 audio: Fixed logic error. 089cd87cb5 audio: Make sure device count stays correct as hardware disconnects. e50cb72eb6 docs: Note that audio opening doesn't implicitly init SDL now. 97b2f747d0 docs: Corrections to audio section of README-migration.md 464640440f audio: Added SDL_GetAudioStreamBinding. 01f7b53865 audio: Readded (logical) device pausing. fd4c9f4e11 audio: documentation improvements. 4b78b789a7 audio: Switch SDL_audio.c and SDL_audiocvt.c to C99-ish syntax. d96a1db7d7 audio: Opening via a logical device ID should also track default device. b2e020958f audio: Wrap device access in opening of logical devices. 7ee2459927 audio: Check for unlikely failure case in WAV loaded. 3d65a2cefe audio: Made SDL_LoadWAV a real function, not just a macro. 26525f5fd3 audio: Readd SDL_AudioSpec, but just with format/channels/freq fields. e6aaed7d79 include: Audio is not, and has not been, a raw mixing buffer for a long time. 56b1bc2198 audio: SDL_AudioStream now has callbacks for Get and Put operations. 905c4fff5b audio: First shot at the SDL3 audio subsystem redesign! b221b59995 cmake: add SDL_REVISION option 0500fca00c Add missing break d3f2de7f29 fixed typo in prev. patch. 12b35c6a46 test/testnativecocoa.m: fixed deprecation warnings. e24b3e2fa4 cmake: rename SDL_TEST -> SDL_TEST_LIBRARY da5016d336 cmake: use pkg-config + test compile instead of Find module for detecting rpi deec574ff6 cmake: fix SDL_HIDAPI_LIBUSB f2ae00c1ad Sync SDL3 wiki -> header 41a96c8133 doc: document building of SDL tests with CMake 3174d0b970 Sorted controller list 27b8abb056 Add Steam Deck controller mapping to database. 41d436f0fe Use SetWindowPos to show windows when SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN is set to avoid activating the parent window when showing a child window 0dc85f3078 Improved the documentation for the gamepad paddle buttons 2fff999a41 Try to create the dummy mouse cursor after video backend initialization d086d9874d Sync SDL3 wiki -> header bce598addd SDL_pixels.c: Fixed compiler warning on Android NDK. ad0c0d3cde Sync SDL3 wiki -> header f8e8dff7ee tests: Fix automated window grab and positioning tests under Wayland/XWayland 4cffbc3644 Add VS code directory to gitignore 666f81bace Add more endian-specific aliases for 32 bit pixelformats 4749df0a63 Just disable the 4214 warning instead of trying to change the structure definition git-subtree-dir: external/sdl/SDL git-subtree-split: ec0042081ea104d5dd0ee291105210e00a4fe3d9 --- .clang-tidy | 1 + .gitattributes | 12 + .github/workflows/ios.yml | 4 +- .github/workflows/main.yml | 4 +- .github/workflows/msvc.yml | 3 +- .github/workflows/visionos.yml.disabled | 22 + .gitignore | 3 + CMakeLists.txt | 106 +- VisualC/SDL/SDL.vcxproj | 6 +- VisualC/SDL_test/SDL_test.vcxproj | 6 +- Xcode/SDL/SDL.xcodeproj/project.pbxproj | 6877 +---------------- .../SDLTest/SDLTest.xcodeproj/project.pbxproj | 1759 +++-- Xcode/SDLTest/TestDropFile-Info.plist | 35 - Xcode/SDLTest/config.xcconfig | 6 +- .../java/org/libsdl/app/SDLAudioManager.java | 72 +- build-scripts/SDL_migration.cocci | 74 +- cmake/FindRPi_BcmHost.cmake | 75 - cmake/FindRPi_BrcmEGL.cmake | 59 - cmake/sdlchecks.cmake | 23 +- cmake/sdlplatform.cmake | 3 + cmake/test/CMakeLists.txt | 5 + cmake/xxd.py | 2 +- docs/README-cmake.md | 24 + docs/README-migration.md | 244 +- include/SDL3/SDL_audio.h | 1434 ++-- include/SDL3/SDL_begin_code.h | 2 + include/SDL3/SDL_events.h | 6 +- include/SDL3/SDL_filesystem.h | 17 +- include/SDL3/SDL_gamepad.h | 19 +- include/SDL3/SDL_mutex.h | 4 + include/SDL3/SDL_oldnames.h | 40 +- include/SDL3/SDL_pixels.h | 10 + include/SDL3/SDL_platform_defines.h | 3 + include/SDL3/SDL_render.h | 6 +- include/SDL3/SDL_rwops.h | 435 +- include/SDL3/SDL_surface.h | 12 +- include/SDL3/SDL_test_common.h | 4 +- include/SDL3/SDL_thread.h | 3 +- include/SDL3/SDL_video.h | 24 + src/SDL.c | 4 +- src/audio/SDL_audio.c | 2735 +++---- src/audio/SDL_audio_c.h | 55 +- src/audio/SDL_audiocvt.c | 615 +- src/audio/SDL_audiodev.c | 12 +- src/audio/SDL_audiodev_c.h | 2 +- src/audio/SDL_sysaudio.h | 324 +- src/audio/SDL_wave.c | 76 +- src/audio/aaudio/SDL_aaudio.c | 679 +- src/audio/aaudio/SDL_aaudio.h | 12 +- src/audio/aaudio/SDL_aaudiofuncs.h | 19 +- src/audio/alsa/SDL_alsa_audio.c | 428 +- src/audio/alsa/SDL_alsa_audio.h | 1 - src/audio/android/SDL_androidaudio.c | 193 +- src/audio/coreaudio/SDL_coreaudio.h | 5 +- src/audio/coreaudio/SDL_coreaudio.m | 1299 ++-- src/audio/directsound/SDL_directsound.c | 403 +- src/audio/directsound/SDL_directsound.h | 5 +- src/audio/disk/SDL_diskaudio.c | 136 +- src/audio/dsp/SDL_dspaudio.c | 215 +- src/audio/dsp/SDL_dspaudio.h | 2 - src/audio/dummy/SDL_dummyaudio.c | 60 +- src/audio/dummy/SDL_dummyaudio.h | 9 +- src/audio/emscripten/SDL_emscriptenaudio.c | 229 +- src/audio/emscripten/SDL_emscriptenaudio.h | 2 +- src/audio/haiku/SDL_haikuaudio.cc | 152 +- src/audio/haiku/SDL_haikuaudio.h | 2 + src/audio/jack/SDL_jackaudio.c | 199 +- src/audio/jack/SDL_jackaudio.h | 3 +- src/audio/n3ds/SDL_n3dsaudio.c | 265 +- src/audio/n3ds/SDL_n3dsaudio.h | 6 - src/audio/netbsd/SDL_netbsdaudio.c | 209 +- src/audio/openslES/SDL_openslES.c | 352 +- src/audio/pipewire/SDL_pipewire.c | 377 +- src/audio/pipewire/SDL_pipewire.h | 5 +- src/audio/ps2/SDL_ps2audio.c | 111 +- src/audio/psp/SDL_pspaudio.c | 137 +- src/audio/pulseaudio/SDL_pulseaudio.c | 430 +- src/audio/pulseaudio/SDL_pulseaudio.h | 1 - src/audio/qnx/SDL_qsa_audio.c | 616 +- src/audio/qnx/SDL_qsa_audio.h | 21 +- src/audio/sndio/SDL_sndioaudio.c | 207 +- src/audio/sndio/SDL_sndioaudio.h | 12 +- src/audio/vita/SDL_vitaaudio.c | 160 +- src/audio/wasapi/SDL_wasapi.c | 805 +- src/audio/wasapi/SDL_wasapi.h | 25 +- src/audio/wasapi/SDL_wasapi_win32.c | 61 +- src/audio/wasapi/SDL_wasapi_winrt.cpp | 271 +- src/core/android/SDL_android.c | 131 +- src/core/android/SDL_android.h | 13 +- src/core/windows/SDL_immdevice.c | 429 +- src/core/windows/SDL_immdevice.h | 16 +- src/core/windows/SDL_windows.c | 29 +- src/core/windows/SDL_windows.h | 16 + src/dynapi/SDL_dynapi.sym | 104 +- src/dynapi/SDL_dynapi_overrides.h | 105 +- src/dynapi/SDL_dynapi_procs.h | 116 +- src/events/SDL_events.c | 2 - src/events/SDL_keyboard.c | 33 +- src/events/SDL_keyboard_c.h | 3 + src/events/SDL_mouse.c | 45 +- src/events/SDL_mouse_c.h | 7 +- src/file/SDL_rwops.c | 576 +- src/filesystem/android/SDL_sysfilesystem.c | 2 +- src/filesystem/cocoa/SDL_sysfilesystem.m | 2 +- src/filesystem/dummy/SDL_sysfilesystem.c | 2 +- src/filesystem/emscripten/SDL_sysfilesystem.c | 2 +- src/filesystem/haiku/SDL_sysfilesystem.cc | 2 +- src/filesystem/n3ds/SDL_sysfilesystem.c | 2 +- src/filesystem/ps2/SDL_sysfilesystem.c | 2 +- src/filesystem/psp/SDL_sysfilesystem.c | 2 +- src/filesystem/riscos/SDL_sysfilesystem.c | 2 +- src/filesystem/unix/SDL_sysfilesystem.c | 2 +- src/filesystem/vita/SDL_sysfilesystem.c | 2 +- src/filesystem/windows/SDL_sysfilesystem.c | 4 +- src/filesystem/winrt/SDL_sysfilesystem.cpp | 2 +- src/hidapi/ios/hid.m | 4 + .../windows/hidapi_descriptor_reconstruct.h | 25 +- src/joystick/SDL_gamepad.c | 45 +- src/joystick/SDL_gamepad_db.h | 2 + src/joystick/SDL_joystick.c | 29 +- src/joystick/SDL_joystick_c.h | 8 +- src/joystick/android/SDL_sysjoystick.c | 22 +- src/joystick/apple/SDL_mfijoystick.m | 28 +- src/joystick/controller_list.h | 2 + src/joystick/hidapi/SDL_hidapi_ps4.c | 42 +- src/joystick/hidapi/SDL_hidapi_ps5.c | 37 +- src/joystick/hidapi/SDL_hidapi_steam.c | 16 +- src/joystick/hidapi/SDL_hidapi_switch.c | 16 +- src/joystick/linux/SDL_sysjoystick.c | 30 +- src/joystick/n3ds/SDL_sysjoystick.c | 8 +- src/joystick/virtual/SDL_virtualjoystick.c | 24 +- src/misc/ios/SDL_sysurl.m | 8 + src/misc/macos/SDL_sysurl.m | 4 + src/sensor/SDL_sensor.c | 249 +- src/sensor/SDL_sensor_c.h | 17 +- src/sensor/SDL_syssensor.h | 24 +- src/sensor/android/SDL_androidsensor.c | 31 +- src/stdlib/SDL_string.c | 15 +- src/test/SDL_test_common.c | 34 +- src/thread/generic/SDL_sysrwlock.c | 22 +- src/thread/windows/SDL_systhread.c | 4 +- src/video/SDL_bmp.c | 303 +- src/video/SDL_pixels.c | 15 +- src/video/SDL_sysvideo.h | 5 +- src/video/SDL_video.c | 143 +- src/video/android/SDL_androidevents.c | 20 +- src/video/android/SDL_androidvideo.c | 2 +- src/video/cocoa/SDL_cocoaevents.m | 2 +- src/video/cocoa/SDL_cocoamodes.m | 2 +- src/video/cocoa/SDL_cocoawindow.m | 4 +- src/video/haiku/SDL_BWin.h | 14 +- src/video/kmsdrm/SDL_kmsdrmvideo.c | 2 +- src/video/n3ds/SDL_n3dsvideo.c | 1 - src/video/uikit/SDL_uikitappdelegate.m | 37 +- src/video/uikit/SDL_uikitevents.m | 4 +- src/video/uikit/SDL_uikitmessagebox.m | 4 + src/video/uikit/SDL_uikitmetalview.m | 2 + src/video/uikit/SDL_uikitmodes.h | 17 +- src/video/uikit/SDL_uikitmodes.m | 75 +- src/video/uikit/SDL_uikitvideo.h | 4 + src/video/uikit/SDL_uikitvideo.m | 13 +- src/video/uikit/SDL_uikitview.m | 12 + src/video/uikit/SDL_uikitviewcontroller.m | 92 +- src/video/uikit/SDL_uikitwindow.m | 30 +- src/video/wayland/SDL_waylanddyn.h | 1 + src/video/wayland/SDL_waylandevents.c | 33 +- src/video/wayland/SDL_waylandsym.h | 1 + src/video/wayland/SDL_waylandvideo.c | 7 +- src/video/wayland/SDL_waylandwindow.c | 19 +- src/video/wayland/SDL_waylandwindow.h | 1 + src/video/windows/SDL_windowsmodes.c | 31 +- src/video/windows/SDL_windowsvideo.c | 1 + src/video/windows/SDL_windowswindow.c | 29 +- src/video/windows/SDL_windowswindow.h | 1 + src/video/x11/SDL_x11messagebox.c | 4 +- src/video/x11/SDL_x11modes.c | 7 +- src/video/x11/SDL_x11video.c | 3 +- src/video/x11/SDL_x11window.c | 27 +- src/video/x11/SDL_x11window.h | 1 + test/CMakeLists.txt | 87 +- test/README | 1 - test/audiofile.bmp | Bin 0 -> 65674 bytes test/emscripten/server.py | 67 + test/gamepadutils.c | 20 +- test/logaudiodev.bmp | Bin 0 -> 65674 bytes test/loopwave.c | 73 +- test/loopwavequeue.c | 183 - test/physaudiodev.bmp | Bin 0 -> 65674 bytes test/soundboard.bmp | Bin 0 -> 65674 bytes test/soundboard_levels.bmp | Bin 0 -> 2698 bytes test/speaker.bmp | Bin 0 -> 65674 bytes test/testaudio-art.txt | 8 + test/testaudio.c | 1069 +++ test/testaudiocapture.c | 112 +- test/testaudiohotplug.c | 59 +- test/testaudioinfo.c | 38 +- test/testaudiostreamdynamicresample.c | 252 +- test/testautomation_audio.c | 315 +- test/testautomation_rwops.c | 104 +- test/testautomation_stdlib.c | 30 +- test/testautomation_video.c | 111 +- test/testcontroller.c | 18 +- test/testdraw.c | 3 +- test/testfile.c | 120 +- test/testime.c | 11 +- test/testmultiaudio.c | 176 +- test/testnativecocoa.m | 9 +- test/testresample.c | 45 +- test/testsurround.c | 64 +- test/trashcan.bmp | Bin 0 -> 65674 bytes test/uwp/Package.appxmanifest.in | 52 + test/uwp/logo-50x50.png | Bin 0 -> 2421 bytes test/uwp/splash-620x300.png | Bin 0 -> 30918 bytes test/uwp/square-150x150.png | Bin 0 -> 10605 bytes test/uwp/square-44x44.png | Bin 0 -> 2082 bytes 215 files changed, 12672 insertions(+), 17114 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/visionos.yml.disabled delete mode 100644 Xcode/SDLTest/TestDropFile-Info.plist delete mode 100644 cmake/FindRPi_BcmHost.cmake delete mode 100644 cmake/FindRPi_BrcmEGL.cmake create mode 100644 test/audiofile.bmp create mode 100755 test/emscripten/server.py create mode 100644 test/logaudiodev.bmp delete mode 100644 test/loopwavequeue.c create mode 100644 test/physaudiodev.bmp create mode 100644 test/soundboard.bmp create mode 100644 test/soundboard_levels.bmp create mode 100644 test/speaker.bmp create mode 100644 test/testaudio-art.txt create mode 100644 test/testaudio.c create mode 100644 test/trashcan.bmp create mode 100644 test/uwp/Package.appxmanifest.in create mode 100644 test/uwp/logo-50x50.png create mode 100644 test/uwp/splash-620x300.png create mode 100644 test/uwp/square-150x150.png create mode 100644 test/uwp/square-44x44.png diff --git a/.clang-tidy b/.clang-tidy index 739a8eb0..b46d0de5 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -25,6 +25,7 @@ Checks: > clang-analyzer-core.*, clang-analyzer-valist.*, clang-analyzer-unix.Malloc, + clang-diagnostic-*, google-readability-casting, misc-misleading-bidirectional, misc-misleading-identifier, diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..56cee302 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +*.c text +*.cpp text +*.h text +*.cmake text +*.py text +*.txt text +*.sh text +*.vcxproj text eol=crlf +*.sln text eol=crlf +*.filters text eol=crlf +*.appxmanifest text eol=crlf +*.pbxproj text diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index fb92ecd1..b36f29db 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -15,8 +15,8 @@ jobs: fail-fast: false matrix: platform: - - { name: iOS, target: Static Library-iOS, sdk: iphoneos } - - { name: tvOS, target: Static Library-tvOS, sdk: appletvos } + - { name: iOS, target: SDL3, sdk: iphoneos } + - { name: tvOS, target: SDL3, sdk: appletvos } steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 593a8cf1..7f4fbab0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,7 +30,7 @@ jobs: - { name: Intel Compiler (Ubuntu 20.04), os: ubuntu-20.04, shell: bash, artifact: 'SDL-ubuntu20.04-icc', intel: true, cmake: '-DSDL_CLANG_TIDY=OFF', source_cmd: 'source /opt/intel/oneapi/setvars.sh; export CC=icc; export CXX=icpc; export CFLAGS=-diag-disable=10441; export CXXFLAGS=-diag-disable=10441; '} - { name: Ubuntu 22.04, os: ubuntu-22.04, shell: sh, artifact: 'SDL-ubuntu22.04' } - - { name: MacOS (Framework), os: macos-latest, shell: sh, cmake: '-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DSDL_FRAMEWORK=ON -DSDL_CLANG_TIDY=OFF', skip_test_pkgconfig: true, artifact: 'SDL-macos-framework' } + - { name: MacOS (Framework), os: macos-latest, shell: sh, cmake: '-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DSDL_FRAMEWORK=ON -DSDL_CLANG_TIDY=OFF', skip_test_pkgconfig: true, artifact: 'SDL-macos-framework', no-static: true } - { name: MacOS (GNU prefix), os: macos-latest, shell: sh, cmake: '-DCMAKE_OSX_ARCHITECTURES="x86_64" -DCLANG_TIDY_BINARY="$(brew --prefix llvm)/bin/clang-tidy"', artifact: 'SDL-macos-gnu' } steps: @@ -130,7 +130,7 @@ jobs: ${{ matrix.platform.source_cmd }} cmake -S cmake/test -B cmake_config_build -G Ninja \ -DTEST_SHARED=ON \ - -DTEST_STATIC=ON \ + -DTEST_STATIC=${{ !matrix.platform.no-static }} \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH=$(echo "${{ github.workspace }}/cmake_prefix" | sed -e 's#\\#/#g') cmake --build cmake_config_build --verbose diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml index 0b8cdcd7..a434a728 100644 --- a/.github/workflows/msvc.yml +++ b/.github/workflows/msvc.yml @@ -23,7 +23,7 @@ jobs: - { name: Windows (clang-cl x86), flags: -T ClangCL -A Win32, artifact: 'SDL-clang-cl-x86' } - { name: Windows (ARM), flags: -A ARM, artifact: 'SDL-VC-arm32' } - { name: Windows (ARM64), flags: -A ARM64, artifact: 'SDL-VC-arm64' } - - { name: UWP (x64), flags: -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DSDL_TESTS=OFF, nowerror: true, + - { name: UWP (x64), flags: -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0", nowerror: true, project: VisualC-WinRT/SDL-UWP.sln, projectflags: '/p:Platform=x64 /p:WindowsTargetPlatformVersion=10.0.17763.0', artifact: 'SDL-VC-UWP' } steps: @@ -70,7 +70,6 @@ jobs: run: | cmake --build build/ --config Release --target PACKAGE - name: Verify CMake configuration files - if: ${{ !contains(matrix.platform.name, 'UWP') }} # FIXME: cmake/test/CMakeLists.txt should support UWP run: | cmake -S cmake/test -B cmake_config_build ` -DCMAKE_PREFIX_PATH=${{ env.SDL3_DIR }} ` diff --git a/.github/workflows/visionos.yml.disabled b/.github/workflows/visionos.yml.disabled new file mode 100644 index 00000000..f697543b --- /dev/null +++ b/.github/workflows/visionos.yml.disabled @@ -0,0 +1,22 @@ +name: Build (visionOS) + +# FIXME: Enable this workflow once CMake 3.28 becomes available on GitHub +on: [push, pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true + +jobs: + Build: + name: visionOS + runs-on: macos-latest + + steps: + - uses: actions/checkout@v3 + - name: Configure + run: | + cmake -B build -GXcode -DCMAKE_SYSTEM_NAME=visionOS + - name: Build + run: | + cmake --build build diff --git a/.gitignore b/.gitignore index 391a8f9c..93ee540a 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,9 @@ cmake-build-* xcuserdata *.xcworkspace +# for Visual Studio Code +.vscode/ + # for Visual C++ .vs Debug diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e08ac15..d0457150 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,7 @@ endif() # 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) +if((WINDOWS AND NOT WINDOWS_STORE) OR IOS OR TVOS OR VISIONOS OR ANDROID) set(SDL_HIDAPI_LIBUSB_AVAILABLE FALSE) else() set(SDL_HIDAPI_LIBUSB_AVAILABLE TRUE) @@ -198,6 +198,7 @@ set(SDL_SHARED_DEFAULT ON) set(SDL_STATIC_DEFAULT ON) set(SDL_SHARED_AVAILABLE ON) +set(SDL_STATIC_AVAILABLE ON) # All these *_DEFAULT vars will default to ON if not specified, # so you only need to override them if they need to be disabled. @@ -263,6 +264,11 @@ foreach(_SUB IN LISTS SDL_SUBSYSTEMS) option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ${SDL_${_OPT}_DEFAULT}) endforeach() +cmake_dependent_option(SDL_FRAMEWORK "Build SDL libraries as Apple Framework" OFF "APPLE" OFF) +if(SDL_FRAMEWORK) + set(SDL_STATIC_AVAILABLE FALSE) +endif() + # Allow some projects to be built conditionally. set_option(SDL_DISABLE_INSTALL "Disable installation of SDL3" ${SDL3_SUBPROJECT}) cmake_dependent_option(SDL_DISABLE_INSTALL_CPACK "Create binary SDL3 archive using CPack" ${SDL3_SUBPROJECT} "NOT SDL_DISABLE_INSTALL" ON) @@ -297,8 +303,8 @@ set_option(SDL_DISKAUDIO "Support the disk writer audio driver" ON) set_option(SDL_DUMMYAUDIO "Support the dummy audio driver" ON) set_option(SDL_DUMMYVIDEO "Use dummy video driver" ON) dep_option(SDL_IBUS "Enable IBus support" ON ${UNIX_SYS} OFF) -set_option(SDL_OPENGL "Include OpenGL support" ON) -set_option(SDL_OPENGLES "Include OpenGL ES support" ON) +dep_option(SDL_OPENGL "Include OpenGL support" ON "NOT VISIONOS" OFF) +dep_option(SDL_OPENGLES "Include OpenGL ES support" ON "NOT VISIONOS" OFF) set_option(SDL_PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_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) @@ -342,7 +348,7 @@ dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KM 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 "Enable the HIDAPI subsystem" ON "NOT VISIONOS" OFF) dep_option(SDL_HIDAPI_LIBUSB "Use libusb for low level joystick drivers" ${SDL_HIDAPI_LIBUSB_DEFAULT} "SDL_HIDAPI;${SDL_HIDAPI_LIBUSB_AVAILABLE}" 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) @@ -354,15 +360,12 @@ set_option(SDL_CLANG_TIDY "Run clang-tidy static analysis" OFF) set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION") cmake_dependent_option(SDL_SHARED "Build a shared version of the library" ${SDL_SHARED_DEFAULT} ${SDL_SHARED_AVAILABLE} OFF) -option(SDL_STATIC "Build a static version of the library" ${SDL_STATIC_DEFAULT}) -option(SDL_TEST "Build the SDL3_test library" ON) - -# Apple Frameworks NEED a (shared) SDL3.framework for `#include ` to work -cmake_dependent_option(SDL_FRAMEWORK "Build SDL libraries as Apple Framework" OFF "SDL_SHARED;APPLE" OFF) +cmake_dependent_option(SDL_STATIC "Build a static version of the library" ${SDL_STATIC_DEFAULT} ${SDL_STATIC_AVAILABLE} OFF) +option(SDL_TEST_LIBRARY "Build the SDL3_test library" ON) 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) -dep_option(SDL_INSTALL_TESTS "Install test-cases" OFF "NOT SDL_DISABLE_INSTALL;NOT SDL_FRAMEWORK" OFF) +dep_option(SDL_TESTS "Build the test directory" OFF SDL_TEST_LIBRARY OFF) +dep_option(SDL_INSTALL_TESTS "Install test-cases" OFF "NOT SDL_DISABLE_INSTALL;NOT SDL_FRAMEWORK;NOT WINDOWS_STORE" OFF) dep_option(SDL_TESTS_LINK_SHARED "link tests to shared SDL library" "${SDL_SHARED}" "SDL_SHARED;SDL_STATIC" "${SDL_SHARED}") set(SDL_TESTS_TIMEOUT_MULTIPLIER "1" CACHE STRING "Timeout multiplier to account for really slow machines") @@ -391,7 +394,7 @@ if(SDL_STATIC) target_compile_features(SDL3-static PRIVATE c_std_99) endif() -if(SDL_TEST) +if(SDL_TEST_LIBRARY) add_library(SDL3_test STATIC) add_library(SDL3::SDL3_test ALIAS SDL3_test) SDL_AddCommonCompilerFlags(SDL3_test) @@ -2028,7 +2031,7 @@ elseif(APPLE) endif() if(SDL_MISC) - if(IOS OR TVOS) + if(IOS OR TVOS OR VISIONOS) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/ios/*.m") else() sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/macos/*.m") @@ -2051,10 +2054,10 @@ elseif(APPLE) if(SDL_JOYSTICK) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/joystick/apple/*.m") - if(IOS OR TVOS) + if(IOS OR TVOS OR VISIONOS) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/joystick/steam/*.c") set(SDL_JOYSTICK_MFI 1) - if(IOS) + if(IOS OR VISIONOS) set(SDL_FRAMEWORK_COREMOTION 1) endif() set(SDL_FRAMEWORK_GAMECONTROLLER 1) @@ -2086,15 +2089,17 @@ elseif(APPLE) set(SDL_FRAMEWORK_GAMECONTROLLER 1) set(SDL_FRAMEWORK_COREHAPTICS 1) endif() - set(SDL_JOYSTICK_IOKIT 1) - set(SDL_FRAMEWORK_IOKIT 1) + if(NOT VISIONOS) + set(SDL_JOYSTICK_IOKIT 1) + set(SDL_FRAMEWORK_IOKIT 1) + endif() set(SDL_FRAMEWORK_FF 1) endif() set(HAVE_SDL_JOYSTICK TRUE) endif() if(SDL_HAPTIC) - if (IOS OR TVOS) + if (IOS OR TVOS OR VISIONOS) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/haptic/dummy/*.c") set(SDL_HAPTIC_DUMMY 1) else() @@ -2107,7 +2112,7 @@ elseif(APPLE) endif() if(SDL_POWER) - if (IOS OR TVOS) + if (IOS OR TVOS OR VISIONOS) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/power/uikit/*.m") set(SDL_POWER_UIKIT 1) else() @@ -2136,7 +2141,7 @@ elseif(APPLE) endif() if(SDL_SENSOR) - if(IOS) + if(IOS OR VISIONOS) set(SDL_SENSOR_COREMOTION 1) set(HAVE_SDL_SENSORS TRUE) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/sensor/coremotion/*.m") @@ -2145,7 +2150,7 @@ elseif(APPLE) # iOS hack needed - http://code.google.com/p/ios-cmake/ ? if(SDL_VIDEO) - if (IOS OR TVOS) + if (IOS OR TVOS OR VISIONOS) set(SDL_VIDEO_DRIVER_UIKIT 1) set(SDL_FRAMEWORK_COREGRAPHICS 1) set(SDL_FRAMEWORK_QUARTZCORE 1) @@ -2165,7 +2170,7 @@ elseif(APPLE) endif() if(SDL_OPENGLES) - if(IOS OR TVOS) + if(IOS OR TVOS OR VISIONOS) set(SDL_FRAMEWORK_OPENGLES 1) set(SDL_VIDEO_OPENGL_ES 1) else() @@ -2250,7 +2255,7 @@ elseif(APPLE) endif() endif() if(SDL_FRAMEWORK_METAL) - if(IOS OR TVOS) + if(IOS OR TVOS OR VISIONOS) sdl_link_dependency(metal LINK_OPTIONS "-Wl,-framework,Metal") else() sdl_link_dependency(metal LINK_OPTIONS "-Wl,-weak_framework,Metal") @@ -2260,7 +2265,7 @@ elseif(APPLE) sdl_link_dependency(opengles LINK_OPTIONS "-Wl,-framework,OpenGLES") endif() if(SDL_FRAMEWORK_QUARTZCORE) - if(IOS OR TVOS) + if(IOS OR TVOS OR VISIONOS) sdl_link_dependency(quartz_core LINK_OPTIONS "-Wl,-framework,QuartzCore") else() sdl_link_dependency(metal LINK_OPTIONS "-Wl,-weak_framework,QuartzCore") @@ -2796,19 +2801,22 @@ foreach(_hdr IN LISTS SDL3_INCLUDE_FILES) endif() endforeach() -set(SDL_REVISION_SUFFIX "" CACHE STRING "Suffix for the SDL revision") -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt") - # If VERSION exists, it contains the SDL version - file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt" SDL_REVISION_CENTER) - string(STRIP "${SDL_REVISION_CENTER}" SDL_REVISION_CENTER) -else() - # If VERSION does not exist, use git to calculate a version - git_describe(SDL_REVISION_CENTER) - if(NOT SDL_REVISION_CENTER) - set(SDL_REVISION_CENTER "${SDL3_VERSION}-no-vcs") +set(SDL_REVISION "" CACHE STRING "Custom SDL revision (overrides SDL_REVISION_SUFFIX)") +if(NOT SDL_REVISION) + set(SDL_REVISION_SUFFIX "" CACHE STRING "Suffix for the SDL revision") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt") + # If VERSION exists, it contains the SDL version + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.txt" SDL_REVISION_CENTER) + string(STRIP "${SDL_REVISION_CENTER}" SDL_REVISION_CENTER) + else() + # If VERSION does not exist, use git to calculate a version + git_describe(SDL_REVISION_CENTER) + if(NOT SDL_REVISION_CENTER) + set(SDL_REVISION_CENTER "${SDL3_VERSION}-no-vcs") + endif() endif() + set(SDL_REVISION "SDL-${SDL_REVISION_CENTER}${SDL_REVISION_SUFFIX}") endif() -set(SDL_REVISION "SDL-${SDL_REVISION_CENTER}${SDL_REVISION_SUFFIX}") execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${SDL3_BINARY_DIR}/include/SDL3") configure_file(include/build_config/SDL_revision.h.cmake include/SDL3/SDL_revision.h @ONLY) @@ -3094,18 +3102,6 @@ if(SDL_STATIC) OUTPUT_NAME "${sdl_static_libname}" POSITION_INDEPENDENT_CODE "${SDL_STATIC_PIC}" ) - if(APPLE) - set_target_properties(SDL3-static PROPERTIES - FRAMEWORK "${SDL_FRAMEWORK}" - ) - if(SDL_FRAMEWORK) - set_target_properties(SDL3-static PROPERTIES - FRAMEWORK_VERSION "${SDL_FRAMEWORK_VERSION}" - MACOSX_FRAMEWORK_IDENTIFIER "org.libsdl.SDL3-static" - RESOURCE "${SDL_FRAMEWORK_RESOURCES}" - ) - endif() - endif() target_compile_definitions(SDL3-static PRIVATE SDL_STATIC_LIB) target_link_libraries(SDL3-static PRIVATE ${SDL_CMAKE_DEPENDS}) target_include_directories(SDL3-static @@ -3135,7 +3131,7 @@ sdl_compile_definitions( ##### Tests ##### -if(SDL_TEST) +if(SDL_TEST_LIBRARY) file(GLOB TEST_SOURCES "${SDL3_SOURCE_DIR}/src/test/*.c") target_sources(SDL3_test PRIVATE ${TEST_SOURCES}) if(APPLE) @@ -3193,12 +3189,6 @@ if(SDL_FRAMEWORK) set(SDL_SDL_INSTALL_REAL_RESOURCEDIR "SDL3.framework/Versions/${SDL_FRAMEWORK_VERSION}/Resources") set(SDL_SDL_INSTALL_REAL_CMAKEDIR "${SDL_SDL_INSTALL_REAL_RESOURCEDIR}/CMake") - # - Install other SDL3*Config.cmake files in SDL3*.framework/Resources/CMake - # - The *_RELATIVE_CMAKEDIR variables are the symlinked folders visible from outside - set(SDL_SDLstatic_INSTALL_RESOURCEDIR "SDL3-static.framework/Resources") - set(SDL_SDLstatic_INSTALL_CMAKEDIR "${SDL_SDLstatic_INSTALL_RESOURCEDIR}/CMake") - set(SDL_SDLstatic_INSTALL_CMAKEFILENAME "SDL3-staticConfig.cmake") - set(SDL_SDLtest_INSTALL_RESOURCEDIR "SDL3_test.framework/Resources") set(SDL_SDLtest_INSTALL_CMAKEDIR "${SDL_SDLtest_INSTALL_RESOURCEDIR}/CMake") set(SDL_SDLtest_INSTALL_CMAKEFILENAME "SDL3_testConfig.cmake") @@ -3227,7 +3217,7 @@ if(SDL_STATIC) export(TARGETS SDL3-static NAMESPACE "SDL3::" FILE "SDL3staticTargets.cmake") endif() -if(SDL_TEST) +if(SDL_TEST_LIBRARY) export(TARGETS SDL3_test NAMESPACE "SDL3::" FILE "SDL3testTargets.cmake") endif() @@ -3285,7 +3275,7 @@ if(NOT SDL_DISABLE_INSTALL) ) endif() - if(SDL_TEST) + if(SDL_TEST_LIBRARY) install(TARGETS SDL3_test EXPORT SDL3testTargets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" FRAMEWORK DESTINATION "." @@ -3317,7 +3307,7 @@ if(NOT SDL_DISABLE_INSTALL) ) endif() - if(SDL_TEST) + if(SDL_TEST_LIBRARY) install(EXPORT SDL3testTargets FILE "${SDL_SDLtest_INSTALL_CMAKEFILENAME}" NAMESPACE SDL3:: @@ -3336,7 +3326,7 @@ if(NOT SDL_DISABLE_INSTALL) install(FILES ${SDL3_INCLUDE_FILES} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SDL3" ) - if(SDL_TEST) + if(SDL_TEST_LIBRARY) install(FILES ${SDL3_TEST_INCLUDE_FILES} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/SDL3" ) diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 8b8f6d6a..0cea5060 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -122,6 +122,7 @@ OnlyExplicitInline Use SDL_internal.h + true _DEBUG;%(PreprocessorDefinitions) @@ -153,6 +154,7 @@ OnlyExplicitInline Use SDL_internal.h + true _DEBUG;%(PreprocessorDefinitions) @@ -188,6 +190,7 @@ OnlyExplicitInline Use SDL_internal.h + true NDEBUG;%(PreprocessorDefinitions) @@ -220,6 +223,7 @@ OnlyExplicitInline Use SDL_internal.h + true NDEBUG;%(PreprocessorDefinitions) @@ -656,4 +660,4 @@ - + \ No newline at end of file diff --git a/VisualC/SDL_test/SDL_test.vcxproj b/VisualC/SDL_test/SDL_test.vcxproj index 8148024c..f69b2e5f 100644 --- a/VisualC/SDL_test/SDL_test.vcxproj +++ b/VisualC/SDL_test/SDL_test.vcxproj @@ -100,6 +100,7 @@ Level3 OldStyle true + true @@ -116,6 +117,7 @@ Level3 OldStyle true + true @@ -134,6 +136,7 @@ Level3 OldStyle true + true @@ -150,6 +153,7 @@ Level3 OldStyle true + true @@ -168,4 +172,4 @@ - + \ No newline at end of file diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 862ee339..5fd66058 100644 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -3,2925 +3,345 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 55; objects = { /* Begin PBXAggregateTarget section */ - F3B38CEC296F63B6005DA6D3 /* SDL.xcframework */ = { + F3676F582A7885080091160D /* SDL3.dmg */ = { isa = PBXAggregateTarget; - buildConfigurationList = F3B38CED296F63B6005DA6D3 /* Build configuration list for PBXAggregateTarget "SDL.xcframework" */; + buildConfigurationList = F3676F592A7885080091160D /* Build configuration list for PBXAggregateTarget "SDL3.dmg" */; + buildPhases = ( + F3676F5E2A78852D0091160D /* ShellScript */, + ); + dependencies = ( + F3676F5D2A7885130091160D /* PBXTargetDependency */, + ); + name = SDL3.dmg; + productName = "Create DMG"; + }; + F3B38CEC296F63B6005DA6D3 /* SDL3.xcframework */ = { + isa = PBXAggregateTarget; + buildConfigurationList = F3B38CED296F63B6005DA6D3 /* Build configuration list for PBXAggregateTarget "SDL3.xcframework" */; buildPhases = ( F3B38CF0296F63D1005DA6D3 /* ShellScript */, ); dependencies = ( ); - name = SDL.xcframework; + name = SDL3.xcframework; productName = xcFramework; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; }; - 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; - 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, ); }; }; + 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; platformFilters = (macos, ); }; + 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; platformFilters = (ios, maccatalyst, macos, ); }; + 00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; platformFilters = (macos, ); }; + 00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; platformFilters = (ios, maccatalyst, macos, tvos, watchos, ); }; + 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; platformFilters = (macos, ); }; + 557D0CFA254586CA003913E3 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); }; 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 */; }; - 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, ); }; }; 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 */; }; 56A2373329F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373429F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373529F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373629F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373729F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373829F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373929F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373A29F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56A2373B29F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; }; - 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; - 56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; 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 */; }; - A75FCD0123E25AB700529352 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A75FCD0423E25AB700529352 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A75FCD0623E25AB700529352 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A75FCD0723E25AB700529352 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A75FCD0923E25AB700529352 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A75FCD0B23E25AB700529352 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.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 */; }; - A75FCD0F23E25AB700529352 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A75FCD1023E25AB700529352 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A75FCD1223E25AB700529352 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A75FCD1323E25AB700529352 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - 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 */; }; - 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 */; }; - A75FCD1C23E25AB700529352 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A75FCD1F23E25AB700529352 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - 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 */; }; - 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 */; }; - A75FCD2C23E25AB700529352 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - 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 */; }; - 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 */; }; - A75FCD3623E25AB700529352 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.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 */; }; - 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 */; }; - A75FCD4023E25AB700529352 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A75FCD4223E25AB700529352 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A75FCD4423E25AB700529352 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - 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 */; }; - 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 */; }; - A75FCD4E23E25AB700529352 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - 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 */; }; - 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 */; }; - A75FCD5623E25AB700529352 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A75FCD5723E25AB700529352 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A75FCD5823E25AB700529352 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A75FCD5923E25AB700529352 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A75FCD5B23E25AB700529352 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A75FCD5C23E25AB700529352 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A75FCD5D23E25AB700529352 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A75FCD5E23E25AB700529352 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A75FCD5F23E25AB700529352 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A75FCD6023E25AB700529352 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A75FCD6123E25AB700529352 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A75FCD6223E25AB700529352 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A75FCD6323E25AB700529352 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A75FCD6523E25AB700529352 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - 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 */; }; - A75FCD6B23E25AB700529352 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.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 */; }; - 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 */; }; - 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 */; }; - A75FCD7A23E25AB700529352 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A75FCD7C23E25AB700529352 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A75FCD7E23E25AB700529352 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A75FCD8023E25AB700529352 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A75FCD8323E25AB700529352 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A75FCD8423E25AB700529352 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A75FCD8523E25AB700529352 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - 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 */; }; - A75FCD8A23E25AB700529352 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A75FCD8B23E25AB700529352 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.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 */; }; - A75FCD8F23E25AB700529352 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.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 */; }; - A75FCD9423E25AB700529352 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - A75FCD9523E25AB700529352 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A75FCD9623E25AB700529352 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A75FCD9723E25AB700529352 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A75FCD9823E25AB700529352 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.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 */; }; - 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 */; }; - 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 */; }; - A75FCDAA23E25AB700529352 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - 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 */; }; - A75FCDB023E25AB700529352 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A75FCDB323E25AB700529352 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A75FCDB423E25AB700529352 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A75FCDB523E25AB700529352 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A75FCDB623E25AB700529352 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A75FCDB723E25AB700529352 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; - A75FCDB823E25AB700529352 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A75FCDBA23E25AB700529352 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A75FCDBB23E25AB700529352 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A75FCDBC23E25AB700529352 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A75FCDBD23E25AB700529352 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A75FCDBE23E25AB700529352 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A75FCDBF23E25AB700529352 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A75FCDC023E25AB700529352 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A75FCDC123E25AB700529352 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; - A75FCDC223E25AB700529352 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A75FCDC323E25AB700529352 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A75FCDC723E25AB700529352 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A75FCDC823E25AB700529352 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A75FCDCC23E25AB700529352 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A75FCDCD23E25AB700529352 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A75FCDCE23E25AB700529352 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A75FCDCF23E25AB700529352 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A75FCDD023E25AB700529352 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A75FCDD223E25AB700529352 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - A75FCDD323E25AB700529352 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A75FCDD423E25AB700529352 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A75FCDD623E25AB700529352 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A75FCDD723E25AB700529352 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; - 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 */; }; - A75FCDE123E25AB700529352 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.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 */; }; - 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 */; }; - A75FCDEC23E25AB700529352 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A75FCDED23E25AB700529352 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A75FCDEE23E25AB700529352 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A75FCDEF23E25AB700529352 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A75FCDF023E25AB700529352 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A75FCDF123E25AB700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FCE0923E25AB700529352 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A75FCE0A23E25AB700529352 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A75FCE0B23E25AB700529352 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A75FCE0C23E25AB700529352 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FCE1B23E25AB700529352 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A75FCE1C23E25AB700529352 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A75FCE1D23E25AB700529352 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A75FCE1E23E25AB700529352 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - 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 */; }; - 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 */; }; - A75FCE2623E25AB700529352 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A75FCE2723E25AB700529352 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A75FCE2823E25AB700529352 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A75FCE2923E25AB700529352 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A75FCE2A23E25AB700529352 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A75FCE2B23E25AB700529352 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A75FCE2C23E25AB700529352 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A75FCE2D23E25AB700529352 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A75FCE2E23E25AB700529352 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A75FCE2F23E25AB700529352 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A75FCE3023E25AB700529352 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A75FCE3123E25AB700529352 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A75FCE3223E25AB700529352 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A75FCE3323E25AB700529352 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A75FCE3423E25AB700529352 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A75FCE3523E25AB700529352 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A75FCE3623E25AB700529352 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A75FCE3723E25AB700529352 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A75FCE3823E25AB700529352 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A75FCE3923E25AB700529352 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A75FCE3A23E25AB700529352 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A75FCE3B23E25AB700529352 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A75FCE3C23E25AB700529352 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - 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 */; }; - A75FCE4123E25AB700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A75FCE4323E25AB700529352 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.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 */; }; - 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 */; }; - A75FCE4C23E25AB700529352 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A75FCE4D23E25AB700529352 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A75FCE4E23E25AB700529352 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A75FCE4F23E25AB700529352 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A75FCE5023E25AB700529352 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A75FCE5123E25AB700529352 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A75FCE5223E25AB700529352 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A75FCE5323E25AB700529352 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - 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 */; }; - 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 */; }; - A75FCE5C23E25AB700529352 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; - A75FCE5D23E25AB700529352 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A75FCE5E23E25AB700529352 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A75FCE5F23E25AB700529352 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A75FCE6023E25AB700529352 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A75FCE6123E25AB700529352 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A75FCE6223E25AB700529352 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FCE6D23E25AB700529352 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - A75FCE6E23E25AB700529352 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - 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 */; }; - 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 */; }; - A75FCE7723E25AB700529352 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - 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 */; }; - 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 */; }; - A75FCE7F23E25AB700529352 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A75FCE8023E25AB700529352 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A75FCE8123E25AB700529352 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A75FCE8223E25AB700529352 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A75FCE8323E25AB700529352 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A75FCE8423E25AB700529352 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A75FCE8523E25AB700529352 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A75FCE8623E25AB700529352 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A75FCE8723E25AB700529352 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FCE9823E25AB700529352 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.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 */; }; - 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 */; }; - A75FCEA523E25AB700529352 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; }; - A75FCEA623E25AB700529352 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; }; - A75FCEA723E25AB700529352 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; - A75FCEA823E25AB700529352 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; - A75FCEAA23E25AB700529352 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; - A75FCEAB23E25AB700529352 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; - A75FCEAE23E25AB700529352 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; - A75FCEB623E25AC700529352 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A75FCEBA23E25AC700529352 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A75FCEBD23E25AC700529352 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A75FCEBF23E25AC700529352 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A75FCEC023E25AC700529352 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A75FCEC223E25AC700529352 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A75FCEC423E25AC700529352 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.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 */; }; - A75FCEC823E25AC700529352 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A75FCEC923E25AC700529352 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A75FCECB23E25AC700529352 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A75FCECC23E25AC700529352 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - 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 */; }; - 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 */; }; - A75FCED523E25AC700529352 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A75FCED823E25AC700529352 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - 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 */; }; - 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 */; }; - A75FCEE523E25AC700529352 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - 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 */; }; - 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 */; }; - A75FCEEF23E25AC700529352 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.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 */; }; - 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 */; }; - A75FCEF923E25AC700529352 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A75FCEFB23E25AC700529352 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A75FCEFD23E25AC700529352 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - 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 */; }; - 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 */; }; - A75FCF0723E25AC700529352 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - 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 */; }; - 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 */; }; - A75FCF0F23E25AC700529352 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A75FCF1023E25AC700529352 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A75FCF1123E25AC700529352 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A75FCF1223E25AC700529352 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A75FCF1423E25AC700529352 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A75FCF1523E25AC700529352 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A75FCF1623E25AC700529352 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A75FCF1723E25AC700529352 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A75FCF1823E25AC700529352 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A75FCF1923E25AC700529352 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A75FCF1A23E25AC700529352 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A75FCF1B23E25AC700529352 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A75FCF1C23E25AC700529352 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A75FCF1E23E25AC700529352 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - 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 */; }; - A75FCF2423E25AC700529352 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.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 */; }; - 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 */; }; - 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 */; }; - A75FCF3323E25AC700529352 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A75FCF3523E25AC700529352 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A75FCF3723E25AC700529352 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A75FCF3923E25AC700529352 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A75FCF3C23E25AC700529352 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A75FCF3D23E25AC700529352 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A75FCF3E23E25AC700529352 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - 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 */; }; - A75FCF4323E25AC700529352 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A75FCF4423E25AC700529352 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.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 */; }; - A75FCF4823E25AC700529352 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.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 */; }; - A75FCF4D23E25AC700529352 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - A75FCF4E23E25AC700529352 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A75FCF4F23E25AC700529352 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A75FCF5023E25AC700529352 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A75FCF5123E25AC700529352 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.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 */; }; - 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 */; }; - 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 */; }; - A75FCF6323E25AC700529352 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - 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 */; }; - A75FCF6923E25AC700529352 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A75FCF6C23E25AC700529352 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A75FCF6D23E25AC700529352 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A75FCF6E23E25AC700529352 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A75FCF6F23E25AC700529352 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A75FCF7023E25AC700529352 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; - A75FCF7123E25AC700529352 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A75FCF7323E25AC700529352 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A75FCF7423E25AC700529352 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A75FCF7523E25AC700529352 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A75FCF7623E25AC700529352 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A75FCF7723E25AC700529352 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A75FCF7823E25AC700529352 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A75FCF7923E25AC700529352 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A75FCF7A23E25AC700529352 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; - A75FCF7B23E25AC700529352 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A75FCF7C23E25AC700529352 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A75FCF8023E25AC700529352 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A75FCF8123E25AC700529352 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A75FCF8523E25AC700529352 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A75FCF8623E25AC700529352 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A75FCF8723E25AC700529352 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A75FCF8823E25AC700529352 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A75FCF8923E25AC700529352 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A75FCF8B23E25AC700529352 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - A75FCF8C23E25AC700529352 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A75FCF8D23E25AC700529352 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A75FCF8F23E25AC700529352 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A75FCF9023E25AC700529352 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; - 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 */; }; - A75FCF9A23E25AC700529352 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.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 */; }; - 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 */; }; - A75FCFA523E25AC700529352 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A75FCFA623E25AC700529352 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A75FCFA723E25AC700529352 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A75FCFA823E25AC700529352 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A75FCFA923E25AC700529352 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A75FCFAA23E25AC700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FCFC223E25AC700529352 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A75FCFC323E25AC700529352 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A75FCFC423E25AC700529352 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A75FCFC523E25AC700529352 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FCFD423E25AC700529352 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A75FCFD523E25AC700529352 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A75FCFD623E25AC700529352 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A75FCFD723E25AC700529352 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - 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 */; }; - 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 */; }; - A75FCFDF23E25AC700529352 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A75FCFE023E25AC700529352 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A75FCFE123E25AC700529352 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A75FCFE223E25AC700529352 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A75FCFE323E25AC700529352 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A75FCFE423E25AC700529352 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A75FCFE523E25AC700529352 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A75FCFE623E25AC700529352 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A75FCFE723E25AC700529352 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A75FCFE823E25AC700529352 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A75FCFE923E25AC700529352 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A75FCFEA23E25AC700529352 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A75FCFEB23E25AC700529352 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A75FCFEC23E25AC700529352 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A75FCFED23E25AC700529352 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A75FCFEE23E25AC700529352 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A75FCFEF23E25AC700529352 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A75FCFF023E25AC700529352 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A75FCFF123E25AC700529352 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A75FCFF223E25AC700529352 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A75FCFF323E25AC700529352 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A75FCFF423E25AC700529352 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A75FCFF523E25AC700529352 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - 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 */; }; - A75FCFFA23E25AC700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A75FCFFC23E25AC700529352 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.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 */; }; - 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 */; }; - A75FD00523E25AC700529352 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A75FD00623E25AC700529352 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A75FD00723E25AC700529352 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A75FD00823E25AC700529352 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A75FD00923E25AC700529352 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A75FD00A23E25AC700529352 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A75FD00B23E25AC700529352 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A75FD00C23E25AC700529352 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - 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 */; }; - 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 */; }; - A75FD01523E25AC700529352 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; - A75FD01623E25AC700529352 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A75FD01723E25AC700529352 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A75FD01823E25AC700529352 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A75FD01923E25AC700529352 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A75FD01A23E25AC700529352 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A75FD01B23E25AC700529352 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FD02623E25AC700529352 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - A75FD02723E25AC700529352 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - 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 */; }; - 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 */; }; - A75FD03023E25AC700529352 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - 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 */; }; - 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 */; }; - A75FD03823E25AC700529352 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A75FD03923E25AC700529352 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A75FD03A23E25AC700529352 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A75FD03B23E25AC700529352 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A75FD03C23E25AC700529352 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A75FD03D23E25AC700529352 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A75FD03E23E25AC700529352 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A75FD03F23E25AC700529352 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A75FD04023E25AC700529352 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A75FD05123E25AC700529352 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.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 */; }; - 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 */; }; - 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 */; }; - A75FDABA23E28A7A00529352 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAB923E28A7A00529352 /* AVFoundation.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 */; }; + A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; platformFilters = (ios, maccatalyst, macos, tvos, watchos, ); }; + A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; platformFilters = (ios, maccatalyst, macos, tvos, ); }; 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 */; }; - A75FDB5B23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; - A75FDB5C23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; - A75FDB5D23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; - 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 */; }; 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 */; }; - A75FDBBA23E4CBC700529352 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = F59C710300D5CB5801000001 /* ReadMe.txt */; }; - A75FDBBB23E4CBC800529352 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 00794D3F09D0C461003FC8A1 /* License.txt */; }; - A75FDBBC23E4CBC800529352 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = F59C710300D5CB5801000001 /* ReadMe.txt */; }; A75FDBC523EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBC623EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBC723EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBC823EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBC923EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBCA23EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBCB23EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBCC23EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; - A75FDBCD23EA380300529352 /* SDL_hidapi_rumble.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */; }; A75FDBCE23EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - A75FDBCF23EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - A75FDBD023EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - A75FDBD123EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - A75FDBD223EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - A75FDBD323EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - A75FDBD423EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; - 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 */; }; - A769B08823E259AE00872273 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A769B08B23E259AE00872273 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - 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 */; }; - A769B09023E259AE00872273 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A769B09223E259AE00872273 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.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 */; }; - 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 */; }; - A769B09923E259AE00872273 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A769B09A23E259AE00872273 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - 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 */; }; - 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 */; }; - A769B0A323E259AE00872273 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A769B0A623E259AE00872273 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - 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 */; }; - 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 */; }; - A769B0B323E259AE00872273 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - 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 */; }; - 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 */; }; - A769B0BC23E259AE00872273 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.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 */; }; - 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 */; }; - A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.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 */; }; - 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 */; }; - A769B0D423E259AE00872273 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - 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 */; }; - 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 */; }; - A769B0DC23E259AE00872273 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - 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 */; }; - 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 */; }; - A769B0E523E259AE00872273 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A769B0E623E259AE00872273 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A769B0E723E259AE00872273 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A769B0E823E259AE00872273 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - 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 */; }; - A769B0ED23E259AE00872273 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - 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 */; }; - A769B0F323E259AE00872273 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.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 */; }; - 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 */; }; - 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 */; }; - A769B10523E259AE00872273 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A769B10723E259AE00872273 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.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 */; }; - A769B11023E259AE00872273 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A769B11123E259AE00872273 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.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 */; }; - A769B11523E259AE00872273 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.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 */; }; - A769B11C23E259AE00872273 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - A769B11D23E259AE00872273 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A769B13823E259AE00872273 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - 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 */; }; - A769B13E23E259AE00872273 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A769B13F23E259AE00872273 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; - A769B14023E259AE00872273 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A769B14123E259AE00872273 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A769B14223E259AE00872273 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A769B14323E259AE00872273 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A769B14423E259AE00872273 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A769B14523E259AE00872273 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A769B14623E259AE00872273 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A769B14723E259AE00872273 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A769B16123E259AE00872273 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; - A769B16323E259AE00872273 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A769B16923E259AE00872273 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.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 */; }; - 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 */; }; - A769B17423E259AE00872273 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A769B17523E259AE00872273 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A769B17623E259AE00872273 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A769B17723E259AE00872273 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A769B17823E259AE00872273 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A769B17923E259AE00872273 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A769B19223E259AE00872273 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A769B19323E259AE00872273 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A769B19423E259AE00872273 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A769B19523E259AE00872273 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A769B1A423E259AE00872273 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A769B1A523E259AE00872273 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A769B1A623E259AE00872273 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A769B1A723E259AE00872273 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - 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 */; }; - 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 */; }; - A769B1AF23E259AE00872273 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A769B1B023E259AE00872273 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A769B1B123E259AE00872273 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A769B1B223E259AE00872273 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A769B1B323E259AE00872273 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A769B1B423E259AE00872273 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A769B1B523E259AE00872273 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A769B1B623E259AE00872273 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A769B1B723E259AE00872273 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A769B1B823E259AE00872273 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A769B1B923E259AE00872273 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A769B1BA23E259AE00872273 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A769B1BB23E259AE00872273 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A769B1BC23E259AE00872273 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A769B1BD23E259AE00872273 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A769B1BE23E259AE00872273 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A769B1BF23E259AE00872273 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A769B1C023E259AE00872273 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A769B1C123E259AE00872273 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A769B1C223E259AE00872273 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A769B1C323E259AE00872273 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; - A769B1C423E259AE00872273 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A769B1C523E259AE00872273 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A769B1C623E259AE00872273 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - 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 */; }; - A769B1CB23E259AE00872273 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A769B1CD23E259AE00872273 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.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 */; }; - 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 */; }; - A769B1D623E259AE00872273 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A769B1D723E259AE00872273 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A769B1D823E259AE00872273 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A769B1D923E259AE00872273 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A769B1DA23E259AE00872273 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A769B1DB23E259AE00872273 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A769B1DC23E259AE00872273 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A769B1DD23E259AE00872273 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - 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 */; }; - A769B1E223E259AE00872273 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - 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 */; }; - A769B1E823E259AE00872273 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A769B1EA23E259AE00872273 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A769B1EB23E259AE00872273 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A769B1EC23E259AE00872273 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A769B1ED23E259AE00872273 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A769B1EE23E259AE00872273 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A769B1F923E259AE00872273 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - A769B1FA23E259AE00872273 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - 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 */; }; - 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 */; }; - A769B20323E259AE00872273 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - 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 */; }; - 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 */; }; - A769B20B23E259AE00872273 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A769B20C23E259AE00872273 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A769B20D23E259AE00872273 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A769B20E23E259AE00872273 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A769B20F23E259AE00872273 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A769B21023E259AE00872273 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A769B21123E259AE00872273 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A769B21223E259AE00872273 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A769B21323E259AE00872273 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - 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 */; }; - 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 */; }; - 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 */; }; - A769B22323E259AE00872273 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.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 */; }; - 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 */; }; - A7D88B4723E2437C00DCD162 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; }; - A7D88B4823E2437C00DCD162 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; }; - A7D88B4C23E2437C00DCD162 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; - 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 */; }; - A7D88D0723E24BED00DCD162 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; - A7D88D0823E24BED00DCD162 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; - A7D88D0B23E24BED00DCD162 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; - A7D88D0E23E24BED00DCD162 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; }; - A7D88D1023E24BED00DCD162 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; }; 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 */; }; - A7D8A94823E2514000DCD162 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; - A7D8A94923E2514000DCD162 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; - A7D8A94A23E2514000DCD162 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A7D8A94B23E2514000DCD162 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A7D8A94C23E2514000DCD162 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A7D8A94D23E2514000DCD162 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A7D8A94E23E2514000DCD162 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A7D8A94F23E2514000DCD162 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A7D8A95023E2514000DCD162 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; A7D8A95123E2514000DCD162 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A7D8A95223E2514000DCD162 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A7D8A95323E2514000DCD162 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A7D8A95423E2514000DCD162 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A7D8A95523E2514000DCD162 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; - A7D8A95623E2514000DCD162 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */; }; A7D8A95723E2514000DCD162 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; - A7D8A95823E2514000DCD162 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; - A7D8A95923E2514000DCD162 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; - A7D8A95A23E2514000DCD162 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; - A7D8A95B23E2514000DCD162 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; - A7D8A95C23E2514000DCD162 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A7D8A95D23E2514000DCD162 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A7D8A95E23E2514000DCD162 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A7D8A95F23E2514000DCD162 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A7D8A96023E2514000DCD162 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A7D8A96123E2514000DCD162 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A7D8A96223E2514000DCD162 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; A7D8A96323E2514000DCD162 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A7D8A96423E2514000DCD162 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A7D8A96523E2514000DCD162 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A7D8A96623E2514000DCD162 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A7D8A96723E2514000DCD162 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; - A7D8A96823E2514000DCD162 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; A7D8A96923E2514000DCD162 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - A7D8A96A23E2514000DCD162 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - A7D8A96B23E2514000DCD162 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - A7D8A96C23E2514000DCD162 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - A7D8A96D23E2514000DCD162 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; - A7D8A96E23E2514000DCD162 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57923E2513D00DCD162 /* SDL_dummysensor.c */; }; A7D8A96F23E2514000DCD162 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A7D8A97023E2514000DCD162 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A7D8A97123E2514000DCD162 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A7D8A97223E2514000DCD162 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A7D8A97323E2514000DCD162 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; - A7D8A97423E2514000DCD162 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; A7D8A97523E2514000DCD162 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; - A7D8A97623E2514000DCD162 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; - A7D8A97723E2514000DCD162 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; - A7D8A97823E2514000DCD162 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; - A7D8A97923E2514000DCD162 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; - A7D8A97A23E2514000DCD162 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A7D8A97B23E2514000DCD162 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A7D8A97C23E2514000DCD162 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A7D8A97D23E2514000DCD162 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A7D8A97E23E2514000DCD162 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A7D8A97F23E2514000DCD162 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; - A7D8A98023E2514000DCD162 /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57D23E2513D00DCD162 /* SDL_syssensor.h */; }; A7D8A98D23E2514000DCD162 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A7D8A98E23E2514000DCD162 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A7D8A98F23E2514000DCD162 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A7D8A99023E2514000DCD162 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A7D8A99123E2514000DCD162 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; - A7D8A99223E2514000DCD162 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; A7D8A99323E2514000DCD162 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A7D8A99423E2514000DCD162 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A7D8A99523E2514000DCD162 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A7D8A99623E2514000DCD162 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A7D8A99723E2514000DCD162 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A7D8A99823E2514000DCD162 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; A7D8A99923E2514000DCD162 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A7D8A99A23E2514000DCD162 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A7D8A99B23E2514000DCD162 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A7D8A99C23E2514000DCD162 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A7D8A99D23E2514000DCD162 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A7D8A99E23E2514000DCD162 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; A7D8AA6523E2514000DCD162 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; - A7D8AA6623E2514000DCD162 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; - A7D8AA6723E2514000DCD162 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; - A7D8AA6823E2514000DCD162 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; - A7D8AA6923E2514000DCD162 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; - A7D8AA6A23E2514000DCD162 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A7D8AAB023E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AAB323E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AAB423E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AAB523E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; A7D8AAB623E2514100DCD162 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; - A7D8AAB723E2514100DCD162 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; - A7D8AAB823E2514100DCD162 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; - A7D8AAB923E2514100DCD162 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; - A7D8AABA23E2514100DCD162 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; - A7D8AABB23E2514100DCD162 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A7D8AABC23E2514100DCD162 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; - A7D8AABD23E2514100DCD162 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; - A7D8AABE23E2514100DCD162 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; - A7D8AABF23E2514100DCD162 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; - A7D8AAC023E2514100DCD162 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; - A7D8AAC123E2514100DCD162 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; A7D8AAD423E2514100DCD162 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A7D8AAD523E2514100DCD162 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A7D8AAD623E2514100DCD162 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A7D8AAD723E2514100DCD162 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A7D8AAD823E2514100DCD162 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; - A7D8AAD923E2514100DCD162 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; A7D8AADA23E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AADB23E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AADC23E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AADD23E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AADE23E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; - A7D8AADF23E2514100DCD162 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5CE23E2513D00DCD162 /* SDL_syshaptic.c */; }; A7D8AAE023E2514100DCD162 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; - A7D8AAE123E2514100DCD162 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; - A7D8AAE223E2514100DCD162 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; - A7D8AAE323E2514100DCD162 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; - A7D8AAE423E2514100DCD162 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; - A7D8AAE523E2514100DCD162 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A7D8AB0A23E2514100DCD162 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A7D8AB0B23E2514100DCD162 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A7D8AB0C23E2514100DCD162 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A7D8AB0D23E2514100DCD162 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A7D8AB0E23E2514100DCD162 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; - A7D8AB0F23E2514100DCD162 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; A7D8AB1023E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; - A7D8AB1123E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; - A7D8AB1223E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; - A7D8AB1323E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; - A7D8AB1423E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; - A7D8AB1523E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A7D8AB1623E2514100DCD162 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A7D8AB1723E2514100DCD162 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A7D8AB1823E2514100DCD162 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A7D8AB1923E2514100DCD162 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A7D8AB1A23E2514100DCD162 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; - A7D8AB1B23E2514100DCD162 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DA23E2513D00DCD162 /* SDL_dynapi.c */; }; A7D8AB1C23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A7D8AB1D23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A7D8AB1E23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A7D8AB1F23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A7D8AB2023E2514100DCD162 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; - A7D8AB2123E2514100DCD162 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; A7D8AB2523E2514100DCD162 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; - A7D8AB2623E2514100DCD162 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; - A7D8AB2723E2514100DCD162 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; - A7D8AB2823E2514100DCD162 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; - A7D8AB2923E2514100DCD162 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; - A7D8AB2A23E2514100DCD162 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A7D8AB2B23E2514100DCD162 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A7D8AB2C23E2514100DCD162 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A7D8AB2D23E2514100DCD162 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A7D8AB2E23E2514100DCD162 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A7D8AB2F23E2514100DCD162 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; - A7D8AB3023E2514100DCD162 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DF23E2513D00DCD162 /* SDL_timer.c */; }; A7D8AB3123E2514100DCD162 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A7D8AB3223E2514100DCD162 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A7D8AB3323E2514100DCD162 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A7D8AB3423E2514100DCD162 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A7D8AB3523E2514100DCD162 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; - A7D8AB3623E2514100DCD162 /* SDL_timer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */; }; A7D8AB3723E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB3823E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB3923E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB3A23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB3B23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB3C23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A7D8AB4923E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB4A23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB4B23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; - 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 */; }; 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 */; }; - A7D8AB5E23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A7D8AB5F23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A7D8AB6023E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; - A7D8AB6223E2514100DCD162 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; - A7D8AB6323E2514100DCD162 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; - A7D8AB6423E2514100DCD162 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; - A7D8AB6523E2514100DCD162 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; - A7D8AB6623E2514100DCD162 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; A7D8AB6723E2514100DCD162 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; - A7D8AB6823E2514100DCD162 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; - A7D8AB6923E2514100DCD162 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; - A7D8AB6A23E2514100DCD162 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; - A7D8AB6B23E2514100DCD162 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; - A7D8AB6C23E2514100DCD162 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A7D8AB6D23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A7D8AB6E23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A7D8AB6F23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A7D8AB7023E2514100DCD162 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A7D8AB7123E2514100DCD162 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; - A7D8AB7223E2514100DCD162 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; A7D8AB7323E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - A7D8AB7423E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - A7D8AB7523E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - 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 */; }; 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 */; }; - A7D8AB8223E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; - A7D8AB8323E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; - A7D8AB8423E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; A7D8AB8523E2514100DCD162 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; - A7D8AB8623E2514100DCD162 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; - A7D8AB8723E2514100DCD162 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; - A7D8AB8823E2514100DCD162 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; - A7D8AB8923E2514100DCD162 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; - A7D8AB8A23E2514100DCD162 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; A7D8AB8B23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A7D8AB8C23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A7D8AB8D23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A7D8AB8E23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A7D8AB8F23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; - A7D8AB9023E2514100DCD162 /* SDL_offscreenvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */; }; A7D8ABCD23E2514100DCD162 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - A7D8ABCE23E2514100DCD162 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - A7D8ABCF23E2514100DCD162 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - A7D8ABD023E2514100DCD162 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - A7D8ABD123E2514100DCD162 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; - A7D8ABD223E2514100DCD162 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */; }; A7D8ABD323E2514100DCD162 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A7D8ABD423E2514100DCD162 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A7D8ABD523E2514100DCD162 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A7D8ABD623E2514100DCD162 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A7D8ABD723E2514100DCD162 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; - A7D8ABD823E2514100DCD162 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60323E2513D00DCD162 /* SDL_stretch.c */; }; A7D8ABD923E2514100DCD162 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - A7D8ABDA23E2514100DCD162 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - A7D8ABDB23E2514100DCD162 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - A7D8ABDC23E2514100DCD162 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - A7D8ABDD23E2514100DCD162 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - A7D8ABDE23E2514100DCD162 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; A7D8ABDF23E2514100DCD162 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A7D8ABE023E2514100DCD162 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A7D8ABE123E2514100DCD162 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A7D8ABE223E2514100DCD162 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A7D8ABE323E2514100DCD162 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; - A7D8ABE423E2514100DCD162 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60623E2513D00DCD162 /* SDL_nullframebuffer.c */; }; A7D8ABE523E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A7D8ABE623E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A7D8ABE723E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A7D8ABE823E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A7D8ABE923E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A7D8ABEA23E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; A7D8ABEB23E2514100DCD162 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; - A7D8ABEC23E2514100DCD162 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; - A7D8ABED23E2514100DCD162 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; - A7D8ABEE23E2514100DCD162 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; - A7D8ABEF23E2514100DCD162 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; - A7D8ABF023E2514100DCD162 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A7D8ABF123E2514100DCD162 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A7D8ABF223E2514100DCD162 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A7D8ABF323E2514100DCD162 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A7D8ABF423E2514100DCD162 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A7D8ABF523E2514100DCD162 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; - A7D8ABF623E2514100DCD162 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60923E2513D00DCD162 /* SDL_nullevents.c */; }; A7D8ABF723E2514100DCD162 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - A7D8ABF823E2514100DCD162 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - A7D8ABF923E2514100DCD162 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - A7D8ABFA23E2514100DCD162 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - A7D8ABFB23E2514100DCD162 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; - A7D8ABFC23E2514100DCD162 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; A7D8ABFD23E2514100DCD162 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - A7D8ABFE23E2514100DCD162 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - A7D8ABFF23E2514100DCD162 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - A7D8AC0023E2514100DCD162 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - A7D8AC0123E2514100DCD162 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; - A7D8AC0223E2514100DCD162 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; A7D8AC0323E2514100DCD162 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A7D8AC0423E2514100DCD162 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A7D8AC0523E2514100DCD162 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A7D8AC0623E2514100DCD162 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A7D8AC0723E2514100DCD162 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A7D8AC0823E2514100DCD162 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; A7D8AC0923E2514100DCD162 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A7D8AC0A23E2514100DCD162 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A7D8AC0B23E2514100DCD162 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A7D8AC0C23E2514100DCD162 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A7D8AC0D23E2514100DCD162 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; - A7D8AC0E23E2514100DCD162 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; A7D8AC0F23E2514100DCD162 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A7D8AC1223E2514100DCD162 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A7D8AC1323E2514100DCD162 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A7D8AC1423E2514100DCD162 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; A7D8AC2D23E2514100DCD162 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; - A7D8AC2E23E2514100DCD162 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; - A7D8AC2F23E2514100DCD162 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; - A7D8AC3023E2514100DCD162 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; - A7D8AC3123E2514100DCD162 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; - A7D8AC3223E2514100DCD162 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; - A7D8AC3423E2514100DCD162 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; - A7D8AC3523E2514100DCD162 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; - A7D8AC3623E2514100DCD162 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; - A7D8AC3723E2514100DCD162 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; - A7D8AC3823E2514100DCD162 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; A7D8AC3923E2514100DCD162 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A7D8AC3A23E2514100DCD162 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A7D8AC3B23E2514100DCD162 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A7D8AC3C23E2514100DCD162 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A7D8AC3D23E2514100DCD162 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; - A7D8AC3E23E2514100DCD162 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */; }; A7D8AC3F23E2514100DCD162 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A7D8AC4023E2514100DCD162 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A7D8AC4123E2514100DCD162 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A7D8AC4223E2514100DCD162 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A7D8AC4323E2514100DCD162 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A7D8AC4423E2514100DCD162 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A7D8AC4623E2514100DCD162 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A7D8AC4723E2514100DCD162 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A7D8AC4923E2514100DCD162 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A7D8AC4A23E2514100DCD162 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A7D8AC4C23E2514100DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; - A7D8AC4D23E2514100DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; - A7D8AC4F23E2514100DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; - A7D8AC5023E2514100DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; - A7D8AC5223E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; - A7D8AC5323E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; - A7D8AC5523E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; - A7D8AC5623E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; - A7D8AC5823E2514100DCD162 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; - A7D8AC5923E2514100DCD162 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; - A7D8AC5B23E2514100DCD162 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; - A7D8AC5C23E2514100DCD162 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; - A7D8AC5E23E2514100DCD162 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A7D8AC5F23E2514100DCD162 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A7D8AC6123E2514100DCD162 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A7D8AC6223E2514100DCD162 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A7D8AC6423E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; - A7D8AC6523E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; - A7D8AC6723E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; - A7D8AC6823E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; - A7D8AC6A23E2514100DCD162 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A7D8AC6B23E2514100DCD162 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A7D8AC6D23E2514100DCD162 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A7D8AC6E23E2514100DCD162 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A7D8AC7023E2514100DCD162 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A7D8AC7123E2514100DCD162 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A7D8AC7323E2514100DCD162 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A7D8AC7423E2514100DCD162 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A7D8AC7623E2514100DCD162 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; - A7D8AC7723E2514100DCD162 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; - A7D8AC7923E2514100DCD162 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; - A7D8AC7A23E2514100DCD162 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; - A7D8AC7C23E2514100DCD162 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; - A7D8AC7D23E2514100DCD162 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; - A7D8AC7F23E2514100DCD162 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; - A7D8AC8023E2514100DCD162 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; - A7D8AC8223E2514100DCD162 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A7D8AC8323E2514100DCD162 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A7D8AC8523E2514100DCD162 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A7D8AC8623E2514100DCD162 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A7D8AC8823E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A7D8AC8923E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A7D8AC8B23E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A7D8AC8C23E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A7D8AC8E23E2514100DCD162 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A7D8AC8F23E2514100DCD162 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A7D8AC9123E2514100DCD162 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A7D8AC9223E2514100DCD162 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A7D8AC9423E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A7D8AC9523E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A7D8AC9823E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A7D8AC9A23E2514100DCD162 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; - 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 */; }; - A7D8ACAA23E2514100DCD162 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; - A7D8ACAC23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; - A7D8ACAD23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; - A7D8ACAF23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; - A7D8ACB023E2514100DCD162 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; - A7D8ACB223E2514100DCD162 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A7D8ACB323E2514100DCD162 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A7D8ACB523E2514100DCD162 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A7D8ACB623E2514100DCD162 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A7D8ACB823E2514100DCD162 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A7D8ACB923E2514100DCD162 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A7D8ACBB23E2514100DCD162 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A7D8ACBC23E2514100DCD162 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A7D8ACBE23E2514100DCD162 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - A7D8ACBF23E2514100DCD162 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - A7D8ACC123E2514100DCD162 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - A7D8ACC223E2514100DCD162 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - A7D8ACC423E2514100DCD162 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; - A7D8ACC523E2514100DCD162 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; - A7D8ACC723E2514100DCD162 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; - A7D8ACC823E2514100DCD162 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; - A7D8ACCA23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A7D8ACCB23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A7D8ACCD23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A7D8ACCE23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A7D8ACD023E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A7D8ACD123E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A7D8ACD323E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A7D8ACD423E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A7D8ACD623E2514100DCD162 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A7D8ACD723E2514100DCD162 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A7D8ACD923E2514100DCD162 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A7D8ACDA23E2514100DCD162 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A7D8ACDC23E2514100DCD162 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A7D8ACDD23E2514100DCD162 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A7D8ACDF23E2514100DCD162 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A7D8ACE023E2514100DCD162 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A7D8ACE223E2514100DCD162 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A7D8ACE323E2514100DCD162 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A7D8ACE523E2514100DCD162 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A7D8ACE623E2514100DCD162 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; A7D8ACE723E2514100DCD162 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; - A7D8ACE823E2514100DCD162 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; - A7D8ACE923E2514100DCD162 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; - A7D8ACEA23E2514100DCD162 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; - A7D8ACEB23E2514100DCD162 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; - A7D8ACEC23E2514100DCD162 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A7D8AD1D23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A7D8AD1E23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A7D8AD1F23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A7D8AD2023E2514100DCD162 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A7D8AD2123E2514100DCD162 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A7D8AD2223E2514100DCD162 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; A7D8AD2323E2514100DCD162 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A7D8AD2423E2514100DCD162 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A7D8AD2523E2514100DCD162 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A7D8AD2623E2514100DCD162 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A7D8AD2723E2514100DCD162 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A7D8AD2823E2514100DCD162 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; A7D8AD2923E2514100DCD162 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A7D8AD2A23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A7D8AD2B23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A7D8AD2C23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A7D8AD2D23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; - A7D8AD2E23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */; }; A7D8AD3223E2514100DCD162 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A7D8AD3323E2514100DCD162 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A7D8AD3423E2514100DCD162 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A7D8AD3523E2514100DCD162 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A7D8AD3623E2514100DCD162 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; - A7D8AD3723E2514100DCD162 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */; }; A7D8AD6823E2514100DCD162 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A7D8AD6923E2514100DCD162 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A7D8AD6A23E2514100DCD162 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A7D8AD6B23E2514100DCD162 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A7D8AD6C23E2514100DCD162 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; - A7D8AD6D23E2514100DCD162 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64C23E2513D00DCD162 /* SDL_blit.c */; }; A7D8AD6E23E2514100DCD162 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A7D8AD6F23E2514100DCD162 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A7D8AD7023E2514100DCD162 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A7D8AD7123E2514100DCD162 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A7D8AD7223E2514100DCD162 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A7D8AD7323E2514100DCD162 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; A7D8ADE623E2514100DCD162 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; - A7D8ADE723E2514100DCD162 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; - A7D8ADE823E2514100DCD162 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; - A7D8ADE923E2514100DCD162 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; - A7D8ADEA23E2514100DCD162 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; - A7D8ADEB23E2514100DCD162 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A7D8ADEC23E2514100DCD162 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; - A7D8ADED23E2514100DCD162 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; - A7D8ADEE23E2514100DCD162 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; - A7D8ADEF23E2514100DCD162 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; - A7D8ADF023E2514100DCD162 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; - A7D8ADF123E2514100DCD162 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A7D8ADF223E2514100DCD162 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; - A7D8ADF323E2514100DCD162 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; - A7D8ADF423E2514100DCD162 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; - A7D8ADF523E2514100DCD162 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; - A7D8ADF623E2514100DCD162 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; - A7D8ADF723E2514100DCD162 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A7D8AE7623E2514100DCD162 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; - A7D8AE7723E2514100DCD162 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; - A7D8AE7823E2514100DCD162 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; - A7D8AE7923E2514100DCD162 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; - A7D8AE7A23E2514100DCD162 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; - A7D8AE7B23E2514100DCD162 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A7D8AE7C23E2514100DCD162 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; - A7D8AE7D23E2514100DCD162 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; - A7D8AE7E23E2514100DCD162 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; - A7D8AE7F23E2514100DCD162 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; - A7D8AE8023E2514100DCD162 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; - A7D8AE8123E2514100DCD162 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A7D8AE8223E2514100DCD162 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A7D8AE8323E2514100DCD162 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A7D8AE8423E2514100DCD162 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A7D8AE8523E2514100DCD162 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A7D8AE8623E2514100DCD162 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A7D8AE8723E2514100DCD162 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; A7D8AE8823E2514100DCD162 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; - A7D8AE8923E2514100DCD162 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; - A7D8AE8A23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; - A7D8AE8B23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; - A7D8AE8C23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; - A7D8AE8D23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; - A7D8AE8F23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; - A7D8AE9023E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; - A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; - A7D8AE9223E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; - A7D8AE9323E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A7D8AE9423E2514100DCD162 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; - A7D8AE9523E2514100DCD162 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; - A7D8AE9623E2514100DCD162 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; - A7D8AE9723E2514100DCD162 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; - A7D8AE9823E2514100DCD162 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; - A7D8AE9923E2514100DCD162 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A7D8AE9A23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; - A7D8AE9B23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; - A7D8AE9C23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; - A7D8AE9D23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; - A7D8AE9E23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; - A7D8AE9F23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; - A7D8AEA123E2514100DCD162 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; - A7D8AEA223E2514100DCD162 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; - A7D8AEA323E2514100DCD162 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; - A7D8AEA423E2514100DCD162 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; - A7D8AEA523E2514100DCD162 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A7D8AEA623E2514100DCD162 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A7D8AEA723E2514100DCD162 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A7D8AEA823E2514100DCD162 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A7D8AEA923E2514100DCD162 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A7D8AEAA23E2514100DCD162 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; - A7D8AEAB23E2514100DCD162 /* SDL_cocoawindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68423E2513E00DCD162 /* SDL_cocoawindow.m */; }; A7D8AEAC23E2514100DCD162 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; - A7D8AEAD23E2514100DCD162 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; - A7D8AEAE23E2514100DCD162 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; - A7D8AEAF23E2514100DCD162 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; - A7D8AEB023E2514100DCD162 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; - A7D8AEB123E2514100DCD162 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; - A7D8AEB323E2514100DCD162 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; - A7D8AEB423E2514100DCD162 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; - A7D8AEB523E2514100DCD162 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; - A7D8AEB623E2514100DCD162 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; - A7D8AEB723E2514100DCD162 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A7D8AEB823E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A7D8AEB923E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A7D8AEBA23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - 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 */; }; 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 */; }; - A7D8AEC723E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A7D8AEC823E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A7D8AEC923E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; A7D8AECA23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A7D8AECB23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A7D8AECC23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A7D8AECD23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A7D8AECE23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; - A7D8AECF23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; A7D8AED023E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A7D8AED123E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A7D8AED223E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A7D8AED323E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A7D8AED423E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; - A7D8AED523E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */; }; A7D8AED623E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A7D8AED723E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A7D8AED823E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A7D8AED923E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A7D8AEDA23E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; - A7D8AEDB23E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68C23E2513E00DCD162 /* SDL_cocoakeyboard.m */; }; A7D8AEDC23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; - A7D8AEDD23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; - A7D8AEDE23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; - A7D8AEDF23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; - A7D8AEE023E2514100DCD162 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; - A7D8AEE123E2514100DCD162 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A7D8AEE223E2514100DCD162 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A7D8AEE323E2514100DCD162 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A7D8AEE423E2514100DCD162 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A7D8AEE523E2514100DCD162 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A7D8AEE623E2514100DCD162 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; - A7D8AEE723E2514100DCD162 /* SDL_cocoashape.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68E23E2513E00DCD162 /* SDL_cocoashape.m */; }; A7D8AEE823E2514100DCD162 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; - A7D8AEE923E2514100DCD162 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; - A7D8AEEA23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; - A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; - A7D8AEEC23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; - A7D8AEED23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A7D8AEEE23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; - A7D8AEEF23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; - A7D8AEF023E2514100DCD162 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; - A7D8AEF123E2514100DCD162 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; - A7D8AEF223E2514100DCD162 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; - A7D8AEF323E2514100DCD162 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; A7D8AEF423E2514100DCD162 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A7D8AEF523E2514100DCD162 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A7D8AEF623E2514100DCD162 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A7D8AEF723E2514100DCD162 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A7D8AEF823E2514100DCD162 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; - A7D8AEF923E2514100DCD162 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; A7D8AEFA23E2514100DCD162 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A7D8AEFB23E2514100DCD162 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A7D8AEFC23E2514100DCD162 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A7D8AEFD23E2514100DCD162 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A7D8AEFE23E2514100DCD162 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A7D8AEFF23E2514100DCD162 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; A7D8AF0023E2514100DCD162 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A7D8AF0123E2514100DCD162 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A7D8AF0223E2514100DCD162 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A7D8AF0323E2514100DCD162 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A7D8AF0423E2514100DCD162 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; A7D8AF0623E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A7D8AF0723E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A7D8AF0823E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A7D8AF0923E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A7D8AF0B23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; A7D8AF0C23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A7D8AF0D23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A7D8AF0E23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A7D8AF0F23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A7D8AF1023E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; - A7D8AF1123E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */; }; A7D8AF1223E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - A7D8AF1323E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - A7D8AF1423E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - 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 */; }; 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 */; }; - A7D8AF2123E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; - A7D8AF2223E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; - A7D8AF2323E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A7D8AF2423E2514100DCD162 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; - A7D8AF2523E2514100DCD162 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; - A7D8AF2623E2514100DCD162 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; - A7D8AF2723E2514100DCD162 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; - A7D8AF2823E2514100DCD162 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; - A7D8AF2923E2514100DCD162 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; - A7D8AFC123E2514200DCD162 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; - A7D8AFC223E2514200DCD162 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; - A7D8AFC323E2514200DCD162 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; - A7D8AFC423E2514200DCD162 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; - A7D8AFC523E2514200DCD162 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A7D8B14023E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A7D8B14123E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A7D8B14223E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - 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 */; }; 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 */; }; - A7D8B22723E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; - A7D8B22823E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; - A7D8B22923E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A7D8B22A23E2514200DCD162 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A7D8B22B23E2514200DCD162 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A7D8B22C23E2514200DCD162 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A7D8B22D23E2514200DCD162 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A7D8B22E23E2514200DCD162 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; - A7D8B22F23E2514200DCD162 /* gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72423E2513E00DCD162 /* gl2.h */; }; A7D8B23023E2514200DCD162 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; - A7D8B23123E2514200DCD162 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; - A7D8B23223E2514200DCD162 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; - A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; - A7D8B23423E2514200DCD162 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; - A7D8B23523E2514200DCD162 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; A7D8B23623E2514200DCD162 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A7D8B23723E2514200DCD162 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A7D8B23823E2514200DCD162 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A7D8B23923E2514200DCD162 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A7D8B23A23E2514200DCD162 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A7D8B23B23E2514200DCD162 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; A7D8B23C23E2514200DCD162 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A7D8B23D23E2514200DCD162 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A7D8B23E23E2514200DCD162 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A7D8B23F23E2514200DCD162 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A7D8B24023E2514200DCD162 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; - A7D8B24123E2514200DCD162 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; A7D8B24223E2514200DCD162 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; - A7D8B24323E2514200DCD162 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; - A7D8B24423E2514200DCD162 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; - A7D8B24523E2514200DCD162 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; - A7D8B24623E2514200DCD162 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; - A7D8B24723E2514200DCD162 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A7D8B24823E2514200DCD162 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A7D8B24923E2514200DCD162 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A7D8B24A23E2514200DCD162 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A7D8B24B23E2514200DCD162 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A7D8B24C23E2514200DCD162 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A7D8B24D23E2514200DCD162 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; A7D8B24E23E2514200DCD162 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A7D8B24F23E2514200DCD162 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A7D8B25023E2514200DCD162 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A7D8B25123E2514200DCD162 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A7D8B25223E2514200DCD162 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A7D8B25323E2514200DCD162 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; A7D8B25423E2514200DCD162 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A7D8B25523E2514200DCD162 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A7D8B25623E2514200DCD162 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A7D8B25723E2514200DCD162 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A7D8B25823E2514200DCD162 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; - A7D8B25923E2514200DCD162 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; A7D8B25A23E2514200DCD162 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A7D8B25B23E2514200DCD162 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A7D8B25C23E2514200DCD162 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A7D8B25D23E2514200DCD162 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A7D8B25E23E2514200DCD162 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A7D8B25F23E2514200DCD162 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; A7D8B26023E2514200DCD162 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A7D8B26123E2514200DCD162 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A7D8B26223E2514200DCD162 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A7D8B26323E2514200DCD162 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A7D8B26423E2514200DCD162 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; - A7D8B26523E2514200DCD162 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; A7D8B26623E2514200DCD162 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; - A7D8B26723E2514200DCD162 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; - A7D8B26823E2514200DCD162 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; - 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 */; }; - A7D8B27523E2514200DCD162 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; - A7D8B27623E2514200DCD162 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; - A7D8B27723E2514200DCD162 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; A7D8B27823E2514200DCD162 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A7D8B27923E2514200DCD162 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A7D8B27A23E2514200DCD162 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A7D8B27B23E2514200DCD162 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A7D8B27C23E2514200DCD162 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A7D8B27D23E2514200DCD162 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; A7D8B27E23E2514200DCD162 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A7D8B27F23E2514200DCD162 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A7D8B28023E2514200DCD162 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A7D8B28123E2514200DCD162 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A7D8B28223E2514200DCD162 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; - A7D8B28323E2514200DCD162 /* vulkan_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73523E2513E00DCD162 /* vulkan_win32.h */; }; A7D8B28423E2514200DCD162 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A7D8B28523E2514200DCD162 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A7D8B28623E2514200DCD162 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A7D8B28723E2514200DCD162 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A7D8B28823E2514200DCD162 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; - A7D8B28923E2514200DCD162 /* vulkan_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73623E2513E00DCD162 /* vulkan_macos.h */; }; A7D8B28A23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A7D8B28B23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A7D8B28C23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A7D8B28D23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A7D8B28E23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; - A7D8B28F23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */; }; A7D8B29023E2514200DCD162 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; - A7D8B29123E2514200DCD162 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; - A7D8B29223E2514200DCD162 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; - 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 */; }; - A7D8B29F23E2514200DCD162 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; - A7D8B2A023E2514200DCD162 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; - A7D8B2A123E2514200DCD162 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A7D8B2A223E2514200DCD162 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A7D8B2A323E2514200DCD162 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A7D8B2A423E2514200DCD162 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A7D8B2A523E2514200DCD162 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A7D8B2A623E2514200DCD162 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; - A7D8B2A723E2514200DCD162 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; A7D8B2A823E2514200DCD162 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A7D8B2A923E2514200DCD162 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A7D8B2AA23E2514200DCD162 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A7D8B2AB23E2514200DCD162 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A7D8B2AC23E2514200DCD162 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; - A7D8B2AD23E2514200DCD162 /* vulkan_core.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73C23E2513E00DCD162 /* vulkan_core.h */; }; A7D8B2AE23E2514200DCD162 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; - A7D8B2AF23E2514200DCD162 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; - A7D8B2B023E2514200DCD162 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; - A7D8B2B123E2514200DCD162 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; - A7D8B2B223E2514200DCD162 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; - A7D8B2B323E2514200DCD162 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A7D8B2B423E2514200DCD162 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A7D8B2B523E2514200DCD162 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A7D8B2B623E2514200DCD162 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A7D8B2B723E2514200DCD162 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A7D8B2B823E2514200DCD162 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; - A7D8B2B923E2514200DCD162 /* vulkan_android.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73E23E2513E00DCD162 /* vulkan_android.h */; }; A7D8B2BA23E2514200DCD162 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A7D8B2BB23E2514200DCD162 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A7D8B2BC23E2514200DCD162 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A7D8B2BD23E2514200DCD162 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A7D8B2BE23E2514200DCD162 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; - A7D8B2BF23E2514200DCD162 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; A7D8B2C023E2514200DCD162 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A7D8B2C123E2514200DCD162 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A7D8B2C223E2514200DCD162 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A7D8B2C323E2514200DCD162 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A7D8B2C423E2514200DCD162 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A7D8B2C523E2514200DCD162 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; A7D8B39823E2514200DCD162 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; - A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; - A7D8B39A23E2514200DCD162 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; - A7D8B39B23E2514200DCD162 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; - A7D8B39C23E2514200DCD162 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; - A7D8B39D23E2514200DCD162 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A7D8B39E23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; - A7D8B39F23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; - A7D8B3A023E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; - A7D8B3A123E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; - A7D8B3A223E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; - A7D8B3A323E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A7D8B3A423E2514200DCD162 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A7D8B3A523E2514200DCD162 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A7D8B3A623E2514200DCD162 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A7D8B3A723E2514200DCD162 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A7D8B3A823E2514200DCD162 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; - A7D8B3A923E2514200DCD162 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */; }; A7D8B3AA23E2514200DCD162 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; - A7D8B3AB23E2514200DCD162 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; - A7D8B3AC23E2514200DCD162 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; - A7D8B3AD23E2514200DCD162 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; - A7D8B3AE23E2514200DCD162 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; - A7D8B3AF23E2514200DCD162 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A7D8B3B023E2514200DCD162 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; - A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; - A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; - A7D8B3B323E2514200DCD162 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; - A7D8B3B423E2514200DCD162 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; - A7D8B3B523E2514200DCD162 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A7D8B3B623E2514200DCD162 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - A7D8B3B723E2514200DCD162 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - A7D8B3B823E2514200DCD162 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - 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 */; }; - A7D8B3CB23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A7D8B3CC23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A7D8B3CD23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; A7D8B3CE23E2514300DCD162 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A7D8B3CF23E2514300DCD162 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A7D8B3D023E2514300DCD162 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A7D8B3D123E2514300DCD162 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A7D8B3D223E2514300DCD162 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; - A7D8B3D323E2514300DCD162 /* yuv_rgb_std_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */; }; A7D8B3D423E2514300DCD162 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; - A7D8B3D523E2514300DCD162 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; - A7D8B3D623E2514300DCD162 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; - A7D8B3D723E2514300DCD162 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; - A7D8B3D823E2514300DCD162 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; - A7D8B3D923E2514300DCD162 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A7D8B3DA23E2514300DCD162 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A7D8B3DB23E2514300DCD162 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A7D8B3DC23E2514300DCD162 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A7D8B3DD23E2514300DCD162 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A7D8B3DE23E2514300DCD162 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; - A7D8B3DF23E2514300DCD162 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77323E2513E00DCD162 /* SDL_bmp.c */; }; A7D8B3E023E2514300DCD162 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; - A7D8B3E123E2514300DCD162 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; - A7D8B3E223E2514300DCD162 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; - A7D8B3E323E2514300DCD162 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; - A7D8B3E423E2514300DCD162 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; - A7D8B3E523E2514300DCD162 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A7D8B3E623E2514300DCD162 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A7D8B3E723E2514300DCD162 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A7D8B3E823E2514300DCD162 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A7D8B3E923E2514300DCD162 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A7D8B3EA23E2514300DCD162 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A7D8B3EB23E2514300DCD162 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; A7D8B3EC23E2514300DCD162 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; - A7D8B3ED23E2514300DCD162 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; - A7D8B3EE23E2514300DCD162 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; - A7D8B3EF23E2514300DCD162 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; - A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; - A7D8B3F123E2514300DCD162 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A7D8B3F223E2514300DCD162 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; - A7D8B3F323E2514300DCD162 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; - A7D8B3F423E2514300DCD162 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; - A7D8B3F523E2514300DCD162 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; - A7D8B3F623E2514300DCD162 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; - A7D8B3F723E2514300DCD162 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A7D8B41C23E2514300DCD162 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A7D8B41D23E2514300DCD162 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A7D8B41E23E2514300DCD162 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A7D8B41F23E2514300DCD162 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A7D8B42023E2514300DCD162 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; - A7D8B42123E2514300DCD162 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78223E2513E00DCD162 /* SDL_systls.c */; }; A7D8B42223E2514300DCD162 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; - A7D8B42323E2514300DCD162 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; - A7D8B42423E2514300DCD162 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; - A7D8B42523E2514300DCD162 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; - A7D8B42623E2514300DCD162 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; - A7D8B42723E2514300DCD162 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A7D8B42823E2514300DCD162 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A7D8B42923E2514300DCD162 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A7D8B42A23E2514300DCD162 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A7D8B42C23E2514300DCD162 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A7D8B42D23E2514300DCD162 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; A7D8B42E23E2514300DCD162 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A7D8B42F23E2514300DCD162 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A7D8B43023E2514300DCD162 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A7D8B43123E2514300DCD162 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A7D8B43223E2514300DCD162 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; - A7D8B43323E2514300DCD162 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78523E2513E00DCD162 /* SDL_syscond.c */; }; A7D8B43423E2514300DCD162 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; - A7D8B43523E2514300DCD162 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; - A7D8B43623E2514300DCD162 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; - A7D8B43723E2514300DCD162 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; - A7D8B43823E2514300DCD162 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; - A7D8B43923E2514300DCD162 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; A7D8B43A23E2514300DCD162 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - A7D8B43B23E2514300DCD162 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - A7D8B43C23E2514300DCD162 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - A7D8B43D23E2514300DCD162 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - A7D8B43E23E2514300DCD162 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; - A7D8B43F23E2514300DCD162 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78723E2513E00DCD162 /* SDL_sysmutex.c */; }; A7D8B44023E2514300DCD162 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A7D8B44123E2514300DCD162 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A7D8B44223E2514300DCD162 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A7D8B44323E2514300DCD162 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A7D8B44423E2514300DCD162 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; - A7D8B44523E2514300DCD162 /* SDL_sysmutex_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78823E2513E00DCD162 /* SDL_sysmutex_c.h */; }; A7D8B4AC23E2514300DCD162 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.h */; }; - A7D8B4AD23E2514300DCD162 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.h */; }; - A7D8B4AE23E2514300DCD162 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.h */; }; - A7D8B4AF23E2514300DCD162 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.h */; }; - A7D8B4B023E2514300DCD162 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.h */; }; - A7D8B4B123E2514300DCD162 /* SDL_gamepad_db.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamepad_db.h */; }; A7D8B4B223E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B4B323E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B4B423E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B4B523E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B4B623E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B4B723E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B4C523E2514300DCD162 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; - A7D8B4C623E2514300DCD162 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; - A7D8B4C823E2514300DCD162 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; - A7D8B4D123E2514300DCD162 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; - A7D8B4D223E2514300DCD162 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; - A7D8B4D423E2514300DCD162 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A7D8B4DC23E2514300DCD162 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - A7D8B4DD23E2514300DCD162 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - A7D8B4DE23E2514300DCD162 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - 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 */; }; A7D8B4EE23E2514300DCD162 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - A7D8B4EF23E2514300DCD162 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - A7D8B4F023E2514300DCD162 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - A7D8B4F123E2514300DCD162 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - A7D8B4F223E2514300DCD162 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; - A7D8B4F323E2514300DCD162 /* SDL_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamepad.c */; }; A7D8B53923E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; - A7D8B53A23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; - A7D8B53B23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; - A7D8B53C23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; - A7D8B53D23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; - A7D8B53E23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A7D8B53F23E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; - A7D8B54023E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; - A7D8B54123E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; - A7D8B54223E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; - A7D8B54323E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; - A7D8B54423E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A7D8B54523E2514300DCD162 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; - A7D8B54623E2514300DCD162 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; - A7D8B54723E2514300DCD162 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; - A7D8B54823E2514300DCD162 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; - A7D8B54923E2514300DCD162 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; - A7D8B54A23E2514300DCD162 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A7D8B54B23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; - A7D8B54C23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; - A7D8B54D23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; - A7D8B54E23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; - A7D8B54F23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; - A7D8B55023E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A7D8B55123E2514300DCD162 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; - A7D8B55223E2514300DCD162 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; - A7D8B55323E2514300DCD162 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; - A7D8B55423E2514300DCD162 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; - A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; - A7D8B55623E2514300DCD162 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A7D8B55723E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; - A7D8B55823E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; - A7D8B55923E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; - A7D8B55A23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; - A7D8B55B23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; - A7D8B55C23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A7D8B55D23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; - A7D8B55E23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; - A7D8B55F23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; - A7D8B56023E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; - A7D8B56123E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; - A7D8B56223E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A7D8B56323E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; - A7D8B56423E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; - A7D8B56523E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; - A7D8B56623E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; - A7D8B56723E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; - A7D8B56823E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; A7D8B56F23E2514300DCD162 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; - A7D8B57023E2514300DCD162 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; - A7D8B57123E2514300DCD162 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; - 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 */; }; 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 */; }; - A7D8B58423E2514300DCD162 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; - A7D8B58523E2514300DCD162 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; - A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A7D8B58723E2514300DCD162 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; - A7D8B58823E2514300DCD162 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; - A7D8B58923E2514300DCD162 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; - A7D8B58A23E2514300DCD162 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; - A7D8B58B23E2514300DCD162 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; - A7D8B58C23E2514300DCD162 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A7D8B5B723E2514300DCD162 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A7D8B5B823E2514300DCD162 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A7D8B5B923E2514300DCD162 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A7D8B5BA23E2514300DCD162 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A7D8B5BB23E2514300DCD162 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A7D8B5BC23E2514300DCD162 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; A7D8B5BD23E2514300DCD162 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A7D8B5BE23E2514300DCD162 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A7D8B5BF23E2514300DCD162 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A7D8B5C023E2514300DCD162 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A7D8B5C123E2514300DCD162 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; - A7D8B5C223E2514300DCD162 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DB23E2513F00DCD162 /* SDL_rwops.c */; }; A7D8B5C323E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A7D8B5C423E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A7D8B5C523E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A7D8B5C623E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A7D8B5C723E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; - A7D8B5C823E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7DD23E2513F00DCD162 /* SDL_rwopsbundlesupport.h */; }; A7D8B5C923E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; - A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; - A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; - A7D8B5CC23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; - A7D8B5CD23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; - A7D8B5CE23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; A7D8B5CF23E2514300DCD162 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A7D8B5D023E2514300DCD162 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A7D8B5D123E2514300DCD162 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A7D8B5D223E2514300DCD162 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A7D8B5D323E2514300DCD162 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; - A7D8B5D423E2514300DCD162 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E123E2513F00DCD162 /* SDL_syspower.m */; }; A7D8B5D523E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B5D623E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B5D723E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B5D823E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B5DA23E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; A7D8B5E723E2514300DCD162 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A7D8B5E823E2514300DCD162 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A7D8B5E923E2514300DCD162 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A7D8B5EA23E2514300DCD162 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A7D8B5EB23E2514300DCD162 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; - A7D8B5EC23E2514300DCD162 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7E723E2513F00DCD162 /* SDL_power.c */; }; A7D8B5F323E2514300DCD162 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A7D8B5F423E2514300DCD162 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A7D8B5F523E2514300DCD162 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A7D8B5F723E2514300DCD162 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; A7D8B61123E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B61223E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B61323E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B61423E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B61523E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; - A7D8B61623E2514300DCD162 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F423E2513F00DCD162 /* SDL_syspower.h */; }; A7D8B61723E2514300DCD162 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A7D8B61823E2514300DCD162 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A7D8B61923E2514300DCD162 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A7D8B61A23E2514300DCD162 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A7D8B61B23E2514300DCD162 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; - A7D8B61C23E2514300DCD162 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; A7D8B61D23E2514300DCD162 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A7D8B61E23E2514300DCD162 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A7D8B61F23E2514300DCD162 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A7D8B62023E2514300DCD162 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A7D8B62123E2514300DCD162 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; - A7D8B62223E2514300DCD162 /* SDL_sysfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7F823E2513F00DCD162 /* SDL_sysfilesystem.c */; }; A7D8B62F23E2514300DCD162 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; - A7D8B63023E2514300DCD162 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; - A7D8B63123E2514300DCD162 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; - A7D8B63223E2514300DCD162 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; - A7D8B63323E2514300DCD162 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; - A7D8B63423E2514300DCD162 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; A7D8B75223E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B75323E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B75423E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B75523E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B75623E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B75723E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A85F23E2513F00DCD162 /* SDL_sysloadso.c */; }; A7D8B75E23E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B75F23E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B76023E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B76123E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B76223E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; A7D8B76423E2514300DCD162 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - A7D8B76523E2514300DCD162 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - A7D8B76623E2514300DCD162 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - A7D8B76723E2514300DCD162 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - A7D8B76823E2514300DCD162 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; - A7D8B76923E2514300DCD162 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86523E2513F00DCD162 /* SDL_mixer.c */; }; A7D8B76A23E2514300DCD162 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A7D8B76B23E2514300DCD162 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A7D8B76C23E2514300DCD162 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A7D8B76D23E2514300DCD162 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A7D8B76E23E2514300DCD162 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; - A7D8B76F23E2514300DCD162 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86623E2513F00DCD162 /* SDL_wave.c */; }; A7D8B79423E2514400DCD162 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; - A7D8B79523E2514400DCD162 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; - A7D8B79623E2514400DCD162 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; - A7D8B79723E2514400DCD162 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; - A7D8B79823E2514400DCD162 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; - A7D8B79923E2514400DCD162 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A7D8B79A23E2514400DCD162 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A7D8B79B23E2514400DCD162 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A7D8B79C23E2514400DCD162 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A7D8B79D23E2514400DCD162 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A7D8B79E23E2514400DCD162 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; - A7D8B79F23E2514400DCD162 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A87223E2513F00DCD162 /* SDL_dummyaudio.c */; }; A7D8B7A023E2514400DCD162 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A7D8B7A123E2514400DCD162 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A7D8B7A223E2514400DCD162 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A7D8B7A323E2514400DCD162 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A7D8B7A423E2514400DCD162 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; - A7D8B7A523E2514400DCD162 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87323E2513F00DCD162 /* SDL_audio_c.h */; }; A7D8B7B223E2514400DCD162 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; - A7D8B7B323E2514400DCD162 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; - A7D8B7B423E2514400DCD162 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; - A7D8B7B523E2514400DCD162 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; - A7D8B7B623E2514400DCD162 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; - A7D8B7B723E2514400DCD162 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; A7D8B81823E2514400DCD162 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A7D8B81923E2514400DCD162 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A7D8B81A23E2514400DCD162 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A7D8B81B23E2514400DCD162 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A7D8B81C23E2514400DCD162 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; - A7D8B81D23E2514400DCD162 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A88F23E2513F00DCD162 /* SDL_audiodev.c */; }; A7D8B85A23E2514400DCD162 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; - A7D8B85B23E2514400DCD162 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; - A7D8B85C23E2514400DCD162 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; - A7D8B85D23E2514400DCD162 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; - A7D8B85E23E2514400DCD162 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; - A7D8B85F23E2514400DCD162 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; A7D8B86023E2514400DCD162 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; - A7D8B86123E2514400DCD162 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; - A7D8B86223E2514400DCD162 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; - A7D8B86323E2514400DCD162 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; - A7D8B86423E2514400DCD162 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; - A7D8B86523E2514400DCD162 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A7D8B86623E2514400DCD162 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; - A7D8B86723E2514400DCD162 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; - A7D8B86823E2514400DCD162 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; - A7D8B86923E2514400DCD162 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; - A7D8B86A23E2514400DCD162 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; - A7D8B86B23E2514400DCD162 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A7D8B86C23E2514400DCD162 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; - A7D8B86D23E2514400DCD162 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; - A7D8B86E23E2514400DCD162 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; - A7D8B86F23E2514400DCD162 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; - A7D8B87023E2514400DCD162 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; - A7D8B87123E2514400DCD162 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A7D8B8A223E2514400DCD162 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A7D8B8A323E2514400DCD162 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A7D8B8A423E2514400DCD162 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A7D8B8A523E2514400DCD162 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A7D8B8A623E2514400DCD162 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A7D8B8A723E2514400DCD162 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - A7D8B8A923E2514400DCD162 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - A7D8B8AA23E2514400DCD162 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - A7D8B8AB23E2514400DCD162 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - A7D8B8AC23E2514400DCD162 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - A7D8B8AD23E2514400DCD162 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; A7D8B8C623E2514400DCD162 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A7D8B8C723E2514400DCD162 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A7D8B8C823E2514400DCD162 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A7D8B8C923E2514400DCD162 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A7D8B8CA23E2514400DCD162 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; - A7D8B8CB23E2514400DCD162 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B823E2513F00DCD162 /* SDL_audio.c */; }; A7D8B8CC23E2514400DCD162 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; - A7D8B8CD23E2514400DCD162 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; - A7D8B8CE23E2514400DCD162 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; - A7D8B8CF23E2514400DCD162 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; - A7D8B8D023E2514400DCD162 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; - A7D8B8D123E2514400DCD162 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A7D8B8D223E2514400DCD162 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; - A7D8B8D323E2514400DCD162 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; - A7D8B8D423E2514400DCD162 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; - A7D8B8D523E2514400DCD162 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; - A7D8B8D623E2514400DCD162 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; - A7D8B8D723E2514400DCD162 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A7D8B8E423E2514400DCD162 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A7D8B8E523E2514400DCD162 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A7D8B8E623E2514400DCD162 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A7D8B8E723E2514400DCD162 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A7D8B8E823E2514400DCD162 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; - A7D8B8E923E2514400DCD162 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BF23E2513F00DCD162 /* SDL_error.c */; }; A7D8B94A23E2514400DCD162 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; - A7D8B94B23E2514400DCD162 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; - A7D8B94C23E2514400DCD162 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; - A7D8B94D23E2514400DCD162 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; - A7D8B94E23E2514400DCD162 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; - A7D8B94F23E2514400DCD162 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A7D8B95023E2514400DCD162 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; - A7D8B95123E2514400DCD162 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; - A7D8B95223E2514400DCD162 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; - A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; - A7D8B95423E2514400DCD162 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; - A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A7D8B95623E2514400DCD162 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; - A7D8B95723E2514400DCD162 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; - A7D8B95823E2514400DCD162 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; - A7D8B95923E2514400DCD162 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; - A7D8B95A23E2514400DCD162 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; - A7D8B95B23E2514400DCD162 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; A7D8B95C23E2514400DCD162 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; - A7D8B95D23E2514400DCD162 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; - A7D8B95E23E2514400DCD162 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; - A7D8B95F23E2514400DCD162 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; - A7D8B96023E2514400DCD162 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; - A7D8B96123E2514400DCD162 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A7D8B96223E2514400DCD162 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; - A7D8B96323E2514400DCD162 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; - A7D8B96423E2514400DCD162 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; - A7D8B96523E2514400DCD162 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; - A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; - A7D8B96723E2514400DCD162 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A7D8B96823E2514400DCD162 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - A7D8B96923E2514400DCD162 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - A7D8B96A23E2514400DCD162 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - A7D8B96B23E2514400DCD162 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - A7D8B96C23E2514400DCD162 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; - A7D8B96D23E2514400DCD162 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D723E2514000DCD162 /* SDL_qsort.c */; }; A7D8B96E23E2514400DCD162 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A7D8B96F23E2514400DCD162 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A7D8B97023E2514400DCD162 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A7D8B97123E2514400DCD162 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A7D8B97223E2514400DCD162 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; - A7D8B97323E2514400DCD162 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */; }; A7D8B97423E2514400DCD162 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; - A7D8B97523E2514400DCD162 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; - A7D8B97623E2514400DCD162 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; - A7D8B97723E2514400DCD162 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; - A7D8B97823E2514400DCD162 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; - A7D8B97923E2514400DCD162 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; A7D8B97A23E2514400DCD162 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; - A7D8B97B23E2514400DCD162 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; - A7D8B97C23E2514400DCD162 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; - A7D8B97D23E2514400DCD162 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; - A7D8B97E23E2514400DCD162 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; - A7D8B97F23E2514400DCD162 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; A7D8B98023E2514400DCD162 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A7D8B98123E2514400DCD162 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A7D8B98223E2514400DCD162 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A7D8B98323E2514400DCD162 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A7D8B98423E2514400DCD162 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A7D8B98523E2514400DCD162 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; A7D8B98623E2514400DCD162 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; - A7D8B98723E2514400DCD162 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; - A7D8B98823E2514400DCD162 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; - A7D8B98923E2514400DCD162 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; - A7D8B98A23E2514400DCD162 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; - A7D8B98B23E2514400DCD162 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A7D8B98C23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; - A7D8B98D23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; - A7D8B98E23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; - A7D8B98F23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; - A7D8B99023E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; - A7D8B99123E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A7D8B99223E2514400DCD162 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; - A7D8B99323E2514400DCD162 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; - A7D8B99423E2514400DCD162 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; - A7D8B99523E2514400DCD162 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; - A7D8B99623E2514400DCD162 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; - A7D8B99723E2514400DCD162 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A7D8B99B23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.h */; }; - A7D8B99C23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.h */; }; - A7D8B99D23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.h */; }; - A7D8B99E23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.h */; }; - A7D8B99F23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.h */; }; - A7D8B9A023E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_macos.h */; }; A7D8B9A123E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A7D8B9A223E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A7D8B9A323E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A7D8B9A423E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A7D8B9A523E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A7D8B9A623E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; A7D8B9CB23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A7D8B9CC23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A7D8B9CD23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A7D8B9CE23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A7D8B9CF23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A7D8B9D023E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; A7D8B9D123E2514400DCD162 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A7D8B9D223E2514400DCD162 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A7D8B9D323E2514400DCD162 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A7D8B9D423E2514400DCD162 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A7D8B9D523E2514400DCD162 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; - A7D8B9D623E2514400DCD162 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8ED23E2514000DCD162 /* SDL_yuv_sw.c */; }; A7D8B9D723E2514400DCD162 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A7D8B9D823E2514400DCD162 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A7D8B9D923E2514400DCD162 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A7D8B9DA23E2514400DCD162 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A7D8B9DB23E2514400DCD162 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; - A7D8B9DC23E2514400DCD162 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; A7D8B9DD23E2514400DCD162 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A7D8B9DE23E2514400DCD162 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A7D8B9DF23E2514400DCD162 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A7D8B9E023E2514400DCD162 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A7D8B9E123E2514400DCD162 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; - A7D8B9E223E2514400DCD162 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F023E2514000DCD162 /* SDL_blendpoint.c */; }; A7D8B9E323E2514400DCD162 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; - A7D8B9E423E2514400DCD162 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; - A7D8B9E523E2514400DCD162 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; - A7D8B9E623E2514400DCD162 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; - A7D8B9E723E2514400DCD162 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; - A7D8B9E823E2514400DCD162 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A7D8B9E923E2514400DCD162 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A7D8B9EA23E2514400DCD162 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A7D8B9EB23E2514400DCD162 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A7D8B9EC23E2514400DCD162 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A7D8B9ED23E2514400DCD162 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; - A7D8B9EE23E2514400DCD162 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; A7D8B9EF23E2514400DCD162 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - A7D8B9F023E2514400DCD162 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - A7D8B9F123E2514400DCD162 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - A7D8B9F223E2514400DCD162 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - A7D8B9F323E2514400DCD162 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - A7D8B9F423E2514400DCD162 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; A7D8B9F523E2514400DCD162 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; - A7D8B9F623E2514400DCD162 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; - A7D8B9F723E2514400DCD162 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; - A7D8B9F823E2514400DCD162 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; - A7D8B9F923E2514400DCD162 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; - A7D8B9FA23E2514400DCD162 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A7D8B9FB23E2514400DCD162 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; - A7D8B9FC23E2514400DCD162 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; - A7D8B9FD23E2514400DCD162 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; - A7D8B9FE23E2514400DCD162 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; - A7D8B9FF23E2514400DCD162 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; - A7D8BA0023E2514400DCD162 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; A7D8BA0123E2514400DCD162 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - A7D8BA0223E2514400DCD162 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - A7D8BA0323E2514400DCD162 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - A7D8BA0423E2514400DCD162 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - A7D8BA0523E2514400DCD162 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - A7D8BA0623E2514400DCD162 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; A7D8BA0723E2514400DCD162 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; - A7D8BA0823E2514400DCD162 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; - A7D8BA0923E2514400DCD162 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; - A7D8BA0A23E2514400DCD162 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; - A7D8BA0B23E2514400DCD162 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; - A7D8BA0C23E2514400DCD162 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; A7D8BA0D23E2514400DCD162 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A7D8BA0E23E2514400DCD162 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A7D8BA0F23E2514400DCD162 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A7D8BA1023E2514400DCD162 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A7D8BA1123E2514400DCD162 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; - A7D8BA1223E2514400DCD162 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; A7D8BA1323E2514400DCD162 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A7D8BA1423E2514400DCD162 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A7D8BA1523E2514400DCD162 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A7D8BA1623E2514400DCD162 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A7D8BA1723E2514400DCD162 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A7D8BA1823E2514400DCD162 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; A7D8BA1923E2514400DCD162 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; - A7D8BA1A23E2514400DCD162 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; - A7D8BA1B23E2514400DCD162 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; - A7D8BA1C23E2514400DCD162 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; - A7D8BA1D23E2514400DCD162 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; - A7D8BA1E23E2514400DCD162 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A7D8BA1F23E2514400DCD162 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; - A7D8BA2023E2514400DCD162 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; - A7D8BA2123E2514400DCD162 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; - A7D8BA2223E2514400DCD162 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; - A7D8BA2323E2514400DCD162 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; - A7D8BA2423E2514400DCD162 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A7D8BA2523E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; - A7D8BA2623E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; - A7D8BA2723E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; - A7D8BA2823E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; - A7D8BA2923E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; - A7D8BA2A23E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A7D8BA2B23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A7D8BA2C23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A7D8BA2D23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A7D8BA2E23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A7D8BA2F23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; - A7D8BA3023E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; }; A7D8BA3123E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; - A7D8BA3223E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; - A7D8BA3323E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; - A7D8BA3423E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; - A7D8BA3523E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; - A7D8BA3623E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A7D8BA3823E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A7D8BA3923E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A7D8BA3A23E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A7D8BA3B23E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A7D8BA3C23E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; A7D8BA4923E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - A7D8BA4A23E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - A7D8BA4B23E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - A7D8BA4C23E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - A7D8BA4D23E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; - A7D8BA4E23E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; }; A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A7D8BA5023E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A7D8BA5123E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A7D8BA5223E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A7D8BA5323E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A7D8BA5423E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; A7D8BA5523E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A7D8BA5623E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A7D8BA5723E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A7D8BA5823E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A7D8BA5923E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A7D8BA5A23E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; A7D8BA5B23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; - A7D8BA5C23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; - A7D8BA5D23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; - A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; - A7D8BA5F23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; - A7D8BA6023E2514400DCD162 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A7D8BA7323E2514400DCD162 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; - A7D8BA7423E2514400DCD162 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; - A7D8BA7523E2514400DCD162 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; - A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; - A7D8BA7723E2514400DCD162 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; - A7D8BA7823E2514400DCD162 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A7D8BA7923E2514400DCD162 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A7D8BA7A23E2514400DCD162 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A7D8BA7B23E2514400DCD162 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A7D8BA7C23E2514400DCD162 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A7D8BA7D23E2514400DCD162 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A7D8BA7E23E2514400DCD162 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; A7D8BA7F23E2514400DCD162 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; - A7D8BA8023E2514400DCD162 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; - A7D8BA8123E2514400DCD162 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; - A7D8BA8223E2514400DCD162 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; - A7D8BA8323E2514400DCD162 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; - A7D8BA8423E2514400DCD162 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A7D8BA8523E2514400DCD162 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A7D8BA8623E2514400DCD162 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A7D8BA8723E2514400DCD162 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A7D8BA8823E2514400DCD162 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A7D8BA8923E2514400DCD162 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; - A7D8BA8A23E2514400DCD162 /* SDL_shaders_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91023E2514000DCD162 /* SDL_shaders_gl.c */; }; A7D8BA8B23E2514400DCD162 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A7D8BA8C23E2514400DCD162 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A7D8BA8D23E2514400DCD162 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A7D8BA8E23E2514400DCD162 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A7D8BA8F23E2514400DCD162 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; - A7D8BA9023E2514400DCD162 /* s_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91223E2514000DCD162 /* s_sin.c */; }; A7D8BA9123E2514400DCD162 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A7D8BA9223E2514400DCD162 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A7D8BA9323E2514400DCD162 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A7D8BA9423E2514400DCD162 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A7D8BA9523E2514400DCD162 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; - A7D8BA9623E2514400DCD162 /* s_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91323E2514000DCD162 /* s_cos.c */; }; A7D8BA9723E2514400DCD162 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; - A7D8BA9823E2514400DCD162 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; - A7D8BA9923E2514400DCD162 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; - A7D8BA9A23E2514400DCD162 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; - A7D8BA9B23E2514400DCD162 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; - A7D8BA9C23E2514400DCD162 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A7D8BA9D23E2514400DCD162 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A7D8BA9E23E2514400DCD162 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A7D8BA9F23E2514400DCD162 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A7D8BAA123E2514400DCD162 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A7D8BAA223E2514400DCD162 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; A7D8BAA323E2514400DCD162 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A7D8BAA423E2514400DCD162 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A7D8BAA523E2514400DCD162 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A7D8BAA623E2514400DCD162 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A7D8BAA723E2514400DCD162 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A7D8BAA823E2514400DCD162 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; A7D8BAA923E2514400DCD162 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A7D8BAAA23E2514400DCD162 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A7D8BAAB23E2514400DCD162 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A7D8BAAC23E2514400DCD162 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A7D8BAAD23E2514400DCD162 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A7D8BAAE23E2514400DCD162 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; A7D8BAAF23E2514400DCD162 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A7D8BAB023E2514400DCD162 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A7D8BAB123E2514400DCD162 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A7D8BAB223E2514400DCD162 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A7D8BAB323E2514400DCD162 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; - A7D8BAB423E2514400DCD162 /* s_atan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91823E2514000DCD162 /* s_atan.c */; }; A7D8BAB523E2514400DCD162 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; - A7D8BAB623E2514400DCD162 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; - A7D8BAB723E2514400DCD162 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; - A7D8BAB823E2514400DCD162 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; - A7D8BAB923E2514400DCD162 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; - A7D8BABA23E2514400DCD162 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A7D8BABB23E2514400DCD162 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A7D8BABC23E2514400DCD162 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A7D8BABD23E2514400DCD162 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A7D8BABE23E2514400DCD162 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A7D8BABF23E2514400DCD162 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; - A7D8BAC023E2514500DCD162 /* s_scalbn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91A23E2514000DCD162 /* s_scalbn.c */; }; A7D8BAC123E2514500DCD162 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A7D8BAC223E2514500DCD162 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A7D8BAC323E2514500DCD162 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A7D8BAC423E2514500DCD162 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A7D8BAC523E2514500DCD162 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; - A7D8BAC623E2514500DCD162 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; A7D8BAC723E2514500DCD162 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A7D8BAC823E2514500DCD162 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A7D8BAC923E2514500DCD162 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A7D8BACA23E2514500DCD162 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A7D8BACB23E2514500DCD162 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; - A7D8BACC23E2514500DCD162 /* e_pow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91C23E2514000DCD162 /* e_pow.c */; }; A7D8BACD23E2514500DCD162 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A7D8BACE23E2514500DCD162 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A7D8BACF23E2514500DCD162 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A7D8BAD023E2514500DCD162 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A7D8BAD123E2514500DCD162 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; - A7D8BAD223E2514500DCD162 /* e_atan2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91D23E2514000DCD162 /* e_atan2.c */; }; A7D8BAD323E2514500DCD162 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - A7D8BAD423E2514500DCD162 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - A7D8BAD523E2514500DCD162 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - A7D8BAD623E2514500DCD162 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - A7D8BAD723E2514500DCD162 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; - A7D8BAD823E2514500DCD162 /* s_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91E23E2514000DCD162 /* s_tan.c */; }; A7D8BAD923E2514500DCD162 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; - A7D8BADA23E2514500DCD162 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; - A7D8BADB23E2514500DCD162 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; - A7D8BADC23E2514500DCD162 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; - A7D8BADD23E2514500DCD162 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; - A7D8BADE23E2514500DCD162 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A7D8BADF23E2514500DCD162 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A7D8BAE023E2514500DCD162 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A7D8BAE123E2514500DCD162 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A7D8BAE223E2514500DCD162 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A7D8BAE323E2514500DCD162 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; - A7D8BAE423E2514500DCD162 /* e_fmod.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92023E2514000DCD162 /* e_fmod.c */; }; A7D8BAE523E2514500DCD162 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A7D8BAE623E2514500DCD162 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A7D8BAE723E2514500DCD162 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A7D8BAE823E2514500DCD162 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A7D8BAE923E2514500DCD162 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; - A7D8BAEA23E2514500DCD162 /* e_exp.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92123E2514000DCD162 /* e_exp.c */; }; A7D8BAEB23E2514500DCD162 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A7D8BAEC23E2514500DCD162 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A7D8BAED23E2514500DCD162 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A7D8BAEE23E2514500DCD162 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A7D8BAEF23E2514500DCD162 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; - A7D8BAF023E2514500DCD162 /* e_log10.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92223E2514000DCD162 /* e_log10.c */; }; A7D8BAF123E2514500DCD162 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A7D8BAF223E2514500DCD162 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A7D8BAF323E2514500DCD162 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A7D8BAF423E2514500DCD162 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A7D8BAF523E2514500DCD162 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; - A7D8BAF623E2514500DCD162 /* e_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92323E2514000DCD162 /* e_log.c */; }; A7D8BAF723E2514500DCD162 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; - A7D8BAF823E2514500DCD162 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; - A7D8BAF923E2514500DCD162 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; - A7D8BAFA23E2514500DCD162 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; - A7D8BAFB23E2514500DCD162 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; - A7D8BAFC23E2514500DCD162 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A7D8BAFD23E2514500DCD162 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A7D8BAFE23E2514500DCD162 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A7D8BAFF23E2514500DCD162 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A7D8BB0023E2514500DCD162 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A7D8BB0123E2514500DCD162 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; - A7D8BB0223E2514500DCD162 /* s_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92523E2514000DCD162 /* s_floor.c */; }; A7D8BB0323E2514500DCD162 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; - A7D8BB0423E2514500DCD162 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; - A7D8BB0523E2514500DCD162 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; - A7D8BB0623E2514500DCD162 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; - A7D8BB0723E2514500DCD162 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; - A7D8BB0823E2514500DCD162 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; A7D8BB0923E2514500DCD162 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A7D8BB0A23E2514500DCD162 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A7D8BB0B23E2514500DCD162 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A7D8BB0C23E2514500DCD162 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A7D8BB0D23E2514500DCD162 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A7D8BB0E23E2514500DCD162 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; A7D8BB0F23E2514500DCD162 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; - A7D8BB1023E2514500DCD162 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; - A7D8BB1123E2514500DCD162 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; - A7D8BB1223E2514500DCD162 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; - A7D8BB1323E2514500DCD162 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; - A7D8BB1423E2514500DCD162 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A7D8BB1523E2514500DCD162 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; - A7D8BB1623E2514500DCD162 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; - A7D8BB1723E2514500DCD162 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; - A7D8BB1823E2514500DCD162 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; - A7D8BB1923E2514500DCD162 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; - A7D8BB1A23E2514500DCD162 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A7D8BB1B23E2514500DCD162 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A7D8BB1C23E2514500DCD162 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A7D8BB1D23E2514500DCD162 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A7D8BB1E23E2514500DCD162 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A7D8BB1F23E2514500DCD162 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; - A7D8BB2023E2514500DCD162 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; A7D8BB2123E2514500DCD162 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A7D8BB2223E2514500DCD162 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A7D8BB2323E2514500DCD162 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A7D8BB2423E2514500DCD162 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A7D8BB2523E2514500DCD162 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; - A7D8BB2623E2514500DCD162 /* scancodes_windows.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92C23E2514000DCD162 /* scancodes_windows.h */; }; A7D8BB2723E2514500DCD162 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A7D8BB2823E2514500DCD162 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A7D8BB2923E2514500DCD162 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A7D8BB2A23E2514500DCD162 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A7D8BB2B23E2514500DCD162 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A7D8BB2C23E2514500DCD162 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; A7D8BB2D23E2514500DCD162 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; - A7D8BB2E23E2514500DCD162 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; - A7D8BB2F23E2514500DCD162 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; - A7D8BB3023E2514500DCD162 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; - A7D8BB3123E2514500DCD162 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; - A7D8BB3223E2514500DCD162 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; A7D8BB3323E2514500DCD162 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; - A7D8BB3423E2514500DCD162 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; - A7D8BB3523E2514500DCD162 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; - A7D8BB3623E2514500DCD162 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; - A7D8BB3723E2514500DCD162 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; - A7D8BB3823E2514500DCD162 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; A7D8BB3F23E2514500DCD162 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A7D8BB4023E2514500DCD162 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A7D8BB4123E2514500DCD162 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A7D8BB4223E2514500DCD162 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A7D8BB4323E2514500DCD162 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; - A7D8BB4423E2514500DCD162 /* SDL_displayevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93123E2514000DCD162 /* SDL_displayevents_c.h */; }; A7D8BB4523E2514500DCD162 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; - A7D8BB4623E2514500DCD162 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; - A7D8BB4723E2514500DCD162 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; - A7D8BB4823E2514500DCD162 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; - A7D8BB4923E2514500DCD162 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; - A7D8BB4A23E2514500DCD162 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; A7D8BB4B23E2514500DCD162 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; - A7D8BB4C23E2514500DCD162 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; - A7D8BB4D23E2514500DCD162 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; - A7D8BB4E23E2514500DCD162 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; - A7D8BB4F23E2514500DCD162 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; - A7D8BB5023E2514500DCD162 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; A7D8BB5123E2514500DCD162 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; - A7D8BB5223E2514500DCD162 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; - A7D8BB5323E2514500DCD162 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; - A7D8BB5423E2514500DCD162 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; - A7D8BB5523E2514500DCD162 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; - A7D8BB5623E2514500DCD162 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A7D8BB5723E2514500DCD162 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; - A7D8BB5823E2514500DCD162 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; - A7D8BB5923E2514500DCD162 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; - A7D8BB5A23E2514500DCD162 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; - A7D8BB5B23E2514500DCD162 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; - A7D8BB5C23E2514500DCD162 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A7D8BB5D23E2514500DCD162 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A7D8BB5E23E2514500DCD162 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A7D8BB5F23E2514500DCD162 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A7D8BB6123E2514500DCD162 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; A7D8BB6323E2514500DCD162 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A7D8BB6423E2514500DCD162 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A7D8BB6523E2514500DCD162 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A7D8BB6723E2514500DCD162 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; - A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A7D8BB6923E2514500DCD162 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; - A7D8BB6A23E2514500DCD162 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; - A7D8BB6B23E2514500DCD162 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; - A7D8BB6C23E2514500DCD162 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; - A7D8BB6D23E2514500DCD162 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; - A7D8BB6E23E2514500DCD162 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A7D8BB6F23E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A7D8BB7023E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A7D8BB7123E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A7D8BB7223E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A7D8BB7323E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A7D8BB7423E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; A7D8BB7523E2514500DCD162 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A7D8BB7623E2514500DCD162 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A7D8BB7723E2514500DCD162 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A7D8BB7823E2514500DCD162 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A7D8BB7A23E2514500DCD162 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; A7D8BB7B23E2514500DCD162 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A7D8BB7C23E2514500DCD162 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A7D8BB7D23E2514500DCD162 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A7D8BB7E23E2514500DCD162 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A7D8BB7F23E2514500DCD162 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; - A7D8BB8023E2514500DCD162 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93B23E2514000DCD162 /* SDL_dropevents.c */; }; A7D8BB8123E2514500DCD162 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A7D8BB8223E2514500DCD162 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A7D8BB8323E2514500DCD162 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A7D8BB8423E2514500DCD162 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A7D8BB8523E2514500DCD162 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; - A7D8BB8623E2514500DCD162 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93C23E2514000DCD162 /* SDL_quit.c */; }; A7D8BB8723E2514500DCD162 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A7D8BB8823E2514500DCD162 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A7D8BB8923E2514500DCD162 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A7D8BB8A23E2514500DCD162 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A7D8BB8B23E2514500DCD162 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A7D8BB8C23E2514500DCD162 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; A7D8BB8D23E2514500DCD162 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A7D8BB8E23E2514500DCD162 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A7D8BB8F23E2514500DCD162 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - 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 */; }; A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; - A7D8BBA023E2514500DCD162 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; - A7D8BBA123E2514500DCD162 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; - A7D8BBA223E2514500DCD162 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; - A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; - A7D8BBA423E2514500DCD162 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A7D8BBA523E2514500DCD162 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; - A7D8BBA623E2514500DCD162 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; - A7D8BBA723E2514500DCD162 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; - A7D8BBA823E2514500DCD162 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; - A7D8BBA923E2514500DCD162 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; - A7D8BBAA23E2514500DCD162 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; A7D8BBAB23E2514500DCD162 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A7D8BBAC23E2514500DCD162 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A7D8BBAD23E2514500DCD162 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A7D8BBAE23E2514500DCD162 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A7D8BBAF23E2514500DCD162 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; - A7D8BBB223E2514500DCD162 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; - A7D8BBB323E2514500DCD162 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; - 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 */; }; - 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 */; }; @@ -2948,498 +368,112 @@ 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 */; }; - A7D8BBF023E2574800DCD162 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; - A7D8BBF123E2574800DCD162 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; - A7D8BBF223E2574800DCD162 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; - A7D8BBF323E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A7D8BBF423E2574800DCD162 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; - A7D8BBF523E2574800DCD162 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A7D8BBF623E2574800DCD162 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; - A7D8BBF723E2574800DCD162 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; - A7D8BBF823E2574800DCD162 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62C23E2513D00DCD162 /* SDL_uikitmodes.m */; }; - A7D8BBF923E2574800DCD162 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A7D8BBFA23E2574800DCD162 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A7D8BBFB23E2574800DCD162 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; - A7D8BBFC23E2574800DCD162 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62023E2513D00DCD162 /* SDL_uikitopenglview.m */; }; - A7D8BBFD23E2574800DCD162 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; - A7D8BBFE23E2574800DCD162 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63223E2513D00DCD162 /* SDL_uikitvideo.m */; }; - A7D8BBFF23E2574800DCD162 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A7D8BC0023E2574800DCD162 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; - A7D8BC0123E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; - A7D8BC0223E2574800DCD162 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63023E2513D00DCD162 /* SDL_uikitviewcontroller.m */; }; - A7D8BC0323E2574800DCD162 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A7D8BC0523E2574800DCD162 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; - A7D8BC0623E2574800DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; - DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; }; - 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 */; }; 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 */; }; - 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 */; }; - 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 */; }; F36C7AD1294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD2294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD3294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD5294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD6294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD7294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD8294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7AD9294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - F36C7ADA294BA009004D61C3 /* SDL_runapp.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C7AD0294BA009004D61C3 /* SDL_runapp.c */; }; - 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 */; }; - 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 */; }; - 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, ); }; }; 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 */; }; + F3990DF52A787C10000D8759 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3990E042A788303000D8759 /* SDL_hidapi_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3990E012A788303000D8759 /* SDL_hidapi_c.h */; }; + F3990E052A788303000D8759 /* SDL_hidapi_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = F3990E022A788303000D8759 /* SDL_hidapi_mac.h */; }; + F3990E062A788303000D8759 /* SDL_hidapi_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = F3990E032A788303000D8759 /* SDL_hidapi_ios.h */; }; + F3990E072A78833C000D8759 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; 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 */; }; F3B38CCF296E2E52005DA6D3 /* SDL_main_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCA296E2E52005DA6D3 /* SDL_main_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CD0296E2E52005DA6D3 /* SDL_main_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCA296E2E52005DA6D3 /* SDL_main_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CD1296E2E52005DA6D3 /* SDL_main_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCA296E2E52005DA6D3 /* SDL_main_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3B38CD3296E2E52005DA6D3 /* SDL_platform_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCB296E2E52005DA6D3 /* SDL_platform_defines.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CD4296E2E52005DA6D3 /* SDL_platform_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCB296E2E52005DA6D3 /* SDL_platform_defines.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CD5296E2E52005DA6D3 /* SDL_platform_defines.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCB296E2E52005DA6D3 /* SDL_platform_defines.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3B38CD7296E2E52005DA6D3 /* SDL_init.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCC296E2E52005DA6D3 /* SDL_init.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CD8296E2E52005DA6D3 /* SDL_init.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCC296E2E52005DA6D3 /* SDL_init.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CD9296E2E52005DA6D3 /* SDL_init.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCC296E2E52005DA6D3 /* SDL_init.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3B38CDB296E2E52005DA6D3 /* SDL_oldnames.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCD296E2E52005DA6D3 /* SDL_oldnames.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CDC296E2E52005DA6D3 /* SDL_oldnames.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCD296E2E52005DA6D3 /* SDL_oldnames.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CDD296E2E52005DA6D3 /* SDL_oldnames.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCD296E2E52005DA6D3 /* SDL_oldnames.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3B38CDF296E2E52005DA6D3 /* SDL_intrin.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCE296E2E52005DA6D3 /* SDL_intrin.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CE0296E2E52005DA6D3 /* SDL_intrin.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCE296E2E52005DA6D3 /* SDL_intrin.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3B38CE1296E2E52005DA6D3 /* SDL_intrin.h in Headers */ = {isa = PBXBuildFile; fileRef = F3B38CCE296E2E52005DA6D3 /* SDL_intrin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; F3F7D8ED2933074E00816151 /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AA2933074900816151 /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8EE2933074E00816151 /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AA2933074900816151 /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8EF2933074E00816151 /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AA2933074900816151 /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D8F12933074E00816151 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AB2933074900816151 /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8F22933074E00816151 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AB2933074900816151 /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8F32933074E00816151 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AB2933074900816151 /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D8F52933074E00816151 /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AC2933074900816151 /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8F62933074E00816151 /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AC2933074900816151 /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8F72933074E00816151 /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AC2933074900816151 /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D8F92933074E00816151 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AD2933074900816151 /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8FA2933074E00816151 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AD2933074900816151 /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8FB2933074E00816151 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AD2933074900816151 /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D8FD2933074E00816151 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AE2933074900816151 /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8FE2933074E00816151 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AE2933074900816151 /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D8FF2933074E00816151 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AE2933074900816151 /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9012933074E00816151 /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AF2933074900816151 /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9022933074E00816151 /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AF2933074900816151 /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9032933074E00816151 /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8AF2933074900816151 /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9052933074E00816151 /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B02933074900816151 /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9062933074E00816151 /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B02933074900816151 /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9072933074E00816151 /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B02933074900816151 /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9092933074E00816151 /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B12933074900816151 /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D90A2933074E00816151 /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B12933074900816151 /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D90B2933074E00816151 /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B12933074900816151 /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D90D2933074E00816151 /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B22933074900816151 /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D90E2933074E00816151 /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B22933074900816151 /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D90F2933074E00816151 /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B22933074900816151 /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9112933074E00816151 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B32933074900816151 /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9122933074E00816151 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B32933074900816151 /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9132933074E00816151 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B32933074900816151 /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9152933074E00816151 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B42933074900816151 /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9162933074E00816151 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B42933074900816151 /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9172933074E00816151 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B42933074900816151 /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9192933074E00816151 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B52933074A00816151 /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D91A2933074E00816151 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B52933074A00816151 /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D91B2933074E00816151 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B52933074A00816151 /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D91D2933074E00816151 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B62933074A00816151 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D91E2933074E00816151 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B62933074A00816151 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D91F2933074E00816151 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B62933074A00816151 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9212933074E00816151 /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B72933074A00816151 /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9222933074E00816151 /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B72933074A00816151 /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9232933074E00816151 /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B72933074A00816151 /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9252933074E00816151 /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B82933074A00816151 /* SDL_egl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9262933074E00816151 /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B82933074A00816151 /* SDL_egl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9272933074E00816151 /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B82933074A00816151 /* SDL_egl.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9292933074E00816151 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B92933074A00816151 /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D92A2933074E00816151 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B92933074A00816151 /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D92B2933074E00816151 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8B92933074A00816151 /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D92D2933074E00816151 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BA2933074A00816151 /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D92E2933074E00816151 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BA2933074A00816151 /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D92F2933074E00816151 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BA2933074A00816151 /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9312933074E00816151 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BB2933074A00816151 /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9322933074E00816151 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BB2933074A00816151 /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9332933074E00816151 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BB2933074A00816151 /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9352933074E00816151 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BC2933074A00816151 /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9362933074E00816151 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BC2933074A00816151 /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9372933074E00816151 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BC2933074A00816151 /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9392933074E00816151 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BD2933074A00816151 /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D93A2933074E00816151 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BD2933074A00816151 /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D93B2933074E00816151 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BD2933074A00816151 /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D93D2933074E00816151 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BE2933074A00816151 /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D93E2933074E00816151 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BE2933074A00816151 /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D93F2933074E00816151 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BE2933074A00816151 /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9412933074E00816151 /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BF2933074A00816151 /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9422933074E00816151 /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BF2933074A00816151 /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9432933074E00816151 /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8BF2933074A00816151 /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9452933074E00816151 /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C02933074A00816151 /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9462933074E00816151 /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C02933074A00816151 /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9472933074E00816151 /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C02933074A00816151 /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9492933074E00816151 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C12933074B00816151 /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D94A2933074E00816151 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C12933074B00816151 /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D94B2933074E00816151 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C12933074B00816151 /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D94D2933074E00816151 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C22933074B00816151 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D94E2933074E00816151 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C22933074B00816151 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D94F2933074E00816151 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C22933074B00816151 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9512933074E00816151 /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C32933074B00816151 /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9522933074E00816151 /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C32933074B00816151 /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9532933074E00816151 /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C32933074B00816151 /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9552933074E00816151 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C42933074B00816151 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9562933074E00816151 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C42933074B00816151 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9572933074E00816151 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C42933074B00816151 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9592933074E00816151 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C52933074B00816151 /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D95A2933074E00816151 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C52933074B00816151 /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D95B2933074E00816151 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C52933074B00816151 /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D95D2933074E00816151 /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C62933074B00816151 /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D95E2933074E00816151 /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C62933074B00816151 /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D95F2933074E00816151 /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C62933074B00816151 /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9612933074E00816151 /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C72933074B00816151 /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9622933074E00816151 /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C72933074B00816151 /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9632933074E00816151 /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C72933074B00816151 /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9652933074E00816151 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C82933074B00816151 /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9662933074E00816151 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C82933074B00816151 /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9672933074E00816151 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C82933074B00816151 /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9692933074E00816151 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C92933074B00816151 /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D96A2933074E00816151 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C92933074B00816151 /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D96B2933074E00816151 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8C92933074B00816151 /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D96D2933074E00816151 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CA2933074B00816151 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D96E2933074E00816151 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CA2933074B00816151 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D96F2933074E00816151 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CA2933074B00816151 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9712933074E00816151 /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CB2933074B00816151 /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9722933074E00816151 /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CB2933074B00816151 /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9732933074E00816151 /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CB2933074B00816151 /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9752933074E00816151 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CC2933074B00816151 /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9762933074E00816151 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CC2933074B00816151 /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9772933074E00816151 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CC2933074B00816151 /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9792933074E00816151 /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CD2933074C00816151 /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D97A2933074E00816151 /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CD2933074C00816151 /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D97B2933074E00816151 /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CD2933074C00816151 /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D97D2933074E00816151 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CE2933074C00816151 /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D97E2933074E00816151 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CE2933074C00816151 /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D97F2933074E00816151 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CE2933074C00816151 /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9812933074E00816151 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CF2933074C00816151 /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9822933074E00816151 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CF2933074C00816151 /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9832933074E00816151 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8CF2933074C00816151 /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9852933074E00816151 /* SDL_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D02933074C00816151 /* SDL_gamepad.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9862933074E00816151 /* SDL_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D02933074C00816151 /* SDL_gamepad.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9872933074E00816151 /* SDL_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D02933074C00816151 /* SDL_gamepad.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9892933074E00816151 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D12933074C00816151 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D98A2933074E00816151 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D12933074C00816151 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D98B2933074E00816151 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D12933074C00816151 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D98D2933074E00816151 /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D22933074C00816151 /* SDL_metal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D98E2933074E00816151 /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D22933074C00816151 /* SDL_metal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D98F2933074E00816151 /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D22933074C00816151 /* SDL_metal.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9912933074E00816151 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D32933074C00816151 /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9922933074E00816151 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D32933074C00816151 /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9932933074E00816151 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D32933074C00816151 /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9952933074E00816151 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D42933074C00816151 /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9962933074E00816151 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D42933074C00816151 /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9972933074E00816151 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D42933074C00816151 /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9992933074E00816151 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D52933074C00816151 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D99A2933074E00816151 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D52933074C00816151 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D99B2933074E00816151 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D52933074C00816151 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D99D2933074E00816151 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D62933074C00816151 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D99E2933074E00816151 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D62933074C00816151 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D99F2933074E00816151 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D62933074C00816151 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9A12933074E00816151 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D72933074C00816151 /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9A22933074E00816151 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D72933074C00816151 /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9A32933074E00816151 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D72933074C00816151 /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9A52933074E00816151 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D82933074C00816151 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9A62933074E00816151 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D82933074C00816151 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9A72933074E00816151 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D82933074C00816151 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9A92933074E00816151 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D92933074C00816151 /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9AA2933074E00816151 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D92933074C00816151 /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9AB2933074E00816151 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8D92933074C00816151 /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9AD2933074E00816151 /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DA2933074D00816151 /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9AE2933074E00816151 /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DA2933074D00816151 /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9AF2933074E00816151 /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DA2933074D00816151 /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9B12933074E00816151 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DB2933074D00816151 /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9B22933074E00816151 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DB2933074D00816151 /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9B32933074E00816151 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DB2933074D00816151 /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9B92933074E00816151 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DD2933074D00816151 /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9BA2933074E00816151 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DD2933074D00816151 /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9BB2933074E00816151 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DD2933074D00816151 /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9BD2933074E00816151 /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DE2933074D00816151 /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9BE2933074E00816151 /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DE2933074D00816151 /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9BF2933074E00816151 /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DE2933074D00816151 /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9C12933074E00816151 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DF2933074D00816151 /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9C22933074E00816151 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DF2933074D00816151 /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9C32933074E00816151 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8DF2933074D00816151 /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9C52933074E00816151 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E02933074D00816151 /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9C62933074E00816151 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E02933074D00816151 /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9C72933074E00816151 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E02933074D00816151 /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9C92933074E00816151 /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E12933074D00816151 /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9CA2933074E00816151 /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E12933074D00816151 /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9CB2933074E00816151 /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E12933074D00816151 /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9CD2933074E00816151 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E22933074D00816151 /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9CE2933074E00816151 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E22933074D00816151 /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9CF2933074E00816151 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E22933074D00816151 /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9D12933074E00816151 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E32933074D00816151 /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9D22933074E00816151 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E32933074D00816151 /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9D32933074E00816151 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E32933074D00816151 /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9D52933074E00816151 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E42933074D00816151 /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9D62933074E00816151 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E42933074D00816151 /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9D72933074E00816151 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E42933074D00816151 /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9D92933074E00816151 /* SDL_close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E52933074D00816151 /* SDL_close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9DA2933074E00816151 /* SDL_close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E52933074D00816151 /* SDL_close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9DB2933074E00816151 /* SDL_close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E52933074D00816151 /* SDL_close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9DD2933074E00816151 /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E62933074E00816151 /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9DE2933074E00816151 /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E62933074E00816151 /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9DF2933074E00816151 /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E62933074E00816151 /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9E12933074E00816151 /* SDL_begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E72933074E00816151 /* SDL_begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9E22933074E00816151 /* SDL_begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E72933074E00816151 /* SDL_begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9E32933074E00816151 /* SDL_begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E72933074E00816151 /* SDL_begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3F7D9E52933074E00816151 /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E82933074E00816151 /* SDL_system.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9E62933074E00816151 /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E82933074E00816151 /* SDL_system.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3F7D9E72933074E00816151 /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F7D8E82933074E00816151 /* SDL_system.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 */; }; + FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; platformFilters = (ios, maccatalyst, macos, tvos, watchos, ); }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - F3B38CF3296F6C8D005DA6D3 /* PBXContainerItemProxy */ = { + F3676F5C2A7885130091160D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = F3B38CEC296F63B6005DA6D3; - remoteInfo = xcFramework; + remoteInfo = SDL.xcframework; }; /* End PBXContainerItemProxy section */ @@ -3454,26 +488,6 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - A75FDB9F23E4CAFA00529352 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDBA223E4CAFF00529352 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -3501,8 +515,6 @@ 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 /* libSDL3.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL3.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - A75FD06C23E25AC700529352 /* libSDL3.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL3.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 = ""; }; A75FDAB923E28A7A00529352 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; @@ -3519,10 +531,6 @@ A75FDBA723E4CB6F00529352 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; }; A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_rumble.h; sourceTree = ""; }; A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_rumble.c; sourceTree = ""; }; - A769B23D23E259AE00872273 /* libSDL3.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL3.a; sourceTree = BUILT_PRODUCTS_DIR; }; - A7D88B5423E2437C00DCD162 /* SDL3.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL3.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A7D88D1523E24BED00DCD162 /* SDL3.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL3.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A7D88E5423E24D3B00DCD162 /* libSDL3.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL3.a; sourceTree = BUILT_PRODUCTS_DIR; }; A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dataqueue.h; sourceTree = ""; }; A7D8A57123E2513D00DCD162 /* SDL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL.c; sourceTree = ""; }; A7D8A57323E2513D00DCD162 /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = ""; }; @@ -3591,7 +599,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 = ""; }; @@ -3832,9 +839,6 @@ A7D8A94423E2514000DCD162 /* SDL_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_assert.c; sourceTree = ""; }; BECDF66B0761BA81005FE872 /* Info-Framework.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-Framework.plist"; sourceTree = ""; }; BECDF66C0761BA81005FE872 /* SDL3.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL3.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BECDF6B30761BA81005FE872 /* libSDL3.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL3.a; sourceTree = BUILT_PRODUCTS_DIR; }; - BECDF6BE0761BA81005FE872 /* SDL3 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SDL3; sourceTree = BUILT_PRODUCTS_DIR; }; - DB31407717554B71006C0E22 /* libSDL3.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL3.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; E2D187D228A5673500D2B4F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 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 = ""; }; @@ -3872,6 +876,9 @@ 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 = ""; }; + F3990E012A788303000D8759 /* SDL_hidapi_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_c.h; sourceTree = ""; }; + F3990E022A788303000D8759 /* SDL_hidapi_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_mac.h; sourceTree = ""; }; + F3990E032A788303000D8759 /* SDL_hidapi_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_ios.h; 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 = ""; }; F3B38CCA296E2E52005DA6D3 /* SDL_main_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_main_impl.h; path = SDL3/SDL_main_impl.h; sourceTree = ""; }; @@ -3950,146 +957,22 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - A75FCEA423E25AB700529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FCEAE23E25AB700529352 /* AudioToolbox.framework in Frameworks */, - A75FDABA23E28A7A00529352 /* AVFoundation.framework in Frameworks */, - A75FCEA723E25AB700529352 /* CoreAudio.framework in Frameworks */, - 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 */, - F376F70E2559B6B800CFC0BC /* OpenGLES.framework in Frameworks */, - A75FCEA623E25AB700529352 /* QuartzCore.framework in Frameworks */, - F376F70F2559B6BF00CFC0BC /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FD05D23E25AC700529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 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; - }; - A769B22E23E259AE00872273 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88B4623E2437C00DCD162 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F376F6332559B33D00CFC0BC /* AudioToolbox.framework in Frameworks */, - F376F6402559B38A00CFC0BC /* AVFoundation.framework in Frameworks */, - A7D88B4C23E2437C00DCD162 /* CoreAudio.framework in Frameworks */, - F382339A2738ED5600F7F527 /* CoreBluetooth.framework in Frameworks */, - A7D88B4D23E2437C00DCD162 /* CoreFoundation.framework in Frameworks */, - F376F63F2559B37300CFC0BC /* CoreGraphics.framework in Frameworks */, - F37DC5F325350EBC0002E6F7 /* CoreHaptics.framework in Frameworks */, - F376F63E2559B35200CFC0BC /* CoreMotion.framework in Frameworks */, - A7D88B4E23E2437C00DCD162 /* CoreVideo.framework in Frameworks */, - F376F6322559B31D00CFC0BC /* GameController.framework in Frameworks */, - A7D88B5023E2437C00DCD162 /* IOKit.framework in Frameworks */, - A7D88B4723E2437C00DCD162 /* Metal.framework in Frameworks */, - F376F6192559B29300CFC0BC /* OpenGLES.framework in Frameworks */, - A7D88B4823E2437C00DCD162 /* QuartzCore.framework in Frameworks */, - F376F61B2559B2AF00CFC0BC /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88D0423E24BED00DCD162 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F376F6DB2559B5A000CFC0BC /* AVFoundation.framework in Frameworks */, - F376F6D92559B59600CFC0BC /* AudioToolbox.framework in Frameworks */, - A7D88D0723E24BED00DCD162 /* CoreAudio.framework in Frameworks */, - F382339C2738ED6600F7F527 /* CoreBluetooth.framework in Frameworks */, - A7D88D0823E24BED00DCD162 /* CoreFoundation.framework in Frameworks */, - F376F6F82559B5EC00CFC0BC /* CoreGraphics.framework in Frameworks */, - F37DC5F525350ECC0002E6F7 /* CoreHaptics.framework in Frameworks */, - A7D88D0B23E24BED00DCD162 /* CoreVideo.framework in Frameworks */, - F376F6DF2559B5BA00CFC0BC /* GameController.framework in Frameworks */, - A7D88D0E23E24BED00DCD162 /* Metal.framework in Frameworks */, - F376F6DD2559B5A900CFC0BC /* OpenGLES.framework in Frameworks */, - A7D88D1023E24BED00DCD162 /* QuartzCore.framework in Frameworks */, - F376F6EC2559B5DA00CFC0BC /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88E4523E24D3B00DCD162 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; BECDF6680761BA81005FE872 /* Frameworks */ = { 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 */, 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */, 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */, A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */, + 557D0CFA254586CA003913E3 /* CoreHaptics.framework in Frameworks */, 00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */, FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */, 00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */, + 557D0CFB254586D7003913E3 /* GameController.framework in Frameworks */, 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BECDF6B10761BA81005FE872 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DB31406B17554B71006C0E22 /* Frameworks */ = { - 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 */, - FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */, - DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */, - DB31407017554B71006C0E22 /* IOKit.framework in Frameworks */, - 56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */, - DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */, - DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */, - 562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */, + 564624381FF821DA0074AC87 /* Metal.framework in Frameworks */, + 564624361FF821C20074AC87 /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4174,16 +1057,7 @@ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( - BECDF6BE0761BA81005FE872 /* SDL3 */, - A7D88B5423E2437C00DCD162 /* SDL3.framework */, - A7D88D1523E24BED00DCD162 /* SDL3.framework */, BECDF66C0761BA81005FE872 /* SDL3.framework */, - A769B23D23E259AE00872273 /* libSDL3.a */, - A7D88E5423E24D3B00DCD162 /* libSDL3.a */, - BECDF6B30761BA81005FE872 /* libSDL3.a */, - A75FCEB323E25AB700529352 /* libSDL3.dylib */, - A75FD06C23E25AC700529352 /* libSDL3.dylib */, - DB31407717554B71006C0E22 /* libSDL3.dylib */, ); name = Products; sourceTree = ""; @@ -4540,7 +1414,6 @@ A7D8A61823E2513D00DCD162 /* uikit */ = { isa = PBXGroup; children = ( - A7D8A62823E2513D00DCD162 /* keyinfotable.h */, A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */, A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */, A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */, @@ -4868,14 +1741,17 @@ A7D8A80923E2513F00DCD162 /* hidapi */ = { isa = PBXGroup; children = ( + A75FDAA423E2790500529352 /* ios */, + A75FDB9123E4C8B800529352 /* mac */, A75FDBA423E4CB6F00529352 /* AUTHORS.txt */, + A75FDB5723E39E6100529352 /* hidapi.h */, A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */, A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */, A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */, A75FDBA723E4CB6F00529352 /* LICENSE.txt */, - A75FDB5723E39E6100529352 /* hidapi.h */, - A75FDB9123E4C8B800529352 /* mac */, - A75FDAA423E2790500529352 /* ios */, + F3990E012A788303000D8759 /* SDL_hidapi_c.h */, + F3990E032A788303000D8759 /* SDL_hidapi_ios.h */, + F3990E022A788303000D8759 /* SDL_hidapi_mac.h */, A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */, ); path = hidapi; @@ -5150,1130 +2026,6 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - A75FCCFC23E25AB700529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FCDAC23E25AB700529352 /* SDL_RLEaccel_c.h in Headers */, - A75FCD6223E25AB700529352 /* SDL_assert_c.h in Headers */, - A75FCD5623E25AB700529352 /* SDL_audio_c.h in Headers */, - A75FCD5523E25AB700529352 /* SDL_audiodev_c.h in Headers */, - A75FCD2C23E25AB700529352 /* SDL_blendfillrect.h in Headers */, - A75FCDCE23E25AB700529352 /* SDL_blendline.h in Headers */, - A75FCD8323E25AB700529352 /* SDL_blendpoint.h in Headers */, - A75FCD9423E25AB700529352 /* SDL_blit.h in Headers */, - A75FCDCD23E25AB700529352 /* SDL_blit_auto.h in Headers */, - A75FCDAB23E25AB700529352 /* SDL_blit_copy.h in Headers */, - A75FCD3D23E25AB700529352 /* SDL_blit_slow.h in Headers */, - A75FCD5123E25AB700529352 /* SDL_clipboardevents_c.h in Headers */, - A75FCDB323E25AB700529352 /* SDL_cocoaclipboard.h in Headers */, - A75FCDD223E25AB700529352 /* SDL_cocoaevents.h in Headers */, - A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */, - A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */, - A75FCD9223E25AB700529352 /* SDL_cocoametalview.h in Headers */, - A75FCDB423E25AB700529352 /* SDL_cocoamodes.h in Headers */, - A75FCD3B23E25AB700529352 /* SDL_cocoamouse.h in Headers */, - A75FCD6823E25AB700529352 /* SDL_cocoaopengl.h in Headers */, - A75FCD9323E25AB700529352 /* SDL_cocoaopengles.h in Headers */, - A75FCD7E23E25AB700529352 /* SDL_cocoashape.h in Headers */, - A75FCD4223E25AB700529352 /* SDL_cocoavideo.h in Headers */, - A75FCD8C23E25AB700529352 /* SDL_cocoavulkan.h in Headers */, - A75FCDE623E25AB700529352 /* SDL_cocoawindow.h in Headers */, - A75FCD6D23E25AB700529352 /* SDL_coreaudio.h in Headers */, - A75FCD0F23E25AB700529352 /* SDL_coremotionsensor.h in Headers */, - A75FCD1C23E25AB700529352 /* SDL_d3dmath.h in Headers */, - A75FCD1823E25AB700529352 /* SDL_dataqueue.h in Headers */, - A75FCD6323E25AB700529352 /* SDL_diskaudio.h in Headers */, - A75FCDB823E25AB700529352 /* SDL_displayevents_c.h in Headers */, - A75FCD6E23E25AB700529352 /* SDL_draw.h in Headers */, - A75FCD6F23E25AB700529352 /* SDL_drawline.h in Headers */, - A75FCD6523E25AB700529352 /* SDL_drawpoint.h in Headers */, - A75FCD1523E25AB700529352 /* SDL_dropevents_c.h in Headers */, - A75FCD2223E25AB700529352 /* SDL_dummyaudio.h in Headers */, - A75FCD5C23E25AB700529352 /* SDL_dummysensor.h in Headers */, - A75FCD6123E25AB700529352 /* SDL_dynapi.h in Headers */, - A75FCDE523E25AB700529352 /* SDL_dynapi_overrides.h in Headers */, - A75FCDD623E25AB700529352 /* SDL_dynapi_procs.h in Headers */, - A75FCD1F23E25AB700529352 /* SDL_egl_c.h in Headers */, - A75FCD1923E25AB700529352 /* SDL_error_c.h in Headers */, - A75FCD7923E25AB700529352 /* SDL_events_c.h in Headers */, - A75FCD8B23E25AB700529352 /* SDL_gamepad_db.h in Headers */, - A75FCDDB23E25AB700529352 /* SDL_gles2funcs.h in Headers */, - A75FCD0723E25AB700529352 /* SDL_glfuncs.h in Headers */, - A75FCD1623E25AB700529352 /* SDL_haptic_c.h in Headers */, - A75FDBCC23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A75FCD2E23E25AB700529352 /* SDL_hidapijoystick_c.h in Headers */, - A75FCD5423E25AB700529352 /* SDL_hints_c.h in Headers */, - A75FCDC323E25AB700529352 /* SDL_internal.h in Headers */, - F395C19A2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - A75FCD3223E25AB700529352 /* SDL_joystick_c.h in Headers */, - A75FCDC823E25AB700529352 /* SDL_keyboard_c.h in Headers */, - A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */, - F386F6EE2884663E001840AA /* SDL_log_c.h in Headers */, - F395C1C12569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - A75FCDCC23E25AB700529352 /* SDL_mouse_c.h in Headers */, - A75FCD8523E25AB700529352 /* SDL_nullevents_c.h in Headers */, - A75FCDD423E25AB700529352 /* SDL_nullframebuffer_c.h in Headers */, - A75FCDAA23E25AB700529352 /* SDL_nullvideo.h in Headers */, - A75FCD6B23E25AB700529352 /* SDL_offscreenevents_c.h in Headers */, - A75FCDB723E25AB700529352 /* SDL_offscreenframebuffer_c.h in Headers */, - F31A92D028D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A75FCD8423E25AB700529352 /* SDL_offscreenvideo.h in Headers */, - A75FCD0D23E25AB700529352 /* SDL_offscreenwindow.h in Headers */, - A75FCD3023E25AB700529352 /* SDL_pixels_c.h in Headers */, - A75FCD0923E25AB700529352 /* SDL_rect_c.h in Headers */, - A75FCDA723E25AB700529352 /* SDL_render_sw_c.h in Headers */, - A75FCD9823E25AB700529352 /* SDL_rotate.h in Headers */, - A75FCDBE23E25AB700529352 /* SDL_rwopsbundlesupport.h in Headers */, - A75FCD9623E25AB700529352 /* SDL_sensor_c.h in Headers */, - A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */, - A75FCD8023E25AB700529352 /* SDL_shaders_gles2.h in Headers */, - A75FCD0C23E25AB700529352 /* SDL_shaders_metal_ios.h in Headers */, - A75FCD0B23E25AB700529352 /* SDL_shaders_metal_macos.h in Headers */, - A75FCCFD23E25AB700529352 /* SDL_shaders_metal_tvos.h in Headers */, - A75FCD0623E25AB700529352 /* SDL_shape_internals.h in Headers */, - A75FCD8723E25AB700529352 /* SDL_steamcontroller.h in Headers */, - A75FCD3623E25AB700529352 /* SDL_sysaudio.h in Headers */, - A75FCDCF23E25AB700529352 /* SDL_syshaptic.h in Headers */, - A75FCD5323E25AB700529352 /* SDL_syshaptic_c.h in Headers */, - A75FCD8623E25AB700529352 /* SDL_sysjoystick.h in Headers */, - 5605721D2473688E00B46B66 /* SDL_syslocale.h in Headers */, - A75FCDBC23E25AB700529352 /* SDL_sysmutex_c.h in Headers */, - A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */, - A75FCDBF23E25AB700529352 /* SDL_syspower.h in Headers */, - A75FCD9723E25AB700529352 /* SDL_sysrender.h in Headers */, - A75FCD6023E25AB700529352 /* SDL_syssensor.h in Headers */, - A75FCDB023E25AB700529352 /* SDL_systhread.h in Headers */, - A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */, - 5616CA63252BB35F005D5928 /* SDL_sysurl.h in Headers */, - A75FCDE123E25AB700529352 /* SDL_sysvideo.h in Headers */, - A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */, - A75FCDBA23E25AB700529352 /* SDL_timer_c.h in Headers */, - A75FCD8A23E25AB700529352 /* SDL_touch_c.h in Headers */, - A1626A592617008D003F1973 /* SDL_triangle.h in Headers */, - A75FCD1223E25AB700529352 /* SDL_uikitappdelegate.h in Headers */, - A75FCDA023E25AB700529352 /* SDL_uikitclipboard.h in Headers */, - A75FCD4423E25AB700529352 /* SDL_uikitevents.h in Headers */, - A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */, - A75FCD0423E25AB700529352 /* SDL_uikitmetalview.h in Headers */, - A75FCD5723E25AB700529352 /* SDL_uikitmodes.h in Headers */, - A75FCD0123E25AB700529352 /* SDL_uikitopengles.h in Headers */, - A75FCDB523E25AB700529352 /* SDL_uikitopenglview.h in Headers */, - A75FCD3A23E25AB700529352 /* SDL_uikitvideo.h in Headers */, - A75FCD1023E25AB700529352 /* SDL_uikitview.h in Headers */, - A75FCD5B23E25AB700529352 /* SDL_uikitviewcontroller.h in Headers */, - A75FCD4B23E25AB700529352 /* SDL_uikitvulkan.h in Headers */, - A75FCDA223E25AB700529352 /* SDL_uikitwindow.h in Headers */, - F386F6F72884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA928A59BDD00B84553 /* SDL_vacopy.h in Headers */, - 75E0916A241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - A75FCDD023E25AB700529352 /* SDL_vulkan_internal.h in Headers */, - A75FCD6723E25AB700529352 /* SDL_wave.h in Headers */, - A75FCD4023E25AB700529352 /* SDL_windowevents_c.h in Headers */, - A75FCD7323E25AB700529352 /* SDL_yuv_c.h in Headers */, - A75FCD3E23E25AB700529352 /* SDL_yuv_sw_c.h in Headers */, - A75FCD3423E25AB700529352 /* blank_cursor.h in Headers */, - A75FCD9E23E25AB700529352 /* controller_type.h in Headers */, - A75FCDA623E25AB700529352 /* default_cursor.h in Headers */, - A75FCD5823E25AB700529352 /* egl.h in Headers */, - A75FCD7823E25AB700529352 /* eglext.h in Headers */, - A75FCDAD23E25AB700529352 /* eglplatform.h in Headers */, - A75FCDBB23E25AB700529352 /* gl2.h in Headers */, - A75FCD5023E25AB700529352 /* gl2ext.h in Headers */, - A75FCD8D23E25AB700529352 /* gl2platform.h in Headers */, - A75FDB5F23E39E6100529352 /* hidapi.h in Headers */, - A75FCD1323E25AB700529352 /* keyinfotable.h in Headers */, - A75FCD5923E25AB700529352 /* khrplatform.h in Headers */, - A75FCD3923E25AB700529352 /* math_libm.h in Headers */, - A75FCD7A23E25AB700529352 /* math_private.h in Headers */, - A75FCD9D23E25AB700529352 /* scancodes_darwin.h in Headers */, - A75FCD8823E25AB700529352 /* scancodes_linux.h in Headers */, - A75FCDBD23E25AB700529352 /* scancodes_windows.h in Headers */, - A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */, - A75FCDDA23E25AB700529352 /* usb_ids.h in Headers */, - A75FCDD323E25AB700529352 /* vk_icd.h in Headers */, - A75FCD8F23E25AB700529352 /* vk_layer.h in Headers */, - A75FCD9123E25AB700529352 /* vk_platform.h in Headers */, - A75FCD3323E25AB700529352 /* vk_sdk_platform.h in Headers */, - A75FCDC723E25AB700529352 /* vulkan.h in Headers */, - A75FCD4E23E25AB700529352 /* vulkan.hpp in Headers */, - A75FCD5D23E25AB700529352 /* vulkan_android.h in Headers */, - A75FCD5F23E25AB700529352 /* vulkan_core.h in Headers */, - A75FCDD723E25AB700529352 /* vulkan_fuchsia.h in Headers */, - A75FCDC223E25AB700529352 /* vulkan_ios.h in Headers */, - A75FCDC023E25AB700529352 /* vulkan_macos.h in Headers */, - A75FCDA423E25AB700529352 /* vulkan_mir.h in Headers */, - A75FCDA323E25AB700529352 /* vulkan_vi.h in Headers */, - A75FCD7C23E25AB700529352 /* vulkan_wayland.h in Headers */, - A75FCDB623E25AB700529352 /* vulkan_win32.h in Headers */, - A75FCDC123E25AB700529352 /* vulkan_xcb.h in Headers */, - A75FCDA123E25AB700529352 /* vulkan_xlib.h in Headers */, - A75FCD9523E25AB700529352 /* vulkan_xlib_xrandr.h in Headers */, - A75FCD2123E25AB700529352 /* yuv_rgb.h in Headers */, - A75FCD6923E25AB700529352 /* yuv_rgb_sse_func.h in Headers */, - A75FCD5E23E25AB700529352 /* yuv_rgb_std_func.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FCEB523E25AC700529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FCF6523E25AC700529352 /* SDL_RLEaccel_c.h in Headers */, - A75FCF1B23E25AC700529352 /* SDL_assert_c.h in Headers */, - A75FCF0F23E25AC700529352 /* SDL_audio_c.h in Headers */, - A75FCF0E23E25AC700529352 /* SDL_audiodev_c.h in Headers */, - A75FCEE523E25AC700529352 /* SDL_blendfillrect.h in Headers */, - A75FCF8723E25AC700529352 /* SDL_blendline.h in Headers */, - A75FCF3C23E25AC700529352 /* SDL_blendpoint.h in Headers */, - A75FCF4D23E25AC700529352 /* SDL_blit.h in Headers */, - A75FCF8623E25AC700529352 /* SDL_blit_auto.h in Headers */, - A75FCF6423E25AC700529352 /* SDL_blit_copy.h in Headers */, - A75FCEF623E25AC700529352 /* SDL_blit_slow.h in Headers */, - A75FCF0A23E25AC700529352 /* SDL_clipboardevents_c.h in Headers */, - A75FCF6C23E25AC700529352 /* SDL_cocoaclipboard.h in Headers */, - A75FCF8B23E25AC700529352 /* SDL_cocoaevents.h in Headers */, - A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */, - A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */, - A75FCF4B23E25AC700529352 /* SDL_cocoametalview.h in Headers */, - A75FCF6D23E25AC700529352 /* SDL_cocoamodes.h in Headers */, - A75FCEF423E25AC700529352 /* SDL_cocoamouse.h in Headers */, - A75FCF2123E25AC700529352 /* SDL_cocoaopengl.h in Headers */, - A75FCF4C23E25AC700529352 /* SDL_cocoaopengles.h in Headers */, - A75FCF3723E25AC700529352 /* SDL_cocoashape.h in Headers */, - A75FCEFB23E25AC700529352 /* SDL_cocoavideo.h in Headers */, - A75FCF4523E25AC700529352 /* SDL_cocoavulkan.h in Headers */, - A75FCF9F23E25AC700529352 /* SDL_cocoawindow.h in Headers */, - A75FCF2623E25AC700529352 /* SDL_coreaudio.h in Headers */, - A75FCEC823E25AC700529352 /* SDL_coremotionsensor.h in Headers */, - A75FCED523E25AC700529352 /* SDL_d3dmath.h in Headers */, - A75FCED123E25AC700529352 /* SDL_dataqueue.h in Headers */, - A75FCF1C23E25AC700529352 /* SDL_diskaudio.h in Headers */, - A75FCF7123E25AC700529352 /* SDL_displayevents_c.h in Headers */, - A75FCF2723E25AC700529352 /* SDL_draw.h in Headers */, - A75FCF2823E25AC700529352 /* SDL_drawline.h in Headers */, - A75FCF1E23E25AC700529352 /* SDL_drawpoint.h in Headers */, - A75FCECE23E25AC700529352 /* SDL_dropevents_c.h in Headers */, - A75FCEDB23E25AC700529352 /* SDL_dummyaudio.h in Headers */, - A75FCF1523E25AC700529352 /* SDL_dummysensor.h in Headers */, - A75FCF1A23E25AC700529352 /* SDL_dynapi.h in Headers */, - A75FCF9E23E25AC700529352 /* SDL_dynapi_overrides.h in Headers */, - A75FCF8F23E25AC700529352 /* SDL_dynapi_procs.h in Headers */, - A75FCED823E25AC700529352 /* SDL_egl_c.h in Headers */, - A75FCED223E25AC700529352 /* SDL_error_c.h in Headers */, - A75FCF3223E25AC700529352 /* SDL_events_c.h in Headers */, - A75FCF4423E25AC700529352 /* SDL_gamepad_db.h in Headers */, - A75FCF9423E25AC700529352 /* SDL_gles2funcs.h in Headers */, - A75FCEC023E25AC700529352 /* SDL_glfuncs.h in Headers */, - A75FCECF23E25AC700529352 /* SDL_haptic_c.h in Headers */, - A75FDBCD23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A75FCEE723E25AC700529352 /* SDL_hidapijoystick_c.h in Headers */, - A75FCF0D23E25AC700529352 /* SDL_hints_c.h in Headers */, - A75FCF7C23E25AC700529352 /* SDL_internal.h in Headers */, - F395C19B2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - A75FCEEB23E25AC700529352 /* SDL_joystick_c.h in Headers */, - A75FCF8123E25AC700529352 /* SDL_keyboard_c.h in Headers */, - A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */, - F386F6EF2884663E001840AA /* SDL_log_c.h in Headers */, - F395C1C22569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - A75FCF8523E25AC700529352 /* SDL_mouse_c.h in Headers */, - A75FCF3E23E25AC700529352 /* SDL_nullevents_c.h in Headers */, - A75FCF8D23E25AC700529352 /* SDL_nullframebuffer_c.h in Headers */, - A75FCF6323E25AC700529352 /* SDL_nullvideo.h in Headers */, - A75FCF2423E25AC700529352 /* SDL_offscreenevents_c.h in Headers */, - A75FCF7023E25AC700529352 /* SDL_offscreenframebuffer_c.h in Headers */, - F31A92D128D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A75FCF3D23E25AC700529352 /* SDL_offscreenvideo.h in Headers */, - A75FCEC623E25AC700529352 /* SDL_offscreenwindow.h in Headers */, - A75FCEE923E25AC700529352 /* SDL_pixels_c.h in Headers */, - A75FCEC223E25AC700529352 /* SDL_rect_c.h in Headers */, - A75FCF6023E25AC700529352 /* SDL_render_sw_c.h in Headers */, - A75FCF5123E25AC700529352 /* SDL_rotate.h in Headers */, - A75FCF7723E25AC700529352 /* SDL_rwopsbundlesupport.h in Headers */, - A75FCF4F23E25AC700529352 /* SDL_sensor_c.h in Headers */, - A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */, - A75FCF3923E25AC700529352 /* SDL_shaders_gles2.h in Headers */, - A75FCEC523E25AC700529352 /* SDL_shaders_metal_ios.h in Headers */, - A75FCEC423E25AC700529352 /* SDL_shaders_metal_macos.h in Headers */, - A75FCEB623E25AC700529352 /* SDL_shaders_metal_tvos.h in Headers */, - A75FCEBF23E25AC700529352 /* SDL_shape_internals.h in Headers */, - A75FCF4023E25AC700529352 /* SDL_steamcontroller.h in Headers */, - A75FCEEF23E25AC700529352 /* SDL_sysaudio.h in Headers */, - A75FCF8823E25AC700529352 /* SDL_syshaptic.h in Headers */, - A75FCF0C23E25AC700529352 /* SDL_syshaptic_c.h in Headers */, - A75FCF3F23E25AC700529352 /* SDL_sysjoystick.h in Headers */, - 5605721E2473688F00B46B66 /* SDL_syslocale.h in Headers */, - A75FCF7523E25AC700529352 /* SDL_sysmutex_c.h in Headers */, - A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */, - A75FCF7823E25AC700529352 /* SDL_syspower.h in Headers */, - A75FCF5023E25AC700529352 /* SDL_sysrender.h in Headers */, - A75FCF1923E25AC700529352 /* SDL_syssensor.h in Headers */, - A75FCF6923E25AC700529352 /* SDL_systhread.h in Headers */, - A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */, - 5616CA66252BB361005D5928 /* SDL_sysurl.h in Headers */, - A75FCF9A23E25AC700529352 /* SDL_sysvideo.h in Headers */, - A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */, - A75FCF7323E25AC700529352 /* SDL_timer_c.h in Headers */, - A75FCF4323E25AC700529352 /* SDL_touch_c.h in Headers */, - A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */, - A75FCECB23E25AC700529352 /* SDL_uikitappdelegate.h in Headers */, - A75FCF5923E25AC700529352 /* SDL_uikitclipboard.h in Headers */, - A75FCEFD23E25AC700529352 /* SDL_uikitevents.h in Headers */, - A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */, - A75FCEBD23E25AC700529352 /* SDL_uikitmetalview.h in Headers */, - A75FCF1023E25AC700529352 /* SDL_uikitmodes.h in Headers */, - A75FCEBA23E25AC700529352 /* SDL_uikitopengles.h in Headers */, - A75FCF6E23E25AC700529352 /* SDL_uikitopenglview.h in Headers */, - A75FCEF323E25AC700529352 /* SDL_uikitvideo.h in Headers */, - A75FCEC923E25AC700529352 /* SDL_uikitview.h in Headers */, - A75FCF1423E25AC700529352 /* SDL_uikitviewcontroller.h in Headers */, - A75FCF0423E25AC700529352 /* SDL_uikitvulkan.h in Headers */, - A75FCF5B23E25AC700529352 /* SDL_uikitwindow.h in Headers */, - F386F6F82884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FAA28A59BDD00B84553 /* SDL_vacopy.h in Headers */, - 75E0916B241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - A75FCF8923E25AC700529352 /* SDL_vulkan_internal.h in Headers */, - A75FCF2023E25AC700529352 /* SDL_wave.h in Headers */, - A75FCEF923E25AC700529352 /* SDL_windowevents_c.h in Headers */, - A75FCF2C23E25AC700529352 /* SDL_yuv_c.h in Headers */, - A75FCEF723E25AC700529352 /* SDL_yuv_sw_c.h in Headers */, - A75FCEED23E25AC700529352 /* blank_cursor.h in Headers */, - A75FCF5723E25AC700529352 /* controller_type.h in Headers */, - A75FCF5F23E25AC700529352 /* default_cursor.h in Headers */, - A75FCF1123E25AC700529352 /* egl.h in Headers */, - A75FCF3123E25AC700529352 /* eglext.h in Headers */, - A75FCF6623E25AC700529352 /* eglplatform.h in Headers */, - A75FCF7423E25AC700529352 /* gl2.h in Headers */, - A75FCF0923E25AC700529352 /* gl2ext.h in Headers */, - A75FCF4623E25AC700529352 /* gl2platform.h in Headers */, - A75FDB6023E39E6100529352 /* hidapi.h in Headers */, - A75FCECC23E25AC700529352 /* keyinfotable.h in Headers */, - A75FCF1223E25AC700529352 /* khrplatform.h in Headers */, - A75FCEF223E25AC700529352 /* math_libm.h in Headers */, - A75FCF3323E25AC700529352 /* math_private.h in Headers */, - A75FCF5623E25AC700529352 /* scancodes_darwin.h in Headers */, - A75FCF4123E25AC700529352 /* scancodes_linux.h in Headers */, - A75FCF7623E25AC700529352 /* scancodes_windows.h in Headers */, - A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */, - A75FCF9323E25AC700529352 /* usb_ids.h in Headers */, - A75FCF8C23E25AC700529352 /* vk_icd.h in Headers */, - A75FCF4823E25AC700529352 /* vk_layer.h in Headers */, - A75FCF4A23E25AC700529352 /* vk_platform.h in Headers */, - A75FCEEC23E25AC700529352 /* vk_sdk_platform.h in Headers */, - A75FCF8023E25AC700529352 /* vulkan.h in Headers */, - A75FCF0723E25AC700529352 /* vulkan.hpp in Headers */, - A75FCF1623E25AC700529352 /* vulkan_android.h in Headers */, - A75FCF1823E25AC700529352 /* vulkan_core.h in Headers */, - A75FCF9023E25AC700529352 /* vulkan_fuchsia.h in Headers */, - A75FCF7B23E25AC700529352 /* vulkan_ios.h in Headers */, - A75FCF7923E25AC700529352 /* vulkan_macos.h in Headers */, - A75FCF5D23E25AC700529352 /* vulkan_mir.h in Headers */, - A75FCF5C23E25AC700529352 /* vulkan_vi.h in Headers */, - A75FCF3523E25AC700529352 /* vulkan_wayland.h in Headers */, - A75FCF6F23E25AC700529352 /* vulkan_win32.h in Headers */, - A75FCF7A23E25AC700529352 /* vulkan_xcb.h in Headers */, - A75FCF5A23E25AC700529352 /* vulkan_xlib.h in Headers */, - A75FCF4E23E25AC700529352 /* vulkan_xlib_xrandr.h in Headers */, - A75FCEDA23E25AC700529352 /* yuv_rgb.h in Headers */, - A75FCF2223E25AC700529352 /* yuv_rgb_sse_func.h in Headers */, - A75FCF1723E25AC700529352 /* yuv_rgb_std_func.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A769B08323E259AE00872273 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A769B13423E259AE00872273 /* SDL_RLEaccel_c.h in Headers */, - A769B0EA23E259AE00872273 /* SDL_assert_c.h in Headers */, - A769B0DC23E259AE00872273 /* SDL_audio_c.h in Headers */, - A769B0DB23E259AE00872273 /* SDL_audiodev_c.h in Headers */, - A769B0B323E259AE00872273 /* SDL_blendfillrect.h in Headers */, - A769B15523E259AE00872273 /* SDL_blendline.h in Headers */, - A769B10A23E259AE00872273 /* SDL_blendpoint.h in Headers */, - A769B11C23E259AE00872273 /* SDL_blit.h in Headers */, - A769B15423E259AE00872273 /* SDL_blit_auto.h in Headers */, - A769B13323E259AE00872273 /* SDL_blit_copy.h in Headers */, - A769B0C323E259AE00872273 /* SDL_blit_slow.h in Headers */, - A769B0D723E259AE00872273 /* SDL_clipboardevents_c.h in Headers */, - A769B13B23E259AE00872273 /* SDL_cocoaclipboard.h in Headers */, - A769B15923E259AE00872273 /* SDL_cocoaevents.h in Headers */, - A769B0D023E259AE00872273 /* SDL_cocoakeyboard.h in Headers */, - A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */, - A769B11A23E259AE00872273 /* SDL_cocoametalview.h in Headers */, - A769B13C23E259AE00872273 /* SDL_cocoamodes.h in Headers */, - A769B0C123E259AE00872273 /* SDL_cocoamouse.h in Headers */, - A769B0F023E259AE00872273 /* SDL_cocoaopengl.h in Headers */, - A769B11B23E259AE00872273 /* SDL_cocoaopengles.h in Headers */, - A769B10523E259AE00872273 /* SDL_cocoashape.h in Headers */, - A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */, - A769B11223E259AE00872273 /* SDL_cocoavulkan.h in Headers */, - A769B16E23E259AE00872273 /* SDL_cocoawindow.h in Headers */, - A769B0F523E259AE00872273 /* SDL_coreaudio.h in Headers */, - A769B09623E259AE00872273 /* SDL_coremotionsensor.h in Headers */, - A769B0A323E259AE00872273 /* SDL_d3dmath.h in Headers */, - A769B09F23E259AE00872273 /* SDL_dataqueue.h in Headers */, - A769B0EB23E259AE00872273 /* SDL_diskaudio.h in Headers */, - A769B14023E259AE00872273 /* SDL_displayevents_c.h in Headers */, - A769B0F623E259AE00872273 /* SDL_draw.h in Headers */, - A769B0F723E259AE00872273 /* SDL_drawline.h in Headers */, - A769B0ED23E259AE00872273 /* SDL_drawpoint.h in Headers */, - A769B09C23E259AE00872273 /* SDL_dropevents_c.h in Headers */, - A769B0A923E259AE00872273 /* SDL_dummyaudio.h in Headers */, - A769B0E223E259AE00872273 /* SDL_dummysensor.h in Headers */, - A769B0E923E259AE00872273 /* SDL_dynapi.h in Headers */, - A769B16D23E259AE00872273 /* SDL_dynapi_overrides.h in Headers */, - A769B15D23E259AE00872273 /* SDL_dynapi_procs.h in Headers */, - A769B0A623E259AE00872273 /* SDL_egl_c.h in Headers */, - A769B0A023E259AE00872273 /* SDL_error_c.h in Headers */, - A769B10123E259AE00872273 /* SDL_events_c.h in Headers */, - A769B11123E259AE00872273 /* SDL_gamepad_db.h in Headers */, - A769B16323E259AE00872273 /* SDL_gles2funcs.h in Headers */, - A769B08E23E259AE00872273 /* SDL_glfuncs.h in Headers */, - A769B09D23E259AE00872273 /* SDL_haptic_c.h in Headers */, - A75FDBCA23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A769B0B523E259AE00872273 /* SDL_hidapijoystick_c.h in Headers */, - A769B0DA23E259AE00872273 /* SDL_hints_c.h in Headers */, - A769B14A23E259AE00872273 /* SDL_internal.h in Headers */, - F395C1982569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - A769B0B823E259AE00872273 /* SDL_joystick_c.h in Headers */, - A769B14F23E259AE00872273 /* SDL_keyboard_c.h in Headers */, - A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */, - F386F6EC2884663E001840AA /* SDL_log_c.h in Headers */, - F395C1BF2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - A769B15323E259AE00872273 /* SDL_mouse_c.h in Headers */, - A769B10C23E259AE00872273 /* SDL_nullevents_c.h in Headers */, - A769B15B23E259AE00872273 /* SDL_nullframebuffer_c.h in Headers */, - A769B13223E259AE00872273 /* SDL_nullvideo.h in Headers */, - A769B0F323E259AE00872273 /* SDL_offscreenevents_c.h in Headers */, - A769B13F23E259AE00872273 /* SDL_offscreenframebuffer_c.h in Headers */, - F31A92CE28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A769B10B23E259AE00872273 /* SDL_offscreenvideo.h in Headers */, - A769B09423E259AE00872273 /* SDL_offscreenwindow.h in Headers */, - A769B0B623E259AE00872273 /* SDL_pixels_c.h in Headers */, - A769B09023E259AE00872273 /* SDL_rect_c.h in Headers */, - A769B12F23E259AE00872273 /* SDL_render_sw_c.h in Headers */, - A769B12023E259AE00872273 /* SDL_rotate.h in Headers */, - A769B14523E259AE00872273 /* SDL_rwopsbundlesupport.h in Headers */, - A769B11E23E259AE00872273 /* SDL_sensor_c.h in Headers */, - A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */, - A769B10723E259AE00872273 /* SDL_shaders_gles2.h in Headers */, - A769B09323E259AE00872273 /* SDL_shaders_metal_ios.h in Headers */, - A769B09223E259AE00872273 /* SDL_shaders_metal_macos.h in Headers */, - A769B08423E259AE00872273 /* SDL_shaders_metal_tvos.h in Headers */, - A769B08D23E259AE00872273 /* SDL_shape_internals.h in Headers */, - A769B0E423E259AE00872273 /* SDL_steamcontroller.h in Headers */, - A769B0BC23E259AE00872273 /* SDL_sysaudio.h in Headers */, - A769B15623E259AE00872273 /* SDL_syshaptic.h in Headers */, - A769B0D923E259AE00872273 /* SDL_syshaptic_c.h in Headers */, - A769B10D23E259AE00872273 /* SDL_sysjoystick.h in Headers */, - 5605721C2473688D00B46B66 /* SDL_syslocale.h in Headers */, - A769B14323E259AE00872273 /* SDL_sysmutex_c.h in Headers */, - A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */, - A769B14623E259AE00872273 /* SDL_syspower.h in Headers */, - A769B11F23E259AE00872273 /* SDL_sysrender.h in Headers */, - A769B0E823E259AE00872273 /* SDL_syssensor.h in Headers */, - A769B13823E259AE00872273 /* SDL_systhread.h in Headers */, - A769B0CD23E259AE00872273 /* SDL_systhread_c.h in Headers */, - 5616CA5D252BB35E005D5928 /* SDL_sysurl.h in Headers */, - A769B16923E259AE00872273 /* SDL_sysvideo.h in Headers */, - A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */, - A769B14123E259AE00872273 /* SDL_timer_c.h in Headers */, - A769B11023E259AE00872273 /* SDL_touch_c.h in Headers */, - A1626A572617008D003F1973 /* SDL_triangle.h in Headers */, - A769B09923E259AE00872273 /* SDL_uikitappdelegate.h in Headers */, - A769B12823E259AE00872273 /* SDL_uikitclipboard.h in Headers */, - A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */, - A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */, - A769B08B23E259AE00872273 /* SDL_uikitmetalview.h in Headers */, - A769B0DD23E259AE00872273 /* SDL_uikitmodes.h in Headers */, - A769B08823E259AE00872273 /* SDL_uikitopengles.h in Headers */, - A769B13D23E259AE00872273 /* SDL_uikitopenglview.h in Headers */, - A769B0C023E259AE00872273 /* SDL_uikitvideo.h in Headers */, - A769B09723E259AE00872273 /* SDL_uikitview.h in Headers */, - A769B0E123E259AE00872273 /* SDL_uikitviewcontroller.h in Headers */, - A769B0D123E259AE00872273 /* SDL_uikitvulkan.h in Headers */, - A769B12A23E259AE00872273 /* SDL_uikitwindow.h in Headers */, - F386F6F52884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA728A59BDD00B84553 /* SDL_vacopy.h in Headers */, - 75E09168241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - A769B15723E259AE00872273 /* SDL_vulkan_internal.h in Headers */, - A769B0EF23E259AE00872273 /* SDL_wave.h in Headers */, - A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */, - A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */, - A769B0C423E259AE00872273 /* SDL_yuv_sw_c.h in Headers */, - A769B0BA23E259AE00872273 /* blank_cursor.h in Headers */, - A769B12623E259AE00872273 /* controller_type.h in Headers */, - A769B12E23E259AE00872273 /* default_cursor.h in Headers */, - A769B0DE23E259AE00872273 /* egl.h in Headers */, - A769B10023E259AE00872273 /* eglext.h in Headers */, - A769B13523E259AE00872273 /* eglplatform.h in Headers */, - A769B14223E259AE00872273 /* gl2.h in Headers */, - A769B0D623E259AE00872273 /* gl2ext.h in Headers */, - A769B11323E259AE00872273 /* gl2platform.h in Headers */, - A75FDB5D23E39E6100529352 /* hidapi.h in Headers */, - A769B09A23E259AE00872273 /* keyinfotable.h in Headers */, - A769B0DF23E259AE00872273 /* khrplatform.h in Headers */, - A769B0BF23E259AE00872273 /* math_libm.h in Headers */, - A769B10223E259AE00872273 /* math_private.h in Headers */, - A769B12523E259AE00872273 /* scancodes_darwin.h in Headers */, - A769B10E23E259AE00872273 /* scancodes_linux.h in Headers */, - A769B14423E259AE00872273 /* scancodes_windows.h in Headers */, - A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */, - A769B16123E259AE00872273 /* usb_ids.h in Headers */, - A769B15A23E259AE00872273 /* vk_icd.h in Headers */, - A769B11523E259AE00872273 /* vk_layer.h in Headers */, - A769B11823E259AE00872273 /* vk_platform.h in Headers */, - A769B0B923E259AE00872273 /* vk_sdk_platform.h in Headers */, - A769B14E23E259AE00872273 /* vulkan.h in Headers */, - A769B0D423E259AE00872273 /* vulkan.hpp in Headers */, - A769B0E523E259AE00872273 /* vulkan_android.h in Headers */, - A769B0E723E259AE00872273 /* vulkan_core.h in Headers */, - A769B15E23E259AE00872273 /* vulkan_fuchsia.h in Headers */, - A769B14923E259AE00872273 /* vulkan_ios.h in Headers */, - A769B14723E259AE00872273 /* vulkan_macos.h in Headers */, - A769B12C23E259AE00872273 /* vulkan_mir.h in Headers */, - A769B12B23E259AE00872273 /* vulkan_vi.h in Headers */, - A769B10323E259AE00872273 /* vulkan_wayland.h in Headers */, - A769B13E23E259AE00872273 /* vulkan_win32.h in Headers */, - A769B14823E259AE00872273 /* vulkan_xcb.h in Headers */, - A769B12923E259AE00872273 /* vulkan_xlib.h in Headers */, - A769B11D23E259AE00872273 /* vulkan_xlib_xrandr.h in Headers */, - A769B0A823E259AE00872273 /* yuv_rgb.h in Headers */, - A769B0F123E259AE00872273 /* yuv_rgb_sse_func.h in Headers */, - A769B0E623E259AE00872273 /* yuv_rgb_std_func.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88A1523E2437C00DCD162 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F3F7D9822933074E00816151 /* SDL.h in Headers */, - A7D8B39F23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - F3F7D9C62933074E00816151 /* SDL_assert.h in Headers */, - A7D8B61823E2514300DCD162 /* SDL_assert_c.h in Headers */, - F3F7D92A2933074E00816151 /* SDL_atomic.h in Headers */, - F3F7D8EE2933074E00816151 /* SDL_audio.h in Headers */, - A7D8B7A123E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B7B323E2514400DCD162 /* SDL_audiodev_c.h in Headers */, - F3F7D9E22933074E00816151 /* SDL_begin_code.h in Headers */, - F3F7D9A62933074E00816151 /* SDL_bits.h in Headers */, - A7D8BA0223E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B9EA23E2514400DCD162 /* SDL_blendline.h in Headers */, - F3F7D97E2933074E00816151 /* SDL_blendmode.h in Headers */, - A7D8BA0E23E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8B3B723E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8B2BB23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8ADED23E2514100DCD162 /* SDL_blit_slow.h in Headers */, - F3F7D9A22933074E00816151 /* SDL_clipboard.h in Headers */, - A7D8BB7023E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - F3F7D9DA2933074E00816151 /* SDL_close_code.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 */, - F3F7D9D22933074E00816151 /* SDL_copying.h in Headers */, - A7D8B8CD23E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8A97023E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - F3F7D9BA2933074E00816151 /* SDL_cpuinfo.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 */, - 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 */, - A7D8AB1123E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, - A7D8AB1D23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - F3F7D9262933074E00816151 /* SDL_egl.h in Headers */, - A7D8ABDA23E2514100DCD162 /* SDL_egl_c.h in Headers */, - F3F7D93E2933074E00816151 /* SDL_endian.h in Headers */, - F3F7D9362933074E00816151 /* SDL_error.h in Headers */, - A7D8A95E23E2514000DCD162 /* SDL_error_c.h in Headers */, - F3F7D9722933074E00816151 /* SDL_events.h in Headers */, - A7D8BBA623E2514500DCD162 /* SDL_events_c.h in Headers */, - F3F7D99E2933074E00816151 /* SDL_filesystem.h in Headers */, - F3F7D9862933074E00816151 /* SDL_gamepad.h in Headers */, - A7D8B4AD23E2514300DCD162 /* SDL_gamepad_db.h in Headers */, - A7D8BA5623E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8BA7A23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - F3F7D98A2933074E00816151 /* SDL_guid.h in Headers */, - F3F7D8FA2933074E00816151 /* SDL_haptic.h in Headers */, - A7D8AABD23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - F3F7D96E2933074E00816151 /* SDL_hidapi.h in Headers */, - A75FDBC623EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B55823E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - F3F7D9122933074E00816151 /* SDL_hints.h in Headers */, - A7D8B94B23E2514400DCD162 /* SDL_hints_c.h in Headers */, - F3B38CD8296E2E52005DA6D3 /* SDL_init.h in Headers */, - A7D8A99A23E2514000DCD162 /* SDL_internal.h in Headers */, - F3B38CE0296E2E52005DA6D3 /* SDL_intrin.h in Headers */, - F395C1942569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - F3F7D9922933074E00816151 /* SDL_joystick.h in Headers */, - A7D8B58823E2514300DCD162 /* SDL_joystick_c.h in Headers */, - F3F7D9522933074E00816151 /* SDL_keyboard.h in Headers */, - A7D8BB8823E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - F3F7D9762933074E00816151 /* SDL_keycode.h in Headers */, - A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */, - F3F7D9AA2933074E00816151 /* SDL_loadso.h in Headers */, - F3F7D9562933074E00816151 /* SDL_locale.h in Headers */, - F3F7D9222933074E00816151 /* SDL_log.h in Headers */, - F386F6E82884663E001840AA /* SDL_log_c.h in Headers */, - F3F7D9062933074E00816151 /* SDL_main.h in Headers */, - F3B38CD0296E2E52005DA6D3 /* SDL_main_impl.h in Headers */, - F3F7D91E2933074E00816151 /* SDL_messagebox.h in Headers */, - F3F7D98E2933074E00816151 /* SDL_metal.h in Headers */, - F395C1BB2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - F3F7D99A2933074E00816151 /* SDL_misc.h in Headers */, - F3F7D9AE2933074E00816151 /* SDL_mouse.h in Headers */, - A7D8BB1C23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - F3F7D9DE2933074E00816151 /* SDL_mutex.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 */, - F31A92C928D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A7D8AB6E23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, - A7D8AB8623E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - F3B38CDC296E2E52005DA6D3 /* SDL_oldnames.h in Headers */, - F3F7D9CA2933074E00816151 /* SDL_opengl.h in Headers */, - F3F7D9462933074E00816151 /* SDL_opengl_glext.h in Headers */, - F3F7D95E2933074E00816151 /* SDL_opengles.h in Headers */, - F3F7D9622933074E00816151 /* SDL_opengles2.h in Headers */, - F3F7D8FE2933074E00816151 /* SDL_opengles2_gl2.h in Headers */, - F3F7D93A2933074E00816151 /* SDL_opengles2_gl2ext.h in Headers */, - F3F7D96A2933074E00816151 /* SDL_opengles2_gl2platform.h in Headers */, - F3F7D90A2933074E00816151 /* SDL_opengles2_khrplatform.h in Headers */, - F3F7D91A2933074E00816151 /* SDL_pixels.h in Headers */, - A7D8B2C123E2514200DCD162 /* SDL_pixels_c.h in Headers */, - F3F7D8F22933074E00816151 /* SDL_platform.h in Headers */, - F3B38CD4296E2E52005DA6D3 /* SDL_platform_defines.h in Headers */, - F3F7D9B22933074E00816151 /* SDL_power.h in Headers */, - F3F7D9C22933074E00816151 /* SDL_quit.h in Headers */, - F3F7D9CE2933074E00816151 /* SDL_rect.h in Headers */, - A7D8AC0423E2514100DCD162 /* SDL_rect_c.h in Headers */, - F3F7D9BE2933074E00816151 /* SDL_render.h in Headers */, - A7D8B9FC23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - F3F7D9162933074E00816151 /* SDL_revision.h in Headers */, - A7D8BA3223E2514400DCD162 /* SDL_rotate.h in Headers */, - F3F7D9662933074E00816151 /* SDL_rwops.h in Headers */, - A7D8B5C423E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, - F3F7D94A2933074E00816151 /* SDL_scancode.h in Headers */, - F3F7D94E2933074E00816151 /* SDL_sensor.h in Headers */, - A7D8A98E23E2514000DCD162 /* SDL_sensor_c.h in Headers */, - A7D8BA7423E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8BA5023E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - A7D8B98D23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8B99C23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */, - A7D8B9A223E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - F3F7D92E2933074E00816151 /* SDL_shape.h in Headers */, - A7D8AC0A23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - F3F7D8F62933074E00816151 /* SDL_stdinc.h in Headers */, - A7D8B4C523E2514300DCD162 /* SDL_steamcontroller.h in Headers */, - F3F7D9322933074E00816151 /* SDL_surface.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 */, - A7D8A97C23E2514000DCD162 /* SDL_syssensor.h in Headers */, - F3F7D9E62933074E00816151 /* SDL_system.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 */, - F3F7D9422933074E00816151 /* SDL_syswm.h in Headers */, - F3F7D97A2933074E00816151 /* SDL_thread.h in Headers */, - A7D8B3ED23E2514300DCD162 /* SDL_thread_c.h in Headers */, - F3F7D90E2933074E00816151 /* SDL_timer.h in Headers */, - A7D8AB3223E2514100DCD162 /* SDL_timer_c.h in Headers */, - F3F7D9022933074E00816151 /* SDL_touch.h in Headers */, - A7D8BB6423E2514500DCD162 /* SDL_touch_c.h in Headers */, - A1626A532617008D003F1973 /* SDL_triangle.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 */, - F386F6F12884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA328A59BDD00B84553 /* SDL_vacopy.h in Headers */, - F3F7D9D62933074E00816151 /* SDL_version.h in Headers */, - F3F7D95A2933074E00816151 /* SDL_video.h in Headers */, - 75E09164241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - F3F7D9962933074E00816151 /* SDL_vulkan.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 */, - A7D8BB4623E2514500DCD162 /* blank_cursor.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 */, - A7D8ACA023E2514100DCD162 /* keyinfotable.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 */, - 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 */, - A7D8B26D23E2514200DCD162 /* vulkan.hpp 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 */, - A7D8B29723E2514200DCD162 /* vulkan_mir.h in Headers */, - A7D8B25B23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B27923E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B27F23E2514200DCD162 /* vulkan_win32.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; - }; - A7D88BCA23E24BED00DCD162 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F3F7D9832933074E00816151 /* SDL.h in Headers */, - A7D8B3A023E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - F3F7D9C72933074E00816151 /* SDL_assert.h in Headers */, - A7D8B61923E2514300DCD162 /* SDL_assert_c.h in Headers */, - F3F7D92B2933074E00816151 /* SDL_atomic.h in Headers */, - F3F7D8EF2933074E00816151 /* SDL_audio.h in Headers */, - A7D8B7A223E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B7B423E2514400DCD162 /* SDL_audiodev_c.h in Headers */, - F3F7D9E32933074E00816151 /* SDL_begin_code.h in Headers */, - F3F7D9A72933074E00816151 /* SDL_bits.h in Headers */, - A7D8BA0323E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B9EB23E2514400DCD162 /* SDL_blendline.h in Headers */, - F3F7D97F2933074E00816151 /* 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 */, - A7D8ADEE23E2514100DCD162 /* SDL_blit_slow.h in Headers */, - F3F7D9A32933074E00816151 /* SDL_clipboard.h in Headers */, - A7D8BB7123E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - F3F7D9DB2933074E00816151 /* SDL_close_code.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 */, - F3F7D9D32933074E00816151 /* SDL_copying.h in Headers */, - A7D8B8CE23E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8A97123E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - F3F7D9BB2933074E00816151 /* SDL_cpuinfo.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 */, - 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 */, - A7D8AB1223E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, - A7D8AB1E23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - F3F7D9272933074E00816151 /* SDL_egl.h in Headers */, - A7D8ABDB23E2514100DCD162 /* SDL_egl_c.h in Headers */, - F3F7D93F2933074E00816151 /* SDL_endian.h in Headers */, - F3F7D9372933074E00816151 /* SDL_error.h in Headers */, - A7D8A95F23E2514000DCD162 /* SDL_error_c.h in Headers */, - F3F7D9732933074E00816151 /* SDL_events.h in Headers */, - A7D8BBA723E2514500DCD162 /* SDL_events_c.h in Headers */, - F3F7D99F2933074E00816151 /* SDL_filesystem.h in Headers */, - F3F7D9872933074E00816151 /* SDL_gamepad.h in Headers */, - A7D8B4AE23E2514300DCD162 /* SDL_gamepad_db.h in Headers */, - A7D8BA5723E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8BA7B23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - F3F7D98B2933074E00816151 /* SDL_guid.h in Headers */, - F3F7D8FB2933074E00816151 /* SDL_haptic.h in Headers */, - A7D8AABE23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - F3F7D96F2933074E00816151 /* SDL_hidapi.h in Headers */, - A75FDBC723EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B55923E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - F3F7D9132933074E00816151 /* SDL_hints.h in Headers */, - A7D8B94C23E2514400DCD162 /* SDL_hints_c.h in Headers */, - F3B38CD9296E2E52005DA6D3 /* SDL_init.h in Headers */, - A7D8A99B23E2514000DCD162 /* SDL_internal.h in Headers */, - F3B38CE1296E2E52005DA6D3 /* SDL_intrin.h in Headers */, - F395C1952569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - F3F7D9932933074E00816151 /* SDL_joystick.h in Headers */, - A7D8B58923E2514300DCD162 /* SDL_joystick_c.h in Headers */, - F3F7D9532933074E00816151 /* SDL_keyboard.h in Headers */, - A7D8BB8923E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - F3F7D9772933074E00816151 /* SDL_keycode.h in Headers */, - A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */, - F3F7D9AB2933074E00816151 /* SDL_loadso.h in Headers */, - F3F7D9572933074E00816151 /* SDL_locale.h in Headers */, - F3F7D9232933074E00816151 /* SDL_log.h in Headers */, - F386F6E92884663E001840AA /* SDL_log_c.h in Headers */, - F3F7D9072933074E00816151 /* SDL_main.h in Headers */, - F3B38CD1296E2E52005DA6D3 /* SDL_main_impl.h in Headers */, - F3F7D91F2933074E00816151 /* SDL_messagebox.h in Headers */, - F3F7D98F2933074E00816151 /* SDL_metal.h in Headers */, - F395C1BC2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - F3F7D99B2933074E00816151 /* SDL_misc.h in Headers */, - F3F7D9AF2933074E00816151 /* SDL_mouse.h in Headers */, - A7D8BB1D23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - F3F7D9DF2933074E00816151 /* SDL_mutex.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 */, - F31A92CA28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A7D8AB6F23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, - A7D8AB8723E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - F3B38CDD296E2E52005DA6D3 /* SDL_oldnames.h in Headers */, - F3F7D9CB2933074E00816151 /* SDL_opengl.h in Headers */, - F3F7D9472933074E00816151 /* SDL_opengl_glext.h in Headers */, - F3F7D95F2933074E00816151 /* SDL_opengles.h in Headers */, - F3F7D9632933074E00816151 /* SDL_opengles2.h in Headers */, - F3F7D8FF2933074E00816151 /* SDL_opengles2_gl2.h in Headers */, - F3F7D93B2933074E00816151 /* SDL_opengles2_gl2ext.h in Headers */, - F3F7D96B2933074E00816151 /* SDL_opengles2_gl2platform.h in Headers */, - F3F7D90B2933074E00816151 /* SDL_opengles2_khrplatform.h in Headers */, - F3F7D91B2933074E00816151 /* SDL_pixels.h in Headers */, - A7D8B2C223E2514200DCD162 /* SDL_pixels_c.h in Headers */, - F3F7D8F32933074E00816151 /* SDL_platform.h in Headers */, - F3B38CD5296E2E52005DA6D3 /* SDL_platform_defines.h in Headers */, - F3F7D9B32933074E00816151 /* SDL_power.h in Headers */, - F3F7D9C32933074E00816151 /* SDL_quit.h in Headers */, - F3F7D9CF2933074E00816151 /* SDL_rect.h in Headers */, - A7D8AC0523E2514100DCD162 /* SDL_rect_c.h in Headers */, - F3F7D9BF2933074E00816151 /* SDL_render.h in Headers */, - A7D8B9FD23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - F3F7D9172933074E00816151 /* SDL_revision.h in Headers */, - A7D8BA3323E2514400DCD162 /* SDL_rotate.h in Headers */, - F3F7D9672933074E00816151 /* SDL_rwops.h in Headers */, - A7D8B5C523E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, - F3F7D94B2933074E00816151 /* SDL_scancode.h in Headers */, - F3F7D94F2933074E00816151 /* SDL_sensor.h in Headers */, - A7D8A98F23E2514000DCD162 /* SDL_sensor_c.h in Headers */, - A7D8BA7523E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8BA5123E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - A7D8B98E23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8B99D23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */, - A7D8B9A323E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - F3F7D92F2933074E00816151 /* SDL_shape.h in Headers */, - A7D8AC0B23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - F3F7D8F72933074E00816151 /* SDL_stdinc.h in Headers */, - A7D8B4C623E2514300DCD162 /* SDL_steamcontroller.h in Headers */, - F3F7D9332933074E00816151 /* SDL_surface.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 */, - A7D8A97D23E2514000DCD162 /* SDL_syssensor.h in Headers */, - F3F7D9E72933074E00816151 /* SDL_system.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 */, - F3F7D9432933074E00816151 /* SDL_syswm.h in Headers */, - F3F7D97B2933074E00816151 /* SDL_thread.h in Headers */, - A7D8B3EE23E2514300DCD162 /* SDL_thread_c.h in Headers */, - F3F7D90F2933074E00816151 /* SDL_timer.h in Headers */, - A7D8AB3323E2514100DCD162 /* SDL_timer_c.h in Headers */, - F3F7D9032933074E00816151 /* SDL_touch.h in Headers */, - A7D8BB6523E2514500DCD162 /* SDL_touch_c.h in Headers */, - A1626A542617008D003F1973 /* SDL_triangle.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 */, - F386F6F22884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA428A59BDD00B84553 /* SDL_vacopy.h in Headers */, - F3F7D9D72933074E00816151 /* SDL_version.h in Headers */, - F3F7D95B2933074E00816151 /* SDL_video.h in Headers */, - 75E09165241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - F3F7D9972933074E00816151 /* SDL_vulkan.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 */, - A7D8BB4723E2514500DCD162 /* blank_cursor.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 */, - A7D8ACA123E2514100DCD162 /* keyinfotable.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 */, - 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 */, - A7D8B26E23E2514200DCD162 /* vulkan.hpp 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 */, - A7D8B29823E2514200DCD162 /* vulkan_mir.h in Headers */, - A7D8B25C23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B27A23E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B28023E2514200DCD162 /* vulkan_win32.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; - }; - A7D88D1823E24D3B00DCD162 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A7D8B3A223E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - A7D8B61B23E2514300DCD162 /* SDL_assert_c.h in Headers */, - A7D8B7A423E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B7B623E2514400DCD162 /* SDL_audiodev_c.h in Headers */, - A7D8BA0523E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B9ED23E2514400DCD162 /* SDL_blendline.h in Headers */, - A7D8BA1123E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8B3BA23E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8B2BE23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8B39C23E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8ADF023E2514100DCD162 /* SDL_blit_slow.h in Headers */, - A7D8BB7323E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8AECE23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, - A7D8AF1623E2514100DCD162 /* SDL_cocoaevents.h in Headers */, - A7D8AE9223E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8AEB623E2514100DCD162 /* SDL_cocoametalview.h in Headers */, - A7D8AEF823E2514100DCD162 /* SDL_cocoamodes.h in Headers */, - A7D8AF2223E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AEE023E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, - A7D8AEF223E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, - A7D8AE8623E2514100DCD162 /* SDL_cocoashape.h in Headers */, - A7D8AF0423E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D8AEEC23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, - A7D8AEFE23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B8D023E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8A97323E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - A7D8B98423E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8A94923E2514000DCD162 /* SDL_dataqueue.h in Headers */, - A7D8B8A623E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D8BB4323E2514500DCD162 /* SDL_displayevents_c.h in Headers */, - A7D8BA1D23E2514400DCD162 /* SDL_draw.h in Headers */, - A7D8BA0B23E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D8B9F323E2514400DCD162 /* SDL_drawpoint.h in Headers */, - A7D8BB3123E2514500DCD162 /* SDL_dropevents_c.h in Headers */, - A7D8B79823E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8A96723E2514000DCD162 /* SDL_dummysensor.h in Headers */, - A7D8AB0E23E2514100DCD162 /* SDL_dynapi.h in Headers */, - A7D8AB1423E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, - A7D8AB2023E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - A7D8ABDD23E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D8A96123E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8BBA923E2514500DCD162 /* SDL_events_c.h in Headers */, - A7D8B4B023E2514300DCD162 /* SDL_gamepad_db.h in Headers */, - A7D8BA5923E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8BA7D23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D8AAC023E2514100DCD162 /* SDL_haptic_c.h in Headers */, - A75FDBC923EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B55B23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - A7D8B94E23E2514400DCD162 /* SDL_hints_c.h in Headers */, - A7D8A99D23E2514000DCD162 /* SDL_internal.h in Headers */, - F395C1972569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - A7D8B58B23E2514300DCD162 /* SDL_joystick_c.h in Headers */, - A7D8BB8B23E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */, - F386F6EB2884663E001840AA /* SDL_log_c.h in Headers */, - F395C1BE2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - A7D8BB1F23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - A7D8AC0123E2514100DCD162 /* SDL_nullevents_c.h in Headers */, - A7D8ABE923E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - A7D8ABFB23E2514100DCD162 /* SDL_nullvideo.h in Headers */, - A7D8AB5F23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8AB8323E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, - F31A92CD28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A7D8AB7123E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, - A7D8AB8923E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - A7D8B2C423E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8AC0723E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B9FF23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D8BA3523E2514400DCD162 /* SDL_rotate.h in Headers */, - A7D8B5C723E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, - A7D8A99123E2514000DCD162 /* SDL_sensor_c.h in Headers */, - A7D8BA7723E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8BA5323E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - A7D8B99023E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8B99F23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */, - A7D8B9A523E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D8AC0D23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - A7D8B4C823E2514300DCD162 /* SDL_steamcontroller.h in Headers */, - A7D8B85E23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D8AAD823E2514100DCD162 /* SDL_syshaptic.h in Headers */, - A7D8AAE423E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, - A7D8B58523E2514300DCD162 /* SDL_sysjoystick.h in Headers */, - 5605721A2473688C00B46B66 /* SDL_syslocale.h in Headers */, - A7D8B44423E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, - A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B61523E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B9DB23E2514400DCD162 /* SDL_sysrender.h in Headers */, - A7D8A97F23E2514000DCD162 /* SDL_syssensor.h in Headers */, - A7D8B3EA23E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D8B42C23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - 5616CA5A252BB35D005D5928 /* SDL_sysurl.h in Headers */, - A7D8AC4323E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */, - A7D8AB3523E2514100DCD162 /* SDL_timer_c.h in Headers */, - A7D8BB6723E2514500DCD162 /* SDL_touch_c.h in Headers */, - A1626A562617008D003F1973 /* SDL_triangle.h in Headers */, - A7D8ACCD23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8AC7923E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, - A7D8ACC123E2514100DCD162 /* SDL_uikitevents.h in Headers */, - A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8AC6123E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, - A7D8AC6D23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, - A7D8ACD923E2514100DCD162 /* SDL_uikitopengles.h in Headers */, - A7D8ACB523E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, - A7D8AC7F23E2514100DCD162 /* SDL_uikitvideo.h in Headers */, - A7D8AC4923E2514100DCD162 /* SDL_uikitview.h in Headers */, - A7D8AC8B23E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, - A7D8ACE523E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8AC9D23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, - F386F6F42884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA628A59BDD00B84553 /* SDL_vacopy.h in Headers */, - 75E09167241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - A7D8AD2123E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D8B87023E2514400DCD162 /* SDL_wave.h in Headers */, - A7D8BBAF23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B3B423E2514200DCD162 /* SDL_yuv_c.h in Headers */, - A7D8B9CF23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8BB4923E2514500DCD162 /* blank_cursor.h in Headers */, - A7D8B5BB23E2514300DCD162 /* controller_type.h in Headers */, - A7D8BB4F23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8B24023E2514200DCD162 /* egl.h in Headers */, - A7D8B24623E2514200DCD162 /* eglext.h in Headers */, - A7D8B24C23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B22E23E2514200DCD162 /* gl2.h in Headers */, - A7D8B22823E2514200DCD162 /* gl2ext.h in Headers */, - A7D8B23423E2514200DCD162 /* gl2platform.h in Headers */, - A75FDB5C23E39E6100529352 /* hidapi.h in Headers */, - A7D8ACA323E2514100DCD162 /* keyinfotable.h in Headers */, - A7D8B23A23E2514200DCD162 /* khrplatform.h in Headers */, - A7D8BB0723E2514500DCD162 /* math_libm.h in Headers */, - A7D8BAC523E2514500DCD162 /* math_private.h in Headers */, - A7D8BB5523E2514500DCD162 /* scancodes_darwin.h in Headers */, - A7D8BB6123E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8BB2523E2514500DCD162 /* scancodes_windows.h in Headers */, - A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */, - A7D8B57323E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B25823E2514200DCD162 /* vk_icd.h in Headers */, - A7D8B25223E2514200DCD162 /* vk_layer.h in Headers */, - A7D8B26A23E2514200DCD162 /* vk_platform.h in Headers */, - A7D8B2B223E2514200DCD162 /* vk_sdk_platform.h in Headers */, - A7D8B26423E2514200DCD162 /* vulkan.h in Headers */, - A7D8B27023E2514200DCD162 /* vulkan.hpp in Headers */, - A7D8B2B823E2514200DCD162 /* vulkan_android.h in Headers */, - A7D8B2AC23E2514200DCD162 /* vulkan_core.h in Headers */, - A7D8B27623E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D8B2A623E2514200DCD162 /* vulkan_ios.h in Headers */, - A7D8B28823E2514200DCD162 /* vulkan_macos.h in Headers */, - A7D8B29A23E2514200DCD162 /* vulkan_mir.h in Headers */, - A7D8B25E23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B27C23E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B28223E2514200DCD162 /* vulkan_win32.h in Headers */, - A7D8B29423E2514200DCD162 /* vulkan_xcb.h in Headers */, - A7D8B2A023E2514200DCD162 /* vulkan_xlib.h in Headers */, - A7D8B28E23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, - A7D8B3D823E2514300DCD162 /* yuv_rgb.h in Headers */, - A7D8B3CC23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B3D223E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BECDF5FF0761BA81005FE872 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -6316,6 +2068,7 @@ A7D8B8CC23E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8A96F23E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, F3F7D9B92933074E00816151 /* SDL_cpuinfo.h in Headers */, + F3990E062A788303000D8759 /* SDL_hidapi_ios.h in Headers */, A7D8B98023E2514400DCD162 /* SDL_d3dmath.h in Headers */, A7D8A94523E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8B8A223E2514400DCD162 /* SDL_diskaudio.h in Headers */, @@ -6353,6 +2106,7 @@ A7D8A99923E2514000DCD162 /* SDL_internal.h in Headers */, F3B38CDF296E2E52005DA6D3 /* SDL_intrin.h in Headers */, F395C1932569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, + F3990E052A788303000D8759 /* SDL_hidapi_mac.h in Headers */, F3F7D9912933074E00816151 /* SDL_joystick.h in Headers */, A7D8B58723E2514300DCD162 /* SDL_joystick_c.h in Headers */, F3F7D9512933074E00816151 /* SDL_keyboard.h in Headers */, @@ -6444,6 +2198,7 @@ A7D8BBD623E2574800DCD162 /* SDL_uikitevents.h in Headers */, A7D8BBD823E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */, A7D8BBDA23E2574800DCD162 /* SDL_uikitmetalview.h in Headers */, + F3990E042A788303000D8759 /* SDL_hidapi_c.h in Headers */, A7D8BBDC23E2574800DCD162 /* SDL_uikitmodes.h in Headers */, A7D8BBDE23E2574800DCD162 /* SDL_uikitopengles.h in Headers */, A7D8BBE023E2574800DCD162 /* SDL_uikitopenglview.h in Headers */, @@ -6473,7 +2228,6 @@ A7D8B22423E2514200DCD162 /* gl2ext.h in Headers */, A7D8B23023E2514200DCD162 /* gl2platform.h in Headers */, A75FDB5823E39E6100529352 /* hidapi.h in Headers */, - A7D8BBD123E2574800DCD162 /* keyinfotable.h in Headers */, A7D8B23623E2514200DCD162 /* khrplatform.h in Headers */, A7D8BB0323E2514500DCD162 /* math_libm.h in Headers */, A7D8BAC123E2514500DCD162 /* math_private.h in Headers */, @@ -6506,464 +2260,12 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BECDF66E0761BA81005FE872 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A7D8B3A123E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - A7D8B61A23E2514300DCD162 /* SDL_assert_c.h in Headers */, - A7D8B7A323E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B7B523E2514400DCD162 /* SDL_audiodev_c.h in Headers */, - A7D8BA0423E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B9EC23E2514400DCD162 /* SDL_blendline.h in Headers */, - A7D8BA1023E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8B3B923E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8B2BD23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8B39B23E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8ADEF23E2514100DCD162 /* SDL_blit_slow.h in Headers */, - A7D8BB7223E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8AECD23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, - A7D8AF1523E2514100DCD162 /* SDL_cocoaevents.h in Headers */, - A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8AF0923E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8AEB523E2514100DCD162 /* SDL_cocoametalview.h in Headers */, - A7D8AEF723E2514100DCD162 /* SDL_cocoamodes.h in Headers */, - A7D8AF2123E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AEDF23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, - A7D8AEF123E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, - A7D8AE8523E2514100DCD162 /* SDL_cocoashape.h in Headers */, - A7D8AF0323E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, - A7D8AEFD23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B8CF23E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8A97223E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - A7D8B98323E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8A94823E2514000DCD162 /* SDL_dataqueue.h in Headers */, - A7D8B8A523E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D8BB4223E2514500DCD162 /* SDL_displayevents_c.h in Headers */, - A7D8BA1C23E2514400DCD162 /* SDL_draw.h in Headers */, - A7D8BA0A23E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D8B9F223E2514400DCD162 /* SDL_drawpoint.h in Headers */, - A7D8BB3023E2514500DCD162 /* SDL_dropevents_c.h in Headers */, - A7D8B79723E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8A96623E2514000DCD162 /* SDL_dummysensor.h in Headers */, - A7D8AB0D23E2514100DCD162 /* SDL_dynapi.h in Headers */, - A7D8AB1323E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, - A7D8AB1F23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - A7D8ABDC23E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D8A96023E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8BBA823E2514500DCD162 /* SDL_events_c.h in Headers */, - A7D8B4AF23E2514300DCD162 /* SDL_gamepad_db.h in Headers */, - A7D8BA5823E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8BA7C23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D8AABF23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - A75FDBC823EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B55A23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - A7D8B94D23E2514400DCD162 /* SDL_hints_c.h in Headers */, - A7D8A99C23E2514000DCD162 /* SDL_internal.h in Headers */, - F395C1962569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - A7D8B58A23E2514300DCD162 /* SDL_joystick_c.h in Headers */, - A7D8BB8A23E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */, - F386F6EA2884663E001840AA /* SDL_log_c.h in Headers */, - F395C1BD2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - A7D8BB1E23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - A7D8AC0023E2514100DCD162 /* SDL_nullevents_c.h in Headers */, - A7D8ABE823E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - A7D8ABFA23E2514100DCD162 /* SDL_nullvideo.h in Headers */, - A7D8AB5E23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8AB8223E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, - F31A92CC28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A7D8AB7023E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, - A7D8AB8823E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - A7D8B2C323E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8AC0623E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B9FE23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D8BA3423E2514400DCD162 /* SDL_rotate.h in Headers */, - A7D8B5C623E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, - A7D8A99023E2514000DCD162 /* SDL_sensor_c.h in Headers */, - A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8BA5223E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - A7D8B98F23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8B99E23E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */, - A7D8B9A423E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D8AC0C23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - A7D8BBCB23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, - A7D8B85D23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D8AAD723E2514100DCD162 /* SDL_syshaptic.h in Headers */, - A7D8AAE323E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, - A7D8B58423E2514300DCD162 /* SDL_sysjoystick.h in Headers */, - 560572192473688C00B46B66 /* SDL_syslocale.h in Headers */, - A7D8B44323E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, - A7D8B5D823E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B61423E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B9DA23E2514400DCD162 /* SDL_sysrender.h in Headers */, - A7D8A97E23E2514000DCD162 /* SDL_syssensor.h in Headers */, - A7D8B3E923E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - 5616CA57252BB35C005D5928 /* SDL_sysurl.h in Headers */, - A7D8AC4223E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8B3EF23E2514300DCD162 /* SDL_thread_c.h in Headers */, - A7D8AB3423E2514100DCD162 /* SDL_timer_c.h in Headers */, - A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */, - A1626A552617008D003F1973 /* SDL_triangle.h in Headers */, - A7D8BBED23E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8BBEF23E2574800DCD162 /* SDL_uikitclipboard.h in Headers */, - A7D8BBF123E2574800DCD162 /* SDL_uikitevents.h in Headers */, - A7D8BBF323E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8BBF523E2574800DCD162 /* SDL_uikitmetalview.h in Headers */, - A7D8BBF723E2574800DCD162 /* SDL_uikitmodes.h in Headers */, - A7D8BBF923E2574800DCD162 /* SDL_uikitopengles.h in Headers */, - A7D8BBFB23E2574800DCD162 /* SDL_uikitopenglview.h in Headers */, - A7D8BBFD23E2574800DCD162 /* SDL_uikitvideo.h in Headers */, - A7D8BBFF23E2574800DCD162 /* SDL_uikitview.h in Headers */, - A7D8BC0123E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */, - A7D8BC0323E2574800DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8BC0523E2574800DCD162 /* SDL_uikitwindow.h in Headers */, - F386F6F32884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA528A59BDD00B84553 /* SDL_vacopy.h in Headers */, - 75E09166241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - A7D8AD2023E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D8B86F23E2514400DCD162 /* SDL_wave.h in Headers */, - A7D8BBAE23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B3B323E2514200DCD162 /* SDL_yuv_c.h in Headers */, - A7D8B9CE23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8BB4823E2514500DCD162 /* blank_cursor.h in Headers */, - A7D8B5BA23E2514300DCD162 /* controller_type.h in Headers */, - A7D8BB4E23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8B23F23E2514200DCD162 /* egl.h in Headers */, - A7D8B24523E2514200DCD162 /* eglext.h in Headers */, - A7D8B24B23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B22D23E2514200DCD162 /* gl2.h in Headers */, - A7D8B22723E2514200DCD162 /* gl2ext.h in Headers */, - A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */, - A75FDB5B23E39E6100529352 /* hidapi.h in Headers */, - A7D8BBEC23E2574800DCD162 /* keyinfotable.h in Headers */, - A7D8B23923E2514200DCD162 /* khrplatform.h in Headers */, - A7D8BB0623E2514500DCD162 /* math_libm.h in Headers */, - A7D8BAC423E2514500DCD162 /* math_private.h in Headers */, - A7D8BB5423E2514500DCD162 /* scancodes_darwin.h in Headers */, - A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8BB2423E2514500DCD162 /* scancodes_windows.h in Headers */, - A7D8BBA223E2514500DCD162 /* scancodes_xfree86.h in Headers */, - A7D8B57223E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B25723E2514200DCD162 /* vk_icd.h in Headers */, - A7D8B25123E2514200DCD162 /* vk_layer.h in Headers */, - A7D8B26923E2514200DCD162 /* vk_platform.h in Headers */, - A7D8B2B123E2514200DCD162 /* vk_sdk_platform.h in Headers */, - A7D8B26323E2514200DCD162 /* vulkan.h in Headers */, - A7D8B26F23E2514200DCD162 /* vulkan.hpp in Headers */, - A7D8B2B723E2514200DCD162 /* vulkan_android.h in Headers */, - A7D8B2AB23E2514200DCD162 /* vulkan_core.h in Headers */, - A7D8B27523E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D8B2A523E2514200DCD162 /* vulkan_ios.h in Headers */, - A7D8B28723E2514200DCD162 /* vulkan_macos.h in Headers */, - A7D8B29923E2514200DCD162 /* vulkan_mir.h in Headers */, - A7D8B25D23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B27B23E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B28123E2514200DCD162 /* vulkan_win32.h in Headers */, - A7D8B29323E2514200DCD162 /* vulkan_xcb.h in Headers */, - A7D8B29F23E2514200DCD162 /* vulkan_xlib.h in Headers */, - A7D8B28D23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, - A7D8B3D723E2514300DCD162 /* yuv_rgb.h in Headers */, - A7D8B3CB23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B3D123E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DB313F7317554B71006C0E22 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A7D8B3A323E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - A7D8B61C23E2514300DCD162 /* SDL_assert_c.h in Headers */, - A7D8B7A523E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B7B723E2514400DCD162 /* SDL_audiodev_c.h in Headers */, - A7D8BA0623E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B9EE23E2514400DCD162 /* SDL_blendline.h in Headers */, - A7D8BA1223E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8B3BB23E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8B2BF23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8B39D23E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8ADF123E2514100DCD162 /* SDL_blit_slow.h in Headers */, - A7D8BB7423E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8AECF23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, - A7D8AF1723E2514100DCD162 /* SDL_cocoaevents.h in Headers */, - A7D8AE9323E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8AF0B23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8AEB723E2514100DCD162 /* SDL_cocoametalview.h in Headers */, - A7D8AEF923E2514100DCD162 /* SDL_cocoamodes.h in Headers */, - A7D8AF2323E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AEE123E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, - A7D8AEF323E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, - A7D8AE8723E2514100DCD162 /* SDL_cocoashape.h in Headers */, - A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D8AEED23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, - A7D8AEFF23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B8D123E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8A97423E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - A7D8B98523E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8A94A23E2514000DCD162 /* SDL_dataqueue.h in Headers */, - A7D8B8A723E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D8BB4423E2514500DCD162 /* SDL_displayevents_c.h in Headers */, - A7D8BA1E23E2514400DCD162 /* SDL_draw.h in Headers */, - A7D8BA0C23E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D8B9F423E2514400DCD162 /* SDL_drawpoint.h in Headers */, - A7D8BB3223E2514500DCD162 /* SDL_dropevents_c.h in Headers */, - A7D8B79923E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8A96823E2514000DCD162 /* SDL_dummysensor.h in Headers */, - A7D8AB0F23E2514100DCD162 /* SDL_dynapi.h in Headers */, - A7D8AB1523E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, - A7D8AB2123E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - A7D8ABDE23E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D8A96223E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8BBAA23E2514500DCD162 /* SDL_events_c.h in Headers */, - A7D8B4B123E2514300DCD162 /* SDL_gamepad_db.h in Headers */, - A7D8BA5A23E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8BA7E23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D8AAC123E2514100DCD162 /* SDL_haptic_c.h in Headers */, - A75FDBCB23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B55C23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - A7D8B94F23E2514400DCD162 /* SDL_hints_c.h in Headers */, - A7D8A99E23E2514000DCD162 /* SDL_internal.h in Headers */, - F395C1992569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, - A7D8B58C23E2514300DCD162 /* SDL_joystick_c.h in Headers */, - A7D8BB8C23E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */, - F386F6ED2884663E001840AA /* SDL_log_c.h in Headers */, - F395C1C02569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, - A7D8BB2023E2514500DCD162 /* SDL_mouse_c.h in Headers */, - A7D8AC0223E2514100DCD162 /* SDL_nullevents_c.h in Headers */, - A7D8ABEA23E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - A7D8ABFC23E2514100DCD162 /* SDL_nullvideo.h in Headers */, - A7D8AB6023E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8AB8423E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, - F31A92CF28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, - A7D8AB7223E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, - A7D8AB8A23E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - A7D8B2C523E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8AC0823E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8BA0023E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D8BA3623E2514400DCD162 /* SDL_rotate.h in Headers */, - A7D8B5C823E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, - A7D8A99223E2514000DCD162 /* SDL_sensor_c.h in Headers */, - A7D8BA7823E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8BA5423E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - A7D8B99123E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8B9A023E2514400DCD162 /* SDL_shaders_metal_macos.h in Headers */, - A7D8B9A623E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D8AC0E23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, - A7D8B85F23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D8AAD923E2514100DCD162 /* SDL_syshaptic.h in Headers */, - A7D8AAE523E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, - A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */, - 5605721B2473688D00B46B66 /* SDL_syslocale.h in Headers */, - A7D8B44523E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, - A7D8B5DA23E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B61623E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B9DC23E2514400DCD162 /* SDL_sysrender.h in Headers */, - A7D8A98023E2514000DCD162 /* SDL_syssensor.h in Headers */, - A7D8B3EB23E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D8B42D23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - 5616CA60252BB35E005D5928 /* SDL_sysurl.h in Headers */, - A7D8AC4423E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8B3F123E2514300DCD162 /* SDL_thread_c.h in Headers */, - A7D8AB3623E2514100DCD162 /* SDL_timer_c.h in Headers */, - A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */, - A1626A582617008D003F1973 /* SDL_triangle.h in Headers */, - A7D8ACCE23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8AC7A23E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, - A7D8ACC223E2514100DCD162 /* SDL_uikitevents.h in Headers */, - A7D8AC9823E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8AC6223E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, - A7D8AC6E23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, - A7D8ACDA23E2514100DCD162 /* SDL_uikitopengles.h in Headers */, - A7D8ACB623E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, - A7D8AC8023E2514100DCD162 /* SDL_uikitvideo.h in Headers */, - A7D8AC4A23E2514100DCD162 /* SDL_uikitview.h in Headers */, - A7D8AC8C23E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, - A7D8ACE623E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8AC9E23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, - F386F6F62884663E001840AA /* SDL_utils_c.h in Headers */, - F3973FA828A59BDD00B84553 /* SDL_vacopy.h in Headers */, - 75E09169241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, - A7D8AD2223E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D8B87123E2514400DCD162 /* SDL_wave.h in Headers */, - A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B3B523E2514200DCD162 /* SDL_yuv_c.h in Headers */, - A7D8B9D023E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8BB4A23E2514500DCD162 /* blank_cursor.h in Headers */, - A7D8B5BC23E2514300DCD162 /* controller_type.h in Headers */, - A7D8BB5023E2514500DCD162 /* default_cursor.h in Headers */, - A7D8B24123E2514200DCD162 /* egl.h in Headers */, - A7D8B24723E2514200DCD162 /* eglext.h in Headers */, - A7D8B24D23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B22F23E2514200DCD162 /* gl2.h in Headers */, - A7D8B22923E2514200DCD162 /* gl2ext.h in Headers */, - A7D8B23523E2514200DCD162 /* gl2platform.h in Headers */, - A75FDB5E23E39E6100529352 /* hidapi.h in Headers */, - A7D8ACA423E2514100DCD162 /* keyinfotable.h in Headers */, - A7D8B23B23E2514200DCD162 /* khrplatform.h in Headers */, - A7D8BB0823E2514500DCD162 /* math_libm.h in Headers */, - A7D8BAC623E2514500DCD162 /* math_private.h in Headers */, - A7D8BB5623E2514500DCD162 /* scancodes_darwin.h in Headers */, - A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8BB2623E2514500DCD162 /* scancodes_windows.h in Headers */, - A7D8BBA423E2514500DCD162 /* scancodes_xfree86.h in Headers */, - A7D8B57423E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B25923E2514200DCD162 /* vk_icd.h in Headers */, - A7D8B25323E2514200DCD162 /* vk_layer.h in Headers */, - A7D8B26B23E2514200DCD162 /* vk_platform.h in Headers */, - A7D8B2B323E2514200DCD162 /* vk_sdk_platform.h in Headers */, - A7D8B26523E2514200DCD162 /* vulkan.h in Headers */, - A7D8B27123E2514200DCD162 /* vulkan.hpp in Headers */, - A7D8B2B923E2514200DCD162 /* vulkan_android.h in Headers */, - A7D8B2AD23E2514200DCD162 /* vulkan_core.h in Headers */, - A7D8B27723E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D8B2A723E2514200DCD162 /* vulkan_ios.h in Headers */, - A7D8B28923E2514200DCD162 /* vulkan_macos.h in Headers */, - A7D8B29B23E2514200DCD162 /* vulkan_mir.h in Headers */, - A7D8B25F23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B27D23E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B28323E2514200DCD162 /* vulkan_win32.h in Headers */, - A7D8B29523E2514200DCD162 /* vulkan_xcb.h in Headers */, - A7D8B2A123E2514200DCD162 /* vulkan_xlib.h in Headers */, - A7D8B28F23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, - A7D8B3D923E2514300DCD162 /* yuv_rgb.h in Headers */, - A7D8B3CD23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B3D323E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - A75FCCFB23E25AB700529352 /* Shared Library-iOS */ = { + BECDF5FE0761BA81005FE872 /* SDL3 */ = { isa = PBXNativeTarget; - buildConfigurationList = A75FCEB023E25AB700529352 /* Build configuration list for PBXNativeTarget "Shared Library-iOS" */; - buildPhases = ( - A75FCCFC23E25AB700529352 /* Headers */, - A75FCDE823E25AB700529352 /* Sources */, - A75FCEA423E25AB700529352 /* Frameworks */, - A75FCEAF23E25AB700529352 /* Rez */, - ); - buildRules = ( - ); - comments = "This produces libSDL3.dylib, which is the shared build of SDL."; - dependencies = ( - ); - name = "Shared Library-iOS"; - productInstallPath = /usr/local/lib; - productName = "Shared Library"; - productReference = A75FCEB323E25AB700529352 /* libSDL3.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; - A75FCEB423E25AC700529352 /* Shared Library-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FD06923E25AC700529352 /* Build configuration list for PBXNativeTarget "Shared Library-tvOS" */; - buildPhases = ( - A75FCEB523E25AC700529352 /* Headers */, - A75FCFA123E25AC700529352 /* Sources */, - A75FD05D23E25AC700529352 /* Frameworks */, - A75FD06823E25AC700529352 /* Rez */, - ); - buildRules = ( - ); - comments = "This produces libSDL3.dylib, which is the shared build of SDL."; - dependencies = ( - ); - name = "Shared Library-tvOS"; - productInstallPath = /usr/local/lib; - productName = "Shared Library"; - productReference = A75FD06C23E25AC700529352 /* libSDL3.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; - A769B08223E259AE00872273 /* Static Library-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A769B23A23E259AE00872273 /* Build configuration list for PBXNativeTarget "Static Library-tvOS" */; - buildPhases = ( - A769B08323E259AE00872273 /* Headers */, - A769B17023E259AE00872273 /* Sources */, - A769B22E23E259AE00872273 /* Frameworks */, - A769B23923E259AE00872273 /* Rez */, - ); - 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."; - dependencies = ( - ); - name = "Static Library-tvOS"; - productInstallPath = /usr/local/lib; - productName = "Static Library"; - productReference = A769B23D23E259AE00872273 /* libSDL3.a */; - productType = "com.apple.product-type.library.static"; - }; - A7D88A1423E2437C00DCD162 /* Framework-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A7D88B5123E2437C00DCD162 /* Build configuration list for PBXNativeTarget "Framework-iOS" */; - buildPhases = ( - A7D88A1523E2437C00DCD162 /* Headers */, - A7D88ABE23E2437C00DCD162 /* Resources */, - A7D88ABF23E2437C00DCD162 /* Sources */, - A7D88B4623E2437C00DCD162 /* Frameworks */, - A75FDB9F23E4CAFA00529352 /* Embed Frameworks */, - ); - buildRules = ( - ); - comments = "We recommend installing to /Library/Frameworks\nAn alternative is $(HOME)/Library/Frameworks for per-user if permissions are an issue.\n\nAdd the framework to the Groups & Files panel (under Linked Frameworks is a good place) and enable the check box for the targets that need to link to it. You can also manually add \"-framework SDL\" to your linker flags if you don't like the check box system.\n\nAdd /Library/Frameworks/SDL.framework/Headers to your header search path\nAdd /Library/Frameworks to your library search path\n(Adjust the two above if installed in $(HOME)/Library/Frameworks. You can also list both paths if you want robustness.)\n\nWe used to use an exports file. It was becoming a maintenance issue we kept neglecting, so we have removed it.\n\n"; - dependencies = ( - ); - name = "Framework-iOS"; - productInstallPath = "@executable_path/../Frameworks"; - productName = SDL; - productReference = A7D88B5423E2437C00DCD162 /* SDL3.framework */; - productType = "com.apple.product-type.framework"; - }; - A7D88BC923E24BED00DCD162 /* Framework-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A7D88D1223E24BED00DCD162 /* Build configuration list for PBXNativeTarget "Framework-tvOS" */; - buildPhases = ( - A7D88BCA23E24BED00DCD162 /* Headers */, - A7D88C7723E24BED00DCD162 /* Resources */, - A7D88C7823E24BED00DCD162 /* Sources */, - A7D88D0423E24BED00DCD162 /* Frameworks */, - A75FDBA223E4CAFF00529352 /* Embed Frameworks */, - ); - buildRules = ( - ); - comments = "We recommend installing to /Library/Frameworks\nAn alternative is $(HOME)/Library/Frameworks for per-user if permissions are an issue.\n\nAdd the framework to the Groups & Files panel (under Linked Frameworks is a good place) and enable the check box for the targets that need to link to it. You can also manually add \"-framework SDL\" to your linker flags if you don't like the check box system.\n\nAdd /Library/Frameworks/SDL.framework/Headers to your header search path\nAdd /Library/Frameworks to your library search path\n(Adjust the two above if installed in $(HOME)/Library/Frameworks. You can also list both paths if you want robustness.)\n\nWe used to use an exports file. It was becoming a maintenance issue we kept neglecting, so we have removed it.\n\n"; - dependencies = ( - ); - name = "Framework-tvOS"; - productInstallPath = "@executable_path/../Frameworks"; - productName = SDL; - productReference = A7D88D1523E24BED00DCD162 /* SDL3.framework */; - productType = "com.apple.product-type.framework"; - }; - A7D88D1723E24D3B00DCD162 /* Static Library-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A7D88E5123E24D3B00DCD162 /* Build configuration list for PBXNativeTarget "Static Library-iOS" */; - buildPhases = ( - A7D88D1823E24D3B00DCD162 /* Headers */, - A7D88DBC23E24D3B00DCD162 /* Sources */, - A7D88E4523E24D3B00DCD162 /* Frameworks */, - A7D88E5023E24D3B00DCD162 /* Rez */, - ); - 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."; - dependencies = ( - ); - name = "Static Library-iOS"; - productInstallPath = /usr/local/lib; - productName = "Static Library"; - productReference = A7D88E5423E24D3B00DCD162 /* libSDL3.a */; - productType = "com.apple.product-type.library.static"; - }; - BECDF5FE0761BA81005FE872 /* Framework */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0073177A0858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "Framework" */; + buildConfigurationList = 0073177A0858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "SDL3" */; buildPhases = ( BECDF5FF0761BA81005FE872 /* Headers */, BECDF62A0761BA81005FE872 /* Resources */, @@ -6976,69 +2278,12 @@ comments = "We recommend installing to /Library/Frameworks\nAn alternative is $(HOME)/Library/Frameworks for per-user if permissions are an issue.\n\nAdd the framework to the Groups & Files panel (under Linked Frameworks is a good place) and enable the check box for the targets that need to link to it. You can also manually add \"-framework SDL\" to your linker flags if you don't like the check box system.\n\nAdd /Library/Frameworks/SDL.framework/Headers to your header search path\nAdd /Library/Frameworks to your library search path\n(Adjust the two above if installed in $(HOME)/Library/Frameworks. You can also list both paths if you want robustness.)\n\nWe used to use an exports file. It was becoming a maintenance issue we kept neglecting, so we have removed it.\n\n"; dependencies = ( ); - name = Framework; + name = SDL3; productInstallPath = "@executable_path/../Frameworks"; productName = SDL; productReference = BECDF66C0761BA81005FE872 /* SDL3.framework */; productType = "com.apple.product-type.framework"; }; - BECDF66D0761BA81005FE872 /* Static Library */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0073177E0858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "Static Library" */; - buildPhases = ( - BECDF66E0761BA81005FE872 /* Headers */, - BECDF6790761BA81005FE872 /* Sources */, - BECDF6B10761BA81005FE872 /* Frameworks */, - BECDF6B20761BA81005FE872 /* Rez */, - ); - 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."; - dependencies = ( - ); - name = "Static Library"; - productInstallPath = /usr/local/lib; - productName = "Static Library"; - productReference = BECDF6B30761BA81005FE872 /* libSDL3.a */; - productType = "com.apple.product-type.library.static"; - }; - BECDF6BB0761BA81005FE872 /* Standard DMG */ = { - isa = PBXNativeTarget; - buildConfigurationList = 007317860858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "Standard DMG" */; - buildPhases = ( - BECDF6BD0761BA81005FE872 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - F3B38CF4296F6C8D005DA6D3 /* PBXTargetDependency */, - ); - name = "Standard DMG"; - productInstallPath = /usr/local/bin; - productName = "Standard Package"; - productReference = BECDF6BE0761BA81005FE872 /* SDL3 */; - productType = "com.apple.product-type.tool"; - }; - DB313F7217554B71006C0E22 /* Shared Library */ = { - isa = PBXNativeTarget; - buildConfigurationList = DB31407417554B71006C0E22 /* Build configuration list for PBXNativeTarget "Shared Library" */; - buildPhases = ( - DB313F7317554B71006C0E22 /* Headers */, - DB313FFD17554B71006C0E22 /* Sources */, - DB31406B17554B71006C0E22 /* Frameworks */, - DB31407317554B71006C0E22 /* Rez */, - ); - buildRules = ( - ); - comments = "This produces libSDL3.dylib, which is the shared build of SDL."; - dependencies = ( - ); - name = "Shared Library"; - productInstallPath = /usr/local/lib; - productName = "Shared Library"; - productReference = DB31407717554B71006C0E22 /* libSDL3.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -7047,6 +2292,9 @@ attributes = { LastUpgradeCheck = 1130; TargetAttributes = { + F3676F582A7885080091160D = { + CreatedOnToolsVersion = 14.3.1; + }; F3B38CEC296F63B6005DA6D3 = { CreatedOnToolsVersion = 14.2; }; @@ -7066,42 +2314,14 @@ projectDirPath = ""; projectRoot = ""; targets = ( - BECDF5FE0761BA81005FE872 /* Framework */, - A7D88A1423E2437C00DCD162 /* Framework-iOS */, - A7D88BC923E24BED00DCD162 /* Framework-tvOS */, - BECDF66D0761BA81005FE872 /* Static Library */, - A7D88D1723E24D3B00DCD162 /* Static Library-iOS */, - A769B08223E259AE00872273 /* Static Library-tvOS */, - DB313F7217554B71006C0E22 /* Shared Library */, - A75FCCFB23E25AB700529352 /* Shared Library-iOS */, - A75FCEB423E25AC700529352 /* Shared Library-tvOS */, - BECDF6BB0761BA81005FE872 /* Standard DMG */, - F3B38CEC296F63B6005DA6D3 /* SDL.xcframework */, + BECDF5FE0761BA81005FE872 /* SDL3 */, + F3B38CEC296F63B6005DA6D3 /* SDL3.xcframework */, + F3676F582A7885080091160D /* SDL3.dmg */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - A7D88ABE23E2437C00DCD162 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F37A8E1B28405AA100C38E95 /* CMake in Resources */, - A75FDBBA23E4CBC700529352 /* ReadMe.txt in Resources */, - A75FDBB923E4CBC700529352 /* License.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88C7723E24BED00DCD162 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F37A8E1C28405AA100C38E95 /* CMake in Resources */, - A75FDBBC23E4CBC800529352 /* ReadMe.txt in Resources */, - A75FDBBB23E4CBC800529352 /* License.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BECDF62A0761BA81005FE872 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -7114,58 +2334,21 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXRezBuildPhase section */ - A75FCEAF23E25AB700529352 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FD06823E25AC700529352 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A769B23923E259AE00872273 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88E5023E24D3B00DCD162 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BECDF6B20761BA81005FE872 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DB31407317554B71006C0E22 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXRezBuildPhase section */ - /* Begin PBXShellScriptBuildPhase section */ - BECDF6BD0761BA81005FE872 /* ShellScript */ = { + F3676F5E2A78852D0091160D /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; - buildActionMask = 12; + buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "mkdir -p build/dmg-tmp\ncp -a build/SDL3.xcframework 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 SDL3 -srcfolder build/dmg-tmp build/SDL3.dmg\n\n# clean up\nrm -rf build/dmg-tmp\n"; @@ -7186,1187 +2369,11 @@ ); 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 echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3\"\nPROJECT_NAME=\"SDL\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"Framework\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -sdk macosx \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"Framework-iOS\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk iphonesimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"Framework-iOS\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -sdk iphoneos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"Framework-tvOS\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk appletvsimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"Framework-tvOS\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -sdk appletvos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\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 -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -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"; + 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 echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3\"\nPROJECT_NAME=\"SDL\"\nSCHEME=\"SDL3\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -destination 'generic/platform=macOS,name=Any Mac' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\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 -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -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"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - A75FCDE823E25AB700529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 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 */, - A75FCDEF23E25AB700529352 /* SDL_spinlock.c in Sources */, - A75FDBD523EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - A75FCDF023E25AB700529352 /* s_atan.c in Sources */, - A75FCDF123E25AB700529352 /* SDL_sysloadso.c in Sources */, - A75FCDF223E25AB700529352 /* SDL_render_metal.m in Sources */, - A75FCDF323E25AB700529352 /* SDL_clipboard.c in Sources */, - A75FCDF423E25AB700529352 /* SDL_cocoaevents.m 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 */, - 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 */, - 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 */, - A75FCE0723E25AB700529352 /* SDL_systhread.c in Sources */, - A75FCE0823E25AB700529352 /* SDL_windowevents.c in Sources */, - A75FCE0923E25AB700529352 /* s_scalbn.c in Sources */, - A75FCE0A23E25AB700529352 /* SDL_timer.c in Sources */, - A75FCE0B23E25AB700529352 /* SDL_blendpoint.c in Sources */, - A75FCE0C23E25AB700529352 /* SDL_gamepad.c in Sources */, - A75FCE0D23E25AB700529352 /* SDL_systimer.c in Sources */, - A75FCE0E23E25AB700529352 /* SDL_uikitclipboard.m in Sources */, - A75FCE0F23E25AB700529352 /* SDL_render_sw.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 */, - A75FCE1823E25AB700529352 /* SDL_nullvideo.c in Sources */, - A75FCE1923E25AB700529352 /* SDL_offscreenevents.c in Sources */, - A75FCE1A23E25AB700529352 /* SDL_uikitview.m in Sources */, - A75FCE1B23E25AB700529352 /* SDL_nullevents.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 */, - 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 */, - F36C7AD9294BA009004D61C3 /* SDL_runapp.c 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 */, - A75FCE2923E25AB700529352 /* e_atan2.c in Sources */, - A75FCE2A23E25AB700529352 /* s_sin.c in Sources */, - 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 */, - A75FCE3223E25AB700529352 /* SDL_uikitvideo.m in Sources */, - 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 */, - A75FCE4123E25AB700529352 /* SDL_sysloadso.c in Sources */, - F31A92DA28D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, - A75FCE4323E25AB700529352 /* SDL_syspower.c in Sources */, - A75FCE4523E25AB700529352 /* SDL_iconv.c in Sources */, - A75FCE4623E25AB700529352 /* s_fabs.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 */, - A75FCE4D23E25AB700529352 /* s_floor.c in Sources */, - A75FCE4E23E25AB700529352 /* SDL_blit_copy.c in Sources */, - A75FCE4F23E25AB700529352 /* e_fmod.c in Sources */, - A75FCE5023E25AB700529352 /* SDL_syspower.m in Sources */, - 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 */, - F386F7002884663E001840AA /* SDL_utils.c in Sources */, - A75FCE5523E25AB700529352 /* SDL_blit_0.c in Sources */, - A75FCE5623E25AB700529352 /* k_tan.c in Sources */, - A75FCE5823E25AB700529352 /* SDL_diskaudio.c in Sources */, - A75FCE5923E25AB700529352 /* SDL_egl.c in Sources */, - A75FCE5A23E25AB700529352 /* SDL_RLEaccel.c in Sources */, - A75FCE5C23E25AB700529352 /* SDL_assert.c in Sources */, - A75FCE5D23E25AB700529352 /* SDL_bmp.c in Sources */, - A75FCE5E23E25AB700529352 /* SDL_stdlib.c in Sources */, - A75FCE5F23E25AB700529352 /* SDL_dummyaudio.c in Sources */, - 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 */, - A75FCE6523E25AB700529352 /* SDL_uikitopengles.m in Sources */, - A75FCE6723E25AB700529352 /* SDL_cocoamodes.m in Sources */, - A75FCE6823E25AB700529352 /* k_rem_pio2.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 */, - A75FCE7023E25AB700529352 /* SDL_hidapi_xboxone.c in Sources */, - A75FCE7123E25AB700529352 /* SDL_blit_auto.c in Sources */, - A75FCE7323E25AB700529352 /* SDL_keyboard.c in Sources */, - 56A2373A29F9C113003CCA5F /* SDL_sysrwlock.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 */, - A75FCE7C23E25AB700529352 /* k_cos.c in Sources */, - A75FCE7D23E25AB700529352 /* SDL_hidapijoystick.c in Sources */, - A75FCE7E23E25AB700529352 /* SDL_malloc.c in Sources */, - A75FCE7F23E25AB700529352 /* SDL_audio.c in Sources */, - A75FCE8023E25AB700529352 /* SDL_sysfilesystem.c in Sources */, - A75FCE8123E25AB700529352 /* SDL_offscreenvideo.c in Sources */, - A75FCE8223E25AB700529352 /* SDL_syscond.c in Sources */, - A75FCE8323E25AB700529352 /* SDL_syshaptic.c in Sources */, - 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 */, - 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 */, - 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 */, - A75FCE9823E25AB700529352 /* k_sin.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 */, - A75FCE9F23E25AB700529352 /* SDL.c in Sources */, - A75FCEA123E25AB700529352 /* SDL_cocoavulkan.m in Sources */, - A75FCEA223E25AB700529352 /* SDL_uikitappdelegate.m in Sources */, - A75FCEA323E25AB700529352 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FCFA123E25AC700529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 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 */, - A75FCFA823E25AC700529352 /* SDL_spinlock.c in Sources */, - A75FDBD623EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - A75FCFA923E25AC700529352 /* s_atan.c in Sources */, - A75FCFAA23E25AC700529352 /* SDL_sysloadso.c in Sources */, - A75FCFAB23E25AC700529352 /* SDL_render_metal.m in Sources */, - A75FCFAC23E25AC700529352 /* SDL_clipboard.c in Sources */, - A75FCFAD23E25AC700529352 /* SDL_cocoaevents.m 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 */, - 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 */, - 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 */, - A75FCFC023E25AC700529352 /* SDL_systhread.c in Sources */, - A75FCFC123E25AC700529352 /* SDL_windowevents.c in Sources */, - A75FCFC223E25AC700529352 /* s_scalbn.c in Sources */, - A75FCFC323E25AC700529352 /* SDL_timer.c in Sources */, - A75FCFC423E25AC700529352 /* SDL_blendpoint.c in Sources */, - A75FCFC523E25AC700529352 /* SDL_gamepad.c in Sources */, - A75FCFC623E25AC700529352 /* SDL_systimer.c in Sources */, - A75FCFC723E25AC700529352 /* SDL_uikitclipboard.m in Sources */, - A75FCFC823E25AC700529352 /* SDL_render_sw.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 */, - A75FCFD123E25AC700529352 /* SDL_nullvideo.c in Sources */, - A75FCFD223E25AC700529352 /* SDL_offscreenevents.c in Sources */, - A75FCFD323E25AC700529352 /* SDL_uikitview.m in Sources */, - A75FCFD423E25AC700529352 /* SDL_nullevents.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 */, - 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 */, - F36C7ADA294BA009004D61C3 /* SDL_runapp.c 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 */, - A75FCFE223E25AC700529352 /* e_atan2.c in Sources */, - A75FCFE323E25AC700529352 /* s_sin.c in Sources */, - 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 */, - A75FCFEB23E25AC700529352 /* SDL_uikitvideo.m in Sources */, - 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 */, - A75FCFFA23E25AC700529352 /* SDL_sysloadso.c in Sources */, - F31A92DB28D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, - A75FCFFC23E25AC700529352 /* SDL_syspower.c in Sources */, - A75FCFFE23E25AC700529352 /* SDL_iconv.c in Sources */, - A75FCFFF23E25AC700529352 /* s_fabs.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 */, - A75FD00623E25AC700529352 /* s_floor.c in Sources */, - A75FD00723E25AC700529352 /* SDL_blit_copy.c in Sources */, - A75FD00823E25AC700529352 /* e_fmod.c in Sources */, - A75FD00923E25AC700529352 /* SDL_syspower.m in Sources */, - 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 */, - F386F7012884663E001840AA /* SDL_utils.c in Sources */, - A75FD00E23E25AC700529352 /* SDL_blit_0.c in Sources */, - A75FD00F23E25AC700529352 /* k_tan.c in Sources */, - A75FD01123E25AC700529352 /* SDL_diskaudio.c in Sources */, - A75FD01223E25AC700529352 /* SDL_egl.c in Sources */, - A75FD01323E25AC700529352 /* SDL_RLEaccel.c in Sources */, - A75FD01523E25AC700529352 /* SDL_assert.c in Sources */, - A75FD01623E25AC700529352 /* SDL_bmp.c in Sources */, - A75FD01723E25AC700529352 /* SDL_stdlib.c in Sources */, - A75FD01823E25AC700529352 /* SDL_dummyaudio.c in Sources */, - 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 */, - A75FD01E23E25AC700529352 /* SDL_uikitopengles.m in Sources */, - A75FD02023E25AC700529352 /* SDL_cocoamodes.m in Sources */, - A75FD02123E25AC700529352 /* k_rem_pio2.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 */, - A75FD02923E25AC700529352 /* SDL_hidapi_xboxone.c in Sources */, - A75FD02A23E25AC700529352 /* SDL_blit_auto.c in Sources */, - A75FD02C23E25AC700529352 /* SDL_keyboard.c in Sources */, - 56A2373B29F9C113003CCA5F /* SDL_sysrwlock.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 */, - A75FD03523E25AC700529352 /* k_cos.c in Sources */, - A75FD03623E25AC700529352 /* SDL_hidapijoystick.c in Sources */, - A75FD03723E25AC700529352 /* SDL_malloc.c in Sources */, - A75FD03823E25AC700529352 /* SDL_audio.c in Sources */, - A75FD03923E25AC700529352 /* SDL_sysfilesystem.c in Sources */, - A75FD03A23E25AC700529352 /* SDL_offscreenvideo.c in Sources */, - A75FD03B23E25AC700529352 /* SDL_syscond.c in Sources */, - A75FD03C23E25AC700529352 /* SDL_syshaptic.c in Sources */, - 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 */, - 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 */, - 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 */, - A75FD05123E25AC700529352 /* k_sin.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 */, - A75FD05823E25AC700529352 /* SDL.c in Sources */, - A75FD05A23E25AC700529352 /* SDL_cocoavulkan.m in Sources */, - A75FD05B23E25AC700529352 /* SDL_uikitappdelegate.m in Sources */, - A75FD05C23E25AC700529352 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A769B17023E259AE00872273 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A769B17123E259AE00872273 /* SDL_drawline.c in Sources */, - A769B17223E259AE00872273 /* SDL_yuv.c in Sources */, - A769B17323E259AE00872273 /* SDL_sysfilesystem.m in Sources */, - A769B17423E259AE00872273 /* e_pow.c in Sources */, - A769B17523E259AE00872273 /* SDL_systls.c in Sources */, - A769B17623E259AE00872273 /* SDL_vulkan_utils.c in Sources */, - A769B17723E259AE00872273 /* SDL_spinlock.c in Sources */, - A769B17823E259AE00872273 /* s_atan.c in Sources */, - A769B17923E259AE00872273 /* SDL_sysloadso.c in Sources */, - A75FDAB023E2795C00529352 /* SDL_hidapi_steam.c in Sources */, - A769B17A23E259AE00872273 /* SDL_render_metal.m in Sources */, - A769B17B23E259AE00872273 /* SDL_clipboard.c in Sources */, - A769B17C23E259AE00872273 /* SDL_cocoaevents.m 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 */, - 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 */, - A769B18B23E259AE00872273 /* SDL_log.c in Sources */, - A769B18C23E259AE00872273 /* SDL_cocoaopengl.m in Sources */, - A769B18D23E259AE00872273 /* SDL_offscreenframebuffer.c in Sources */, - A769B18E23E259AE00872273 /* yuv_rgb.c in Sources */, - A769B19023E259AE00872273 /* SDL_systhread.c in Sources */, - A769B19123E259AE00872273 /* SDL_windowevents.c in Sources */, - A769B19223E259AE00872273 /* s_scalbn.c in Sources */, - A769B19323E259AE00872273 /* SDL_timer.c in Sources */, - A769B19423E259AE00872273 /* SDL_blendpoint.c in Sources */, - A769B19523E259AE00872273 /* SDL_gamepad.c in Sources */, - A769B19623E259AE00872273 /* SDL_systimer.c in Sources */, - A769B19723E259AE00872273 /* SDL_uikitclipboard.m in Sources */, - A769B19823E259AE00872273 /* SDL_render_sw.c in Sources */, - A769B19A23E259AE00872273 /* SDL_syssem.c in Sources */, - A769B19B23E259AE00872273 /* SDL_hidapi_xbox360.c in Sources */, - A769B19C23E259AE00872273 /* SDL_coreaudio.m in Sources */, - A769B19D23E259AE00872273 /* SDL_blendline.c in Sources */, - A769B19E23E259AE00872273 /* SDL_blit_A.c in Sources */, - A769B19F23E259AE00872273 /* SDL_d3dmath.c in Sources */, - A769B1A123E259AE00872273 /* SDL_nullvideo.c in Sources */, - A769B1A223E259AE00872273 /* SDL_offscreenevents.c in Sources */, - A769B1A323E259AE00872273 /* SDL_uikitview.m in Sources */, - A769B1A423E259AE00872273 /* SDL_nullevents.c in Sources */, - A769B1A523E259AE00872273 /* SDL_audiodev.c in Sources */, - A769B1A623E259AE00872273 /* SDL_cocoaclipboard.m in Sources */, - A769B1A723E259AE00872273 /* SDL_blit_slow.c in Sources */, - A769B1A823E259AE00872273 /* s_copysign.c in Sources */, - A769B1A923E259AE00872273 /* SDL_haptic.c in Sources */, - A769B1AA23E259AE00872273 /* SDL_uikitvulkan.m 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 */, - A769B1C423E259AE00872273 /* SDL_yuv_sw.c in Sources */, - 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 */, - A769B1CB23E259AE00872273 /* SDL_sysloadso.c in Sources */, - A769B1CD23E259AE00872273 /* SDL_syspower.c in Sources */, - A769B1CF23E259AE00872273 /* SDL_iconv.c in Sources */, - A769B1D023E259AE00872273 /* s_fabs.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 */, - A769B1D723E259AE00872273 /* s_floor.c in Sources */, - A769B1D823E259AE00872273 /* SDL_blit_copy.c in Sources */, - A769B1D923E259AE00872273 /* e_fmod.c in Sources */, - A769B1DA23E259AE00872273 /* SDL_syspower.m in Sources */, - A769B1DB23E259AE00872273 /* e_log10.c in Sources */, - A769B1DC23E259AE00872273 /* SDL_uikitopenglview.m in Sources */, - A769B1DD23E259AE00872273 /* SDL_mixer.c in Sources */, - A769B1DE23E259AE00872273 /* SDL_events.c in Sources */, - A769B1DF23E259AE00872273 /* SDL_blit_0.c in Sources */, - F36C7AD7294BA009004D61C3 /* SDL_runapp.c in Sources */, - A769B1E023E259AE00872273 /* k_tan.c in Sources */, - A769B1E223E259AE00872273 /* SDL_diskaudio.c 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 */, - F3F07D5F269640160074468B /* SDL_hidapi_luna.c in Sources */, - A769B1EA23E259AE00872273 /* SDL_stdlib.c in Sources */, - A769B1EB23E259AE00872273 /* SDL_dummyaudio.c in Sources */, - A769B1EC23E259AE00872273 /* SDL_fillrect.c in Sources */, - A769B1ED23E259AE00872273 /* SDL_nullframebuffer.c in Sources */, - A769B1EE23E259AE00872273 /* SDL_dummysensor.c in Sources */, - A769B1EF23E259AE00872273 /* SDL_string.c in Sources */, - A769B1F023E259AE00872273 /* SDL_render_gl.c in Sources */, - A769B1F123E259AE00872273 /* SDL_uikitopengles.m in Sources */, - A769B1F323E259AE00872273 /* SDL_cocoamodes.m in Sources */, - A769B1F423E259AE00872273 /* k_rem_pio2.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 */, - F395BF6A25633B2400942BFF /* SDL_crc32.c in Sources */, - A769B1FC23E259AE00872273 /* SDL_hidapi_xboxone.c in Sources */, - A769B1FD23E259AE00872273 /* SDL_blit_auto.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 */, - A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */, - F3984CD525BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, - A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */, - 56A2373829F9C113003CCA5F /* SDL_sysrwlock.c in Sources */, - 5605720B2473687A00B46B66 /* SDL_syslocale.m in Sources */, - F3820718284F3609004DD584 /* controller_type.c in Sources */, - A769B20623E259AE00872273 /* SDL_clipboardevents.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 */, - A769B20C23E259AE00872273 /* SDL_sysfilesystem.c in Sources */, - A75FDBD323EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - A769B20D23E259AE00872273 /* SDL_offscreenvideo.c in Sources */, - 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 */, - 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 */, - 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 */, - A769B22323E259AE00872273 /* k_sin.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 */, - 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; - }; - A7D88ABF23E2437C00DCD162 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 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 */, - A7D8A95223E2514000DCD162 /* SDL_spinlock.c in Sources */, - A7D8BAB023E2514400DCD162 /* s_atan.c in Sources */, - 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 */, - 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 */, - 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 */, - A7D8AB2623E2514100DCD162 /* SDL_log.c in Sources */, - A7D8AE8923E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, - A7D8AB7423E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C023E2514200DCD162 /* yuv_rgb.c 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 */, - A7D8B9DE23E2514400DCD162 /* SDL_blendpoint.c in Sources */, - A7D8B4EF23E2514300DCD162 /* SDL_gamepad.c in Sources */, - A7D8AB3823E2514100DCD162 /* SDL_systimer.c in Sources */, - A7D8ACAC23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, - A7D8BA1423E2514400DCD162 /* SDL_render_sw.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 */, - 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 */, - 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 */, - 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 */, - F36C7AD2294BA009004D61C3 /* SDL_runapp.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 */, - A7D8AED723E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, - A7D8AB1723E2514100DCD162 /* SDL_dynapi.c in Sources */, - 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 */, - A7D8AEB923E2514100DCD162 /* SDL_cocoamouse.m in Sources */, - A7D8B8E523E2514400DCD162 /* SDL_error.c in Sources */, - A7D8AD6923E2514100DCD162 /* SDL_blit.c in Sources */, - 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 */, - 5616CA52252BB35A005D5928 /* SDL_url.c in Sources */, - 9846B07D287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, - A7D8B75F23E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B5F423E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B95123E2514400DCD162 /* SDL_iconv.c in Sources */, - F31A92D328D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, - A7D8BA9E23E2514400DCD162 /* s_fabs.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 */, - A7D8BAE023E2514500DCD162 /* e_fmod.c in Sources */, - A7D8B5D023E2514300DCD162 /* SDL_syspower.m in Sources */, - A7D8BAEC23E2514500DCD162 /* e_log10.c in Sources */, - A7D8AC7023E2514100DCD162 /* SDL_uikitopenglview.m in Sources */, - A7D8B76523E2514300DCD162 /* SDL_mixer.c in Sources */, - A7D8BB5823E2514500DCD162 /* SDL_events.c in Sources */, - A7D8ADE723E2514100DCD162 /* SDL_blit_0.c in Sources */, - A7D8BB0A23E2514500DCD162 /* k_tan.c in Sources */, - A75FDBCF23EA380300529352 /* SDL_hidapi_rumble.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 */, - A7D8BBB223E2514500DCD162 /* SDL_assert.c in Sources */, - A7D8B3DB23E2514300DCD162 /* SDL_bmp.c in Sources */, - A7D8B96F23E2514400DCD162 /* SDL_stdlib.c in Sources */, - A7D8B79B23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, - A7D8B3A523E2514200DCD162 /* SDL_fillrect.c in Sources */, - A7D8ABE023E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, - 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 */, - A7D8AE9523E2514100DCD162 /* SDL_cocoamodes.m in Sources */, - A7D8BAA423E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B95723E2514400DCD162 /* SDL_getenv.c in Sources */, - A7D8B56423E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, - A7D8B4DD23E2514300DCD162 /* SDL_joystick.c in Sources */, - A7D8BA4A23E2514400DCD162 /* SDL_render_gles2.c in Sources */, - A7D8AC2E23E2514100DCD162 /* SDL_surface.c in Sources */, - A7D8B54C23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, - A7D8AD2423E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8BB6A23E2514500DCD162 /* SDL_keyboard.c in Sources */, - A7D8ACE823E2514100DCD162 /* SDL_rect.c in Sources */, - A7D8AE9B23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, - 56A2373429F9C113003CCA5F /* SDL_sysrwlock.c in Sources */, - A7D8B96923E2514400DCD162 /* SDL_qsort.c in Sources */, - A7D8B55223E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, - A7D8B96323E2514400DCD162 /* SDL_strtokr.c in Sources */, - A7D8BB7623E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8BAB623E2514400DCD162 /* k_cos.c in Sources */, - A7D8B54623E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, - A7D8B97523E2514400DCD162 /* SDL_malloc.c in Sources */, - A7D8B8C723E2514400DCD162 /* SDL_audio.c in Sources */, - A7D8B61E23E2514300DCD162 /* SDL_sysfilesystem.c in Sources */, - A7D8AB8C23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */, - A7D8B42F23E2514300DCD162 /* SDL_syscond.c in Sources */, - A7D8AADB23E2514100DCD162 /* SDL_syshaptic.c in Sources */, - A7D8BAE623E2514500DCD162 /* e_exp.c in Sources */, - A7D8BB8223E2514500DCD162 /* SDL_quit.c in Sources */, - A7D8AEA723E2514100DCD162 /* SDL_cocoawindow.m in Sources */, - 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 */, - 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 */, - 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 */, - A75FDAAD23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, - A7D8BAAA23E2514400DCD162 /* k_sin.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 */, - A7D8A94C23E2514000DCD162 /* SDL.c in Sources */, - A7D8AEA123E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, - A7D8AC6423E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, - A7D8AB6223E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88C7823E24BED00DCD162 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 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 */, - A7D8A95323E2514000DCD162 /* SDL_spinlock.c in Sources */, - A7D8BAB123E2514400DCD162 /* s_atan.c in Sources */, - 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 */, - 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 */, - 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 */, - A7D8AB2723E2514100DCD162 /* SDL_log.c in Sources */, - A7D8AE8A23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, - A7D8AB7523E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C123E2514200DCD162 /* yuv_rgb.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 */, - A7D8B9DF23E2514400DCD162 /* SDL_blendpoint.c in Sources */, - A7D8B4F023E2514300DCD162 /* SDL_gamepad.c in Sources */, - A7D8AB3923E2514100DCD162 /* SDL_systimer.c in Sources */, - A7D8ACAD23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, - A7D8BA1523E2514400DCD162 /* SDL_render_sw.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 */, - 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 */, - 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 */, - 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 */, - F36C7AD3294BA009004D61C3 /* SDL_runapp.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 */, - A7D8AED823E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, - A7D8AB1823E2514100DCD162 /* SDL_dynapi.c in Sources */, - 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 */, - A7D8AEBA23E2514100DCD162 /* SDL_cocoamouse.m in Sources */, - A7D8B8E623E2514400DCD162 /* SDL_error.c in Sources */, - A7D8AD6A23E2514100DCD162 /* SDL_blit.c in Sources */, - 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 */, - 5616CA55252BB35B005D5928 /* SDL_url.c in Sources */, - 9846B07E287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, - A7D8B76023E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B5F523E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B95223E2514400DCD162 /* SDL_iconv.c in Sources */, - F31A92D428D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, - A7D8BA9F23E2514400DCD162 /* s_fabs.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 */, - A7D8BAE123E2514500DCD162 /* e_fmod.c in Sources */, - A7D8B5D123E2514300DCD162 /* SDL_syspower.m in Sources */, - A7D8BAED23E2514500DCD162 /* e_log10.c in Sources */, - A7D8AC7123E2514100DCD162 /* SDL_uikitopenglview.m in Sources */, - A7D8B76623E2514300DCD162 /* SDL_mixer.c in Sources */, - A7D8BB5923E2514500DCD162 /* SDL_events.c in Sources */, - A7D8ADE823E2514100DCD162 /* SDL_blit_0.c in Sources */, - A7D8BB0B23E2514500DCD162 /* k_tan.c in Sources */, - A75FDBD023EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - F386F6FB2884663E001840AA /* SDL_utils.c in Sources */, - A7D8B8AA23E2514400DCD162 /* SDL_diskaudio.c in Sources */, - A7D8AFC223E2514200DCD162 /* SDL_egl.c in Sources */, - A7D8AC3523E2514100DCD162 /* SDL_RLEaccel.c in Sources */, - A7D8BBB323E2514500DCD162 /* SDL_assert.c in Sources */, - A7D8B3DC23E2514300DCD162 /* SDL_bmp.c in Sources */, - A7D8B97023E2514400DCD162 /* SDL_stdlib.c in Sources */, - A7D8B79C23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, - A7D8B3A623E2514200DCD162 /* SDL_fillrect.c in Sources */, - A7D8ABE123E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, - 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 */, - A7D8AE9623E2514100DCD162 /* SDL_cocoamodes.m in Sources */, - A7D8BAA523E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B95823E2514400DCD162 /* SDL_getenv.c in Sources */, - A7D8B56523E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, - A7D8B4DE23E2514300DCD162 /* SDL_joystick.c in Sources */, - A7D8BA4B23E2514400DCD162 /* SDL_render_gles2.c in Sources */, - A7D8AC2F23E2514100DCD162 /* SDL_surface.c in Sources */, - A7D8B54D23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, - A7D8AD2523E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8BB6B23E2514500DCD162 /* SDL_keyboard.c in Sources */, - A7D8ACE923E2514100DCD162 /* SDL_rect.c in Sources */, - A7D8AE9C23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, - 56A2373529F9C113003CCA5F /* SDL_sysrwlock.c in Sources */, - A7D8B96A23E2514400DCD162 /* SDL_qsort.c in Sources */, - A7D8B55323E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, - A7D8B96423E2514400DCD162 /* SDL_strtokr.c in Sources */, - A7D8BB7723E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8BAB723E2514400DCD162 /* k_cos.c in Sources */, - A7D8B54723E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, - A7D8B97623E2514400DCD162 /* SDL_malloc.c in Sources */, - A7D8B8C823E2514400DCD162 /* SDL_audio.c in Sources */, - A7D8B61F23E2514300DCD162 /* SDL_sysfilesystem.c in Sources */, - A7D8AB8D23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */, - A7D8B43023E2514300DCD162 /* SDL_syscond.c in Sources */, - A7D8AADC23E2514100DCD162 /* SDL_syshaptic.c in Sources */, - A7D8BAE723E2514500DCD162 /* e_exp.c in Sources */, - A7D8BB8323E2514500DCD162 /* SDL_quit.c in Sources */, - A7D8AEA823E2514100DCD162 /* SDL_cocoawindow.m in Sources */, - 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 */, - 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 */, - 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 */, - A75FDAAE23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, - A7D8BAAB23E2514400DCD162 /* k_sin.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 */, - A7D8A94D23E2514000DCD162 /* SDL.c in Sources */, - A7D8AEA223E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, - A7D8AC6523E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, - A7D8AB6323E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A7D88DBC23E24D3B00DCD162 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A7D8B9E723E2514400DCD162 /* SDL_drawline.c in Sources */, - A7D8AE8023E2514100DCD162 /* SDL_yuv.c in Sources */, - A7D8B63323E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, - A7D8BACB23E2514500DCD162 /* e_pow.c in Sources */, - A7D8B42023E2514300DCD162 /* SDL_systls.c in Sources */, - A7D8AD2D23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */, - A7D8A95523E2514000DCD162 /* SDL_spinlock.c in Sources */, - A7D8BAB323E2514400DCD162 /* s_atan.c in Sources */, - A7D8B75623E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A75FDAAF23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, - A7D8B98A23E2514400DCD162 /* SDL_render_metal.m in Sources */, - A7D8AE7A23E2514100DCD162 /* SDL_clipboard.c in Sources */, - A7D8AEC823E2514100DCD162 /* SDL_cocoaevents.m 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 */, - 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 */, - A7D8AB2923E2514100DCD162 /* SDL_log.c in Sources */, - A7D8AE8C23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, - A7D8AB7723E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C323E2514200DCD162 /* yuv_rgb.c in Sources */, - A7D8B43823E2514300DCD162 /* SDL_systhread.c in Sources */, - A7D8BB3723E2514500DCD162 /* SDL_windowevents.c in Sources */, - A7D8BABF23E2514400DCD162 /* s_scalbn.c in Sources */, - A7D8AB2F23E2514100DCD162 /* SDL_timer.c in Sources */, - A7D8B9E123E2514400DCD162 /* SDL_blendpoint.c in Sources */, - A7D8B4F223E2514300DCD162 /* SDL_gamepad.c in Sources */, - A7D8AB3B23E2514100DCD162 /* SDL_systimer.c in Sources */, - A7D8ACAF23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, - A7D8BA1723E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B42623E2514300DCD162 /* SDL_syssem.c in Sources */, - A7D8B53D23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, - A7D8B8D623E2514400DCD162 /* SDL_coreaudio.m in Sources */, - A7D8BA2323E2514400DCD162 /* SDL_blendline.c in Sources */, - A7D8ADF623E2514100DCD162 /* SDL_blit_A.c in Sources */, - A7D8BA3B23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8ABEF23E2514100DCD162 /* SDL_nullvideo.c in Sources */, - A7D8AB6B23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, - A7D8ACA923E2514100DCD162 /* SDL_uikitview.m in Sources */, - A7D8ABF523E2514100DCD162 /* SDL_nullevents.c in Sources */, - A7D8B81C23E2514400DCD162 /* SDL_audiodev.c in Sources */, - A7D8AF1023E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */, - A7D8ABD123E2514100DCD162 /* SDL_blit_slow.c in Sources */, - A7D8BA9B23E2514400DCD162 /* s_copysign.c in Sources */, - A7D8AABA23E2514100DCD162 /* SDL_haptic.c in Sources */, - A7D8AC9123E2514100DCD162 /* SDL_uikitvulkan.m 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 */, - A7D8B9D523E2514400DCD162 /* SDL_yuv_sw.c in Sources */, - 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 */, - A7D8B76223E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B5F723E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B95423E2514400DCD162 /* SDL_iconv.c in Sources */, - A7D8BAA123E2514400DCD162 /* s_fabs.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 */, - A7D8BB0123E2514500DCD162 /* s_floor.c in Sources */, - A7D8AC3D23E2514100DCD162 /* SDL_blit_copy.c in Sources */, - A7D8BAE323E2514500DCD162 /* e_fmod.c in Sources */, - A7D8B5D323E2514300DCD162 /* SDL_syspower.m in Sources */, - A7D8BAEF23E2514500DCD162 /* e_log10.c in Sources */, - A7D8AC7323E2514100DCD162 /* SDL_uikitopenglview.m in Sources */, - A7D8B76823E2514300DCD162 /* SDL_mixer.c in Sources */, - A7D8BB5B23E2514500DCD162 /* SDL_events.c in Sources */, - A7D8ADEA23E2514100DCD162 /* SDL_blit_0.c in Sources */, - F36C7AD6294BA009004D61C3 /* SDL_runapp.c in Sources */, - A7D8BB0D23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B8AC23E2514400DCD162 /* SDL_diskaudio.c 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 */, - F3F07D5E269640160074468B /* SDL_hidapi_luna.c in Sources */, - A7D8B97223E2514400DCD162 /* SDL_stdlib.c in Sources */, - A7D8B79E23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, - A7D8B3A823E2514200DCD162 /* SDL_fillrect.c in Sources */, - A7D8ABE323E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, - A7D8A96D23E2514000DCD162 /* SDL_dummysensor.c in Sources */, - A7D8B96023E2514400DCD162 /* SDL_string.c in Sources */, - A7D8BA8323E2514400DCD162 /* SDL_render_gl.c in Sources */, - A7D8AC8523E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8AE9823E2514100DCD162 /* SDL_cocoamodes.m in Sources */, - A7D8BAA723E2514400DCD162 /* k_rem_pio2.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 */, - F395BF6925633B2400942BFF /* SDL_crc32.c in Sources */, - A7D8B54F23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, - A7D8AD2723E2514100DCD162 /* SDL_blit_auto.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 */, - A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, - F3984CD425BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, - A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */, - 56A2373729F9C113003CCA5F /* SDL_sysrwlock.c in Sources */, - 560572092473687900B46B66 /* SDL_syslocale.m in Sources */, - F3820717284F3609004DD584 /* controller_type.c in Sources */, - A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.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 */, - A7D8B62123E2514300DCD162 /* SDL_sysfilesystem.c in Sources */, - A75FDBD223EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - A7D8AB8F23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */, - 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 */, - 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 */, - 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 */, - A7D8BAAD23E2514400DCD162 /* k_sin.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 */, - 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; - }; BECDF62C0761BA81005FE872 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -8426,6 +2433,7 @@ A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */, 75E0915A241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8ABEB23E2514100DCD162 /* SDL_nullvideo.c in Sources */, + F3990E072A78833C000D8759 /* hid.m in Sources */, A7D8AB6723E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ABF123E2514100DCD162 /* SDL_nullevents.c in Sources */, A7D8B81823E2514400DCD162 /* SDL_audiodev.c in Sources */, @@ -8474,6 +2482,7 @@ A7D8BA9D23E2514400DCD162 /* s_fabs.c in Sources */, F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8B99223E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, + F3990DF52A787C10000D8759 /* SDL_sysurl.m in Sources */, A7D8B97A23E2514400DCD162 /* SDL_render.c in Sources */, A7D8ABD323E2514100DCD162 /* SDL_stretch.c in Sources */, A7D8BAFD23E2514500DCD162 /* s_floor.c in Sources */, @@ -8562,403 +2571,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BECDF6790761BA81005FE872 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A7D8B9E623E2514400DCD162 /* SDL_drawline.c in Sources */, - A7D8BBEE23E2574800DCD162 /* SDL_uikitappdelegate.m in Sources */, - 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 */, - 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 */, - 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 */, - A7D8AB2823E2514100DCD162 /* SDL_log.c in Sources */, - A7D8BC0223E2574800DCD162 /* SDL_uikitviewcontroller.m in Sources */, - A7D8AE8B23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, - A7D8AB7623E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - 5616CA58252BB35C005D5928 /* SDL_url.c in Sources */, - A7D8B3C223E2514200DCD162 /* yuv_rgb.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_gamepad.c in Sources */, - A7D8AB3A23E2514100DCD162 /* SDL_systimer.c in Sources */, - A7D8BA1623E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B42523E2514300DCD162 /* SDL_syssem.c in Sources */, - A7D8B53C23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, - A7D8B8D523E2514400DCD162 /* SDL_coreaudio.m in Sources */, - A7D8BA2223E2514400DCD162 /* SDL_blendline.c in Sources */, - A7D8BC0623E2574800DCD162 /* SDL_uikitwindow.m in Sources */, - A7D8ADF523E2514100DCD162 /* SDL_blit_A.c in Sources */, - A7D8BA3A23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8ABEE23E2514100DCD162 /* SDL_nullvideo.c in Sources */, - A7D8AB6A23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, - A7D8ABF423E2514100DCD162 /* SDL_nullevents.c in Sources */, - A7D8B81B23E2514400DCD162 /* SDL_audiodev.c in Sources */, - A7D8AF0F23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */, - A7D8ABD023E2514100DCD162 /* SDL_blit_slow.c in Sources */, - A7D8BA9A23E2514400DCD162 /* s_copysign.c in Sources */, - A7D8AAB923E2514100DCD162 /* SDL_haptic.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 */, - A7D8BB7E23E2514500DCD162 /* SDL_dropevents.c in Sources */, - A7D8BBFA23E2574800DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8BAD023E2514500DCD162 /* e_atan2.c in Sources */, - A7D8BA8E23E2514400DCD162 /* s_sin.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 */, - A7D8BA9423E2514400DCD162 /* s_cos.c in Sources */, - A7D8B9D423E2514400DCD162 /* SDL_yuv_sw.c in Sources */, - A7D8B76D23E2514300DCD162 /* SDL_wave.c in Sources */, - A7D8BAD623E2514500DCD162 /* s_tan.c in Sources */, - A7D8BBF423E2574800DCD162 /* SDL_uikitmessagebox.m in Sources */, - A7D8AA6823E2514000DCD162 /* SDL_hints.c in Sources */, - A7D8B54223E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, - A7D8AD7123E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B76123E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */, - 560572112473688100B46B66 /* SDL_locale.c in Sources */, - A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */, - A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m 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 */, - A7D8BAE223E2514500DCD162 /* e_fmod.c in Sources */, - A7D8B5D223E2514300DCD162 /* SDL_syspower.m in Sources */, - A7D8BBF623E2574800DCD162 /* SDL_uikitmetalview.m in Sources */, - A7D8BAEE23E2514500DCD162 /* e_log10.c in Sources */, - A7D8B76723E2514300DCD162 /* SDL_mixer.c in Sources */, - A7D8BB5A23E2514500DCD162 /* SDL_events.c in Sources */, - A7D8ADE923E2514100DCD162 /* SDL_blit_0.c in Sources */, - A7D8BB0C23E2514500DCD162 /* k_tan.c in Sources */, - A7D8BBF223E2574800DCD162 /* SDL_uikitevents.m in Sources */, - A7D8BBB923E2560500DCD162 /* SDL_steamcontroller.c in Sources */, - A7D8B8AB23E2514400DCD162 /* SDL_diskaudio.c in Sources */, - 56A2373629F9C113003CCA5F /* SDL_sysrwlock.c in Sources */, - A7D8AFC323E2514200DCD162 /* SDL_egl.c in Sources */, - A7D8AC3623E2514100DCD162 /* SDL_RLEaccel.c in Sources */, - A7D8BBB423E2514500DCD162 /* SDL_assert.c in Sources */, - A7D8B3DD23E2514300DCD162 /* SDL_bmp.c in Sources */, - 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 */, - A7D8AE9723E2514100DCD162 /* SDL_cocoamodes.m in Sources */, - A7D8BAA623E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B95923E2514400DCD162 /* SDL_getenv.c in Sources */, - A7D8B56623E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, - A7D8B4DF23E2514300DCD162 /* SDL_joystick.c in Sources */, - A7D8BA4C23E2514400DCD162 /* SDL_render_gles2.c in Sources */, - A7D8AC3023E2514100DCD162 /* SDL_surface.c in Sources */, - A7D8B54E23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, - A7D8AD2623E2514100DCD162 /* SDL_blit_auto.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 */, - A7D8B55423E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, - A7D8B96523E2514400DCD162 /* SDL_strtokr.c in Sources */, - A7D8BB7823E2514500DCD162 /* SDL_clipboardevents.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 */, - A7D8BAE823E2514500DCD162 /* e_exp.c in Sources */, - A7D8BBFE23E2574800DCD162 /* SDL_uikitvideo.m in Sources */, - 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 */, - A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, - 5605720A2473687900B46B66 /* SDL_syslocale.m in Sources */, - A7D8B14323E2514200DCD162 /* SDL_blit_1.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 */, - A7D8BAAC23E2514400DCD162 /* k_sin.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 */, - F36C7AD5294BA009004D61C3 /* SDL_runapp.c in Sources */, - A7D8AEAF23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, - A7D8A94E23E2514000DCD162 /* SDL.c in Sources */, - A7D8BBF823E2574800DCD162 /* SDL_uikitmodes.m in Sources */, - A7D8AEA323E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, - A7D8AB6423E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DB313FFD17554B71006C0E22 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A7D8B9E823E2514400DCD162 /* SDL_drawline.c in Sources */, - A7D8AE8123E2514100DCD162 /* SDL_yuv.c in Sources */, - 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 */, - 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 */, - 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 */, - A7D8AB2A23E2514100DCD162 /* SDL_log.c in Sources */, - A7D8AE8D23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, - A7D8AB7823E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C423E2514200DCD162 /* yuv_rgb.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_gamepad.c in Sources */, - A7D8AB3C23E2514100DCD162 /* SDL_systimer.c in Sources */, - A7D8ACB023E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, - A7D8BA1823E2514400DCD162 /* SDL_render_sw.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 */, - A7D8ABF023E2514100DCD162 /* SDL_nullvideo.c in Sources */, - A7D8AB6C23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, - A7D8ACAA23E2514100DCD162 /* SDL_uikitview.m in Sources */, - A7D8ABF623E2514100DCD162 /* SDL_nullevents.c in Sources */, - A7D8B81D23E2514400DCD162 /* SDL_audiodev.c in Sources */, - A7D8AF1123E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */, - A7D8ABD223E2514100DCD162 /* SDL_blit_slow.c in Sources */, - A7D8BA9C23E2514400DCD162 /* s_copysign.c in Sources */, - A7D8AABB23E2514100DCD162 /* SDL_haptic.c in Sources */, - A7D8AC9223E2514100DCD162 /* SDL_uikitvulkan.m 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 */, - A7D8ACBC23E2514100DCD162 /* SDL_uikitmodes.m in Sources */, - A7D8AD3723E2514100DCD162 /* SDL_blit_N.c in Sources */, - A7D8BB8023E2514500DCD162 /* SDL_dropevents.c in Sources */, - A7D8BAD223E2514500DCD162 /* e_atan2.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 */, - A7D8AD6D23E2514100DCD162 /* SDL_blit.c in Sources */, - A7D8B5C223E2514300DCD162 /* SDL_rwops.c in Sources */, - A7D8ACD423E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */, - A7D8BA9623E2514400DCD162 /* s_cos.c in Sources */, - A7D8B9D623E2514400DCD162 /* SDL_yuv_sw.c in Sources */, - A7D8B76F23E2514300DCD162 /* SDL_wave.c in Sources */, - A7D8BAD823E2514500DCD162 /* s_tan.c in Sources */, - A7D8AA6A23E2514000DCD162 /* SDL_hints.c in Sources */, - A7D8B54423E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, - A7D8AD7323E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */, - 560572142473688300B46B66 /* SDL_locale.c in Sources */, - A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */, - A7D8BAA223E2514400DCD162 /* s_fabs.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 */, - A7D8BB0223E2514500DCD162 /* s_floor.c in Sources */, - A7D8AC3E23E2514100DCD162 /* SDL_blit_copy.c in Sources */, - A7D8BAE423E2514500DCD162 /* e_fmod.c in Sources */, - A7D8B5D423E2514300DCD162 /* SDL_syspower.m in Sources */, - A7D8BAF023E2514500DCD162 /* e_log10.c in Sources */, - A7D8AC7423E2514100DCD162 /* SDL_uikitopenglview.m in Sources */, - A7D8B76923E2514300DCD162 /* SDL_mixer.c in Sources */, - A7D8BB5C23E2514500DCD162 /* SDL_events.c in Sources */, - A7D8ADEB23E2514100DCD162 /* SDL_blit_0.c in Sources */, - A7D8BB0E23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B8AD23E2514400DCD162 /* SDL_diskaudio.c in Sources */, - 56A2373929F9C113003CCA5F /* SDL_sysrwlock.c in Sources */, - A7D8AFC523E2514200DCD162 /* SDL_egl.c in Sources */, - A7D8AC3823E2514100DCD162 /* SDL_RLEaccel.c in Sources */, - A7D8BBB623E2514500DCD162 /* SDL_assert.c in Sources */, - A7D8B3DF23E2514300DCD162 /* SDL_bmp.c in Sources */, - 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 */, - A7D8AE9923E2514100DCD162 /* SDL_cocoamodes.m in Sources */, - A7D8BAA823E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B95B23E2514400DCD162 /* SDL_getenv.c in Sources */, - A7D8B56823E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, - A7D8B4E123E2514300DCD162 /* SDL_joystick.c in Sources */, - A7D8BA4E23E2514400DCD162 /* SDL_render_gles2.c in Sources */, - A7D8AC3223E2514100DCD162 /* SDL_surface.c in Sources */, - A7D8B55023E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, - A7D8AD2823E2514100DCD162 /* SDL_blit_auto.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 */, - A7D8B55623E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, - A7D8B96723E2514400DCD162 /* SDL_strtokr.c in Sources */, - A7D8BB7A23E2514500DCD162 /* SDL_clipboardevents.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 */, - A7D8BB8623E2514500DCD162 /* SDL_quit.c in Sources */, - A7D8AEAB23E2514100DCD162 /* SDL_cocoawindow.m in Sources */, - 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 */, - 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 */, - 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 */, - A7D8BAAE23E2514400DCD162 /* k_sin.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 */, - F36C7AD8294BA009004D61C3 /* SDL_runapp.c in Sources */, - A7D8AEB123E2514100DCD162 /* SDL_cocoavideo.m in Sources */, - A7D8A95023E2514000DCD162 /* SDL.c in Sources */, - A7D8AEA523E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, - A7D8AC6823E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, - A7D8AB6623E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - F3B38CF4296F6C8D005DA6D3 /* PBXTargetDependency */ = { + F3676F5D2A7885130091160D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = F3B38CEC296F63B6005DA6D3 /* SDL.xcframework */; - targetProxy = F3B38CF3296F6C8D005DA6D3 /* PBXContainerItemProxy */; + target = F3B38CEC296F63B6005DA6D3 /* SDL3.xcframework */; + targetProxy = F3676F5C2A7885130091160D /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -8966,28 +2585,9 @@ 00CFA621106A567900758660 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_POSTPROCESSING = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; DYLIB_CURRENT_VERSION = 1.0.0; @@ -9000,12 +2600,6 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_SYMBOLS_PRIVATE_EXTERN = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( ../../include, ../../src, @@ -9021,10 +2615,17 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.11; + MARKETING_VERSION = 3.0.0; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3; PRODUCT_NAME = SDL3; STRIP_STYLE = "non-global"; + SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Release; @@ -9033,50 +2634,17 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_LINK_OBJC_RUNTIME = NO; - MARKETING_VERSION = 3.0.0; OTHER_LDFLAGS = "-liconv"; - }; - name = Release; - }; - 00CFA623106A567900758660 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 00CFA625106A567900758660 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { + SUPPORTS_MACCATALYST = YES; }; name = Release; }; 00CFA627106A568900758660 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1.0.0; DYLIB_CURRENT_VERSION = 1.0.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -9088,12 +2656,6 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( ../../include, ../../src, @@ -9109,11 +2671,18 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.11; - ONLY_ACTIVE_ARCH = NO; + MARKETING_VERSION = 3.0.0; + ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3; PRODUCT_NAME = SDL3; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Debug; @@ -9122,215 +2691,39 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_LINK_OBJC_RUNTIME = NO; - MARKETING_VERSION = 3.0.0; OTHER_LDFLAGS = "-liconv"; + SUPPORTS_MACCATALYST = YES; }; name = Debug; }; - 00CFA629106A568900758660 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 00CFA62B106A568900758660 /* Debug */ = { + F3676F5A2A7885080091160D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Debug; }; - A75FCEB123E25AB700529352 /* Debug */ = { + F3676F5B2A7885080091160D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - EXECUTABLE_PREFIX = lib; - 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; - }; - A75FCEB223E25AB700529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - EXECUTABLE_PREFIX = lib; - 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; - }; - A75FD06A23E25AC700529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - EXECUTABLE_PREFIX = lib; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - INSTALL_PATH = "@rpath"; - SDKROOT = appletvos; - }; - name = Debug; - }; - A75FD06B23E25AC700529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - EXECUTABLE_PREFIX = lib; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - INSTALL_PATH = "@rpath"; - SDKROOT = appletvos; - }; - name = Release; - }; - A769B23B23E259AE00872273 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_LINK_OBJC_RUNTIME = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "appletvsimulator appletvos"; - }; - name = Debug; - }; - A769B23C23E259AE00872273 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_LINK_OBJC_RUNTIME = NO; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "appletvsimulator appletvos"; - }; - name = Release; - }; - A7D88B5223E2437C00DCD162 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_LINK_OBJC_RUNTIME = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", - ); - OTHER_LDFLAGS = "-liconv"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2,6"; - }; - name = Debug; - }; - A7D88B5323E2437C00DCD162 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_LINK_OBJC_RUNTIME = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", - ); - OTHER_LDFLAGS = "-liconv"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2,6"; - }; - name = Release; - }; - A7D88D1323E24BED00DCD162 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_LINK_OBJC_RUNTIME = NO; - OTHER_LDFLAGS = "-liconv"; - SDKROOT = appletvos; - }; - name = Debug; - }; - A7D88D1423E24BED00DCD162 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_LINK_OBJC_RUNTIME = NO; - OTHER_LDFLAGS = "-liconv"; - SDKROOT = appletvos; - }; - name = Release; - }; - A7D88E5223E24D3B00DCD162 /* Debug */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Debug; - }; - A7D88E5323E24D3B00DCD162 /* Release */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Release; - }; - DB31407517554B71006C0E22 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_PREFIX = lib; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - INSTALL_PATH = "@rpath"; - }; - name = Debug; - }; - DB31407617554B71006C0E22 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_PREFIX = lib; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; - INSTALL_PATH = "@rpath"; }; name = Release; }; F3B38CEE296F63B6005DA6D3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTS_MACCATALYST = YES; }; name = Debug; }; F3B38CEF296F63B6005DA6D3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTS_MACCATALYST = YES; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 0073177A0858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "Framework" */ = { + 0073177A0858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "SDL3" */ = { isa = XCConfigurationList; buildConfigurations = ( 00CFA628106A568900758660 /* Debug */, @@ -9339,24 +2732,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - 0073177E0858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "Static Library" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00CFA629106A568900758660 /* Debug */, - 00CFA623106A567900758660 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - 007317860858DB0500B2BC32 /* Build configuration list for PBXNativeTarget "Standard DMG" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00CFA62B106A568900758660 /* Debug */, - 00CFA625106A567900758660 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -9366,70 +2741,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - A75FCEB023E25AB700529352 /* Build configuration list for PBXNativeTarget "Shared Library-iOS" */ = { + F3676F592A7885080091160D /* Build configuration list for PBXAggregateTarget "SDL3.dmg" */ = { isa = XCConfigurationList; buildConfigurations = ( - A75FCEB123E25AB700529352 /* Debug */, - A75FCEB223E25AB700529352 /* Release */, + F3676F5A2A7885080091160D /* Debug */, + F3676F5B2A7885080091160D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - A75FD06923E25AC700529352 /* Build configuration list for PBXNativeTarget "Shared Library-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FD06A23E25AC700529352 /* Debug */, - A75FD06B23E25AC700529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A769B23A23E259AE00872273 /* Build configuration list for PBXNativeTarget "Static Library-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A769B23B23E259AE00872273 /* Debug */, - A769B23C23E259AE00872273 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A7D88B5123E2437C00DCD162 /* Build configuration list for PBXNativeTarget "Framework-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A7D88B5223E2437C00DCD162 /* Debug */, - A7D88B5323E2437C00DCD162 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A7D88D1223E24BED00DCD162 /* Build configuration list for PBXNativeTarget "Framework-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A7D88D1323E24BED00DCD162 /* Debug */, - A7D88D1423E24BED00DCD162 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A7D88E5123E24D3B00DCD162 /* Build configuration list for PBXNativeTarget "Static Library-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A7D88E5223E24D3B00DCD162 /* Debug */, - A7D88E5323E24D3B00DCD162 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - DB31407417554B71006C0E22 /* Build configuration list for PBXNativeTarget "Shared Library" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DB31407517554B71006C0E22 /* Debug */, - DB31407617554B71006C0E22 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - F3B38CED296F63B6005DA6D3 /* Build configuration list for PBXAggregateTarget "SDL.xcframework" */ = { + F3B38CED296F63B6005DA6D3 /* Build configuration list for PBXAggregateTarget "SDL3.xcframework" */ = { isa = XCConfigurationList; buildConfigurations = ( F3B38CEE296F63B6005DA6D3 /* Debug */, diff --git a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj index 991cbd97..2642bca1 100644 --- a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj +++ b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXAggregateTarget section */ @@ -13,6 +13,9 @@ buildPhases = ( ); dependencies = ( + F3E1F8032A78C3C500AC76D3 /* PBXTargetDependency */, + F3E1F8012A78C3BE00AC76D3 /* PBXTargetDependency */, + F3E1F7FF2A78C3AD00AC76D3 /* PBXTargetDependency */, F35E56E72983133F00A43A5F /* PBXTargetDependency */, DB0F490517CA5249008798C5 /* PBXTargetDependency */, DB0F490717CA5249008798C5 /* PBXTargetDependency */, @@ -38,7 +41,6 @@ 0017996C1074403E00F5D044 /* PBXTargetDependency */, 0017996E1074403E00F5D044 /* PBXTargetDependency */, 001799701074403E00F5D044 /* PBXTargetDependency */, - 001799721074403E00F5D044 /* PBXTargetDependency */, 001799741074403E00F5D044 /* PBXTargetDependency */, 001799761074403E00F5D044 /* PBXTargetDependency */, 001799781074403E00F5D044 /* PBXTargetDependency */, @@ -88,12 +90,11 @@ 453774A5120915E3002F0F45 /* testshape.c in Sources */ = {isa = PBXBuildFile; fileRef = 453774A4120915E3002F0F45 /* testshape.c */; }; 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 */; }; - BBFC08D0164C6876003E6A99 /* testgamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088E164C6820003E6A99 /* testgamepad.c */; }; + BBFC08D0164C6876003E6A99 /* testcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088E164C6820003E6A99 /* testcontroller.c */; }; BEC566B10761D90300A33029 /* checkkeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 092D6D10FFB30A2C7F000001 /* checkkeys.c */; }; BEC566CB0761D90300A33029 /* loopwave.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E4872006D84C97F000001 /* loopwave.c */; }; BEC567010761D90300A33029 /* testerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E4878006D85357F000001 /* testerror.c */; }; BEC567290761D90400A33029 /* testthread.c in Sources */ = {isa = PBXBuildFile; fileRef = 092D6D58FFB311A97F000001 /* testthread.c */; }; - BEC567360761D90400A33029 /* testjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 092D6D62FFB312AA7F000001 /* testjoystick.c */; }; BEC567430761D90400A33029 /* testkeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 092D6D6CFFB313437F000001 /* testkeys.c */; }; BEC567500761D90400A33029 /* testlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 092D6D75FFB313BB7F000001 /* testlock.c */; }; BEC567780761D90500A33029 /* testsem.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E487E006D86A17F000001 /* testsem.c */; }; @@ -112,27 +113,16 @@ DB166D9F16A1D1A500A1396C /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166D9016A1D1A500A1396C /* SDL_test_log.c */; }; DB166DA016A1D1A500A1396C /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166D9116A1D1A500A1396C /* SDL_test_md5.c */; }; DB166DA116A1D1A500A1396C /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166D9216A1D1A500A1396C /* SDL_test_random.c */; }; - DB166DA216A1D1E900A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; - DB166DA316A1D1FA00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; - DB166DA416A1D21700A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; - DB166DA716A1D24D00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; - 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 */; }; DB166DD716A1D37800A1396C /* testmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CBD16A1C74100A1396C /* testmessage.c */; }; DB166DDB16A1D42F00A1396C /* icon.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; - DB166DEA16A1D50C00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166DF016A1D52500A1396C /* testrelative.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CBF16A1C74100A1396C /* testrelative.c */; }; - DB166E0116A1D57C00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166E0716A1D59400A1396C /* testrendercopyex.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC016A1C74100A1396C /* testrendercopyex.c */; }; - 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 */; }; DB166E3C16A1D66500A1396C /* testrumble.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC216A1C74100A1396C /* testrumble.c */; }; - 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 */; }; @@ -142,14 +132,8 @@ 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 */; }; - DB445EF418184B7000B306B0 /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB445EFB18184BB600B306B0 /* testdropfile.c in Sources */ = {isa = PBXBuildFile; fileRef = DB445EFA18184BB600B306B0 /* testdropfile.c */; }; DB89958418A19B130092407C /* testhotplug.c in Sources */ = {isa = PBXBuildFile; fileRef = DB89958318A19B130092407C /* testhotplug.c */; }; - DBEC54EB1A1A8205005B1EAB /* gamepadmap.c in Sources */ = {isa = PBXBuildFile; fileRef = DBEC54D11A1A811D005B1EAB /* gamepadmap.c */; }; - DBEC54ED1A1A828A005B1EAB /* axis.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBEC54D61A1A8145005B1EAB /* axis.bmp */; }; - DBEC54EE1A1A828D005B1EAB /* button.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBEC54D71A1A8145005B1EAB /* button.bmp */; }; - DBEC54EF1A1A828F005B1EAB /* gamepadmap.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBEC54D81A1A8145005B1EAB /* gamepadmap.bmp */; }; - F35E56A6298312CB00A43A5F /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; F35E56CF2983130F00A43A5F /* testautomation_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F35E56B62983130A00A43A5F /* testautomation_main.c */; }; F35E56D02983130F00A43A5F /* testautomation_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = F35E56B72983130A00A43A5F /* testautomation_hints.c */; }; F35E56D12983130F00A43A5F /* testautomation_render.c in Sources */ = {isa = PBXBuildFile; fileRef = F35E56B82983130A00A43A5F /* testautomation_render.c */; }; @@ -173,9 +157,11 @@ F35E56E32983130F00A43A5F /* testautomation_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = F35E56CB2983130F00A43A5F /* testautomation_surface.c */; }; F35E56E42983130F00A43A5F /* testautomation.c in Sources */ = {isa = PBXBuildFile; fileRef = F35E56CC2983130F00A43A5F /* testautomation.c */; }; F35E56E52983130F00A43A5F /* testautomation_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = F35E56CD2983130F00A43A5F /* testautomation_mouse.c */; }; - 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 /* gamepadmap_back.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = F3C17C7528E40B6B00E1A26D /* gamepadmap_back.bmp */; }; + F399C64E2A78929400C86979 /* gamepadutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6492A78929400C86979 /* gamepadutils.c */; }; + F399C64F2A78929400C86979 /* gamepadutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6492A78929400C86979 /* gamepadutils.c */; }; + F399C6512A7892D800C86979 /* testautomation_intrinsics.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6502A7892D800C86979 /* testautomation_intrinsics.c */; }; + F399C6522A7892D800C86979 /* testautomation_intrinsics.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6502A7892D800C86979 /* testautomation_intrinsics.c */; }; + F399C6552A78933100C86979 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F399C6542A78933000C86979 /* Cocoa.framework */; }; F3C17C7728E40BC800E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; F3C17C7928E40C6E00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; F3C17C7B28E40D4E00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; @@ -191,13 +177,98 @@ 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 */; }; 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 /* gamepadmap_back.bmp in Resources */ = {isa = PBXBuildFile; fileRef = F3C17C7528E40B6B00E1A26D /* gamepadmap_back.bmp */; }; - F3C17D3F28E4277D00E1A26D /* gamepadmap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = DBEC54D81A1A8145005B1EAB /* gamepadmap.bmp */; }; + F3CB56892A7895F800766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB568A2A7895F800766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB568C2A7896BF00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB568D2A7896BF00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56902A7896F900766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56912A7896F900766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56932A78971600766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56942A78971600766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56962A78971F00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56972A78971F00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56992A78972700766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB569A2A78972700766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB569C2A78972F00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB569D2A78972F00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB569F2A78973700766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56A02A78973700766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56A22A78974000766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56A32A78974000766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56A52A78974800766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56A62A78974800766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56A82A78975100766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56A92A78975100766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56AB2A78975A00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56AC2A78975A00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56AE2A78976200766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56AF2A78976200766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56B12A78976800766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56B22A78976800766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56B42A78977000766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56B52A78977000766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56B72A78977D00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56B82A78977D00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56BA2A78978700766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56BB2A78978700766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56BD2A78979000766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56BE2A78979000766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56C02A78979600766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56C12A78979600766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56C32A78979C00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56C42A78979C00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56C62A7897A500766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56C72A7897A500766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56C92A7897AE00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56CA2A7897AE00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56CC2A7897B500766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56CD2A7897B500766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56CF2A7897BE00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56D02A7897BE00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56D22A7897C600766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56D32A7897C600766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56D52A7897CD00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56D62A7897CD00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56D92A7897E200766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56DA2A7897E200766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56DC2A7897E900766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56DD2A7897E900766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56DF2A7897F000766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56E02A7897F000766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56E22A7897F800766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56E32A7897F800766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56E52A7897FE00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56E62A7897FE00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56E82A78980600766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56E92A78980600766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56EB2A78980D00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56EC2A78980D00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56EE2A78981500766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56EF2A78981500766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56F12A78981C00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56F22A78981C00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56F42A78982300766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56F52A78982300766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56F72A78982B00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56F82A78982B00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56FA2A78983200766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56FB2A78983200766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB56FD2A78983C00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB56FE2A78983C00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB57002A78984300766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB57012A78984300766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB57032A78984A00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB57042A78984A00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB57062A78985400766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB57072A78985400766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB57092A78985A00766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB570A2A78985A00766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB570C2A78986000766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB570D2A78986000766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3CB570F2A78986700766177 /* SDL3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; }; + F3CB57102A78986700766177 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -292,13 +363,6 @@ remoteGlobalIDString = 001797961074334C00F5D044; remoteInfo = testintersections; }; - 001799711074403E00F5D044 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = BEC567300761D90400A33029; - remoteInfo = testjoystick; - }; 001799731074403E00F5D044 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -411,20 +475,6 @@ remoteGlobalIDString = BECDF66C0761BA81005FE872; remoteInfo = Framework; }; - 003FA644093FFD41000C53B3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = BECDF6B30761BA81005FE872; - remoteInfo = "Static Library"; - }; - 003FA648093FFD41000C53B3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = BECDF6BE0761BA81005FE872; - remoteInfo = "Standard DMG"; - }; DB0F490417CA5249008798C5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -444,7 +494,7 @@ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = BBFC08B7164C6862003E6A99; - remoteInfo = testgamepad; + remoteInfo = testcontroller; }; DB166D6F16A1CEAF00A1396C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -516,13 +566,6 @@ remoteGlobalIDString = DB166E8016A1D78C00A1396C; remoteInfo = teststreaming; }; - DB1D40D617B3F30D00D74CFC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = DB31407717554B71006C0E22; - remoteInfo = "Shared Library"; - }; F35E56E62983133F00A43A5F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -530,47 +573,26 @@ remoteGlobalIDString = F35E56A2298312CB00A43A5F; remoteInfo = testautomation; }; - F3C17C5C28E3FB2900E1A26D /* PBXContainerItemProxy */ = { + F3E1F7FE2A78C3AD00AC76D3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A7D88B5423E2437C00DCD162; - remoteInfo = "Framework-iOS"; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DB89956D18A19ABA0092407C; + remoteInfo = testhotplug; }; - F3C17C5E28E3FB2900E1A26D /* PBXContainerItemProxy */ = { + F3E1F8002A78C3BE00AC76D3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = A7D88D1523E24BED00DCD162; - remoteInfo = "Framework-tvOS"; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DB445EE618184B7000B306B0; + remoteInfo = testdropfile; }; - F3C17C6228E3FB2900E1A26D /* PBXContainerItemProxy */ = { + F3E1F8022A78C3C500AC76D3 /* 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"; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F3C17CDB28E416CF00E1A26D; + remoteInfo = testgeometry; }; /* End PBXContainerItemProxy section */ @@ -678,60 +700,542 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DBEC54EC1A1A827C005B1EAB /* CopyFiles */ = { + F3CB568B2A7895F800766177 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 7; + dstSubfolderSpec = 10; files = ( - DBEC54ED1A1A828A005B1EAB /* axis.bmp in CopyFiles */, - DBEC54EE1A1A828D005B1EAB /* button.bmp in CopyFiles */, - DBEC54EF1A1A828F005B1EAB /* gamepadmap.bmp in CopyFiles */, - F3C17C7628E40BA200E1A26D /* gamepadmap_back.bmp in CopyFiles */, + F3CB568A2A7895F800766177 /* SDL3.framework in Embed Frameworks */, ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB568E2A7896BF00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB568D2A7896BF00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56922A7896F900766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56912A7896F900766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56952A78971600766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56942A78971600766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56982A78971F00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56972A78971F00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB569B2A78972700766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB569A2A78972700766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB569E2A78973000766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB569D2A78972F00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56A12A78973700766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56A02A78973700766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56A42A78974000766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56A32A78974000766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56A72A78974800766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56A62A78974800766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56AA2A78975100766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56A92A78975100766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56AD2A78975A00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56AC2A78975A00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56B02A78976200766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56AF2A78976200766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56B32A78976900766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56B22A78976800766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56B62A78977000766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56B52A78977000766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56B92A78977D00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56B82A78977D00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56BC2A78978800766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56BB2A78978700766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56BF2A78979000766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56BE2A78979000766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56C22A78979600766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56C12A78979600766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56C52A78979C00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56C42A78979C00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56C82A7897A500766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56C72A7897A500766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56CB2A7897AE00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56CA2A7897AE00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56CE2A7897B500766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56CD2A7897B500766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56D12A7897BE00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56D02A7897BE00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56D42A7897C600766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56D32A7897C600766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56D72A7897CE00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56D62A7897CD00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56DB2A7897E200766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56DA2A7897E200766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56DE2A7897E900766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56DD2A7897E900766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56E12A7897F000766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56E02A7897F000766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56E42A7897F800766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56E32A7897F800766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56E72A7897FE00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56E62A7897FE00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56EA2A78980600766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56E92A78980600766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56ED2A78980D00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56EC2A78980D00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56F02A78981500766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56EF2A78981500766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56F32A78981C00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56F22A78981C00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56F62A78982400766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56F52A78982300766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56F92A78982B00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56F82A78982B00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56FC2A78983200766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56FB2A78983200766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB56FF2A78983C00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB56FE2A78983C00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB57022A78984300766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB57012A78984300766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB57052A78984A00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB57042A78984A00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB57082A78985400766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB57072A78985400766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB570B2A78985A00766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB570A2A78985A00766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB570E2A78986000766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB570D2A78986000766177 /* SDL3.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3CB57112A78986700766177 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3CB57102A78986700766177 /* SDL3.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; name = testatomic; path = testatomic.app; 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; name = testaudioinfo; path = testaudioinfo.app; 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 /* testgl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgl.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017972710742FB900F5D044 /* testgl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testgl.c; sourceTree = ""; }; - 00179748107430D600F5D044 /* testhaptic */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testhaptic; path = testhaptic.app; 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 /* testdraw */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testdraw; path = testdraw.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017976E107431B300F5D044 /* testdraw.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testdraw.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001797711074320D00F5D044 /* testdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testdraw.c; sourceTree = ""; }; - 0017978E107432AE00F5D044 /* testime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testime; path = testime.app; 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; name = testintersections; path = testintersections.app; 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; name = testloadso; path = testloadso.app; 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; name = testmultiaudio; path = testmultiaudio.app; 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.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testnative.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 001798B5107439DF00F5D044 /* testpower */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testpower; path = testpower.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; name = testresample; path = testresample.app; 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 /* testsprite */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testsprite; path = testsprite.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017991610743F1000F5D044 /* testsprite.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testsprite.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017991910743F5300F5D044 /* testsprite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testsprite.c; sourceTree = ""; }; - 0017993810743FB700F5D044 /* testwm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testwm; path = testwm.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017993810743FB700F5D044 /* testwm.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testwm.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017993B10743FEF00F5D044 /* testwm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testwm.c; sourceTree = ""; }; - 002F341209CA1BFF00EBEB88 /* testfile */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testfile; path = testfile.app; 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; name = testiconv; path = testiconv.app; 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 /* testoverlay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testoverlay; path = testoverlay.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 002F344D09CA1FB300EBEB88 /* testoverlay.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testoverlay.app; sourceTree = BUILT_PRODUCTS_DIR; }; 002F345209CA201C00EBEB88 /* testoverlay.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testoverlay.c; sourceTree = ""; }; - 002F346A09CA204F00EBEB88 /* testplatform */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testplatform; path = testplatform.app; 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 = ""; }; @@ -748,30 +1252,28 @@ 083E4887006D86A17F000001 /* torturethread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = torturethread.c; sourceTree = ""; }; 092D6D10FFB30A2C7F000001 /* checkkeys.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = checkkeys.c; sourceTree = ""; }; 092D6D58FFB311A97F000001 /* testthread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testthread.c; sourceTree = ""; }; - 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; name = testshape; path = testshape.app; 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 = ""; }; 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 /* testgamepad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testgamepad.c; sourceTree = ""; }; - BBFC08CD164C6862003E6A99 /* testgamepad */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testgamepad; path = testgamepad.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC566B60761D90300A33029 /* checkkeys */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = checkkeys; path = checkkeys.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC566D10761D90300A33029 /* loopwave */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = loopwave; path = loopwave.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567060761D90400A33029 /* testerror */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testerror; path = testerror.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC5672E0761D90400A33029 /* testthread */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testthread; path = testthread.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC5673B0761D90400A33029 /* testjoystick */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testjoystick; path = testjoystick.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567480761D90400A33029 /* testkeys */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testkeys; path = testkeys.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567550761D90400A33029 /* testlock */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testlock; path = testlock.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC5677D0761D90500A33029 /* testsem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testsem; path = testsem.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567980761D90500A33029 /* testtimer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testtimer; path = testtimer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567B20761D90500A33029 /* testversion */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testversion; path = testversion.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567F50761D90600A33029 /* torturethread */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = torturethread; path = torturethread.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BBFC088E164C6820003E6A99 /* testcontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testcontroller.c; sourceTree = ""; }; + BBFC08CD164C6862003E6A99 /* testcontroller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testcontroller.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; }; + 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; name = testdrawchessboard; path = testdrawchessboard.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB0F490117CA5212008798C5 /* testfilesystem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testfilesystem; path = testfilesystem.app; 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; }; 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 = ""; }; DB166CBF16A1C74100A1396C /* testrelative.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testrelative.c; sourceTree = ""; }; @@ -782,7 +1284,7 @@ DB166CC416A1C74100A1396C /* testshader.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testshader.c; sourceTree = ""; }; DB166CC516A1C74100A1396C /* testspriteminimal.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testspriteminimal.c; sourceTree = ""; }; DB166CC616A1C74100A1396C /* teststreaming.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = teststreaming.c; sourceTree = ""; }; - DB166D7F16A1D12400A1396C /* libSDL_test.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL_test.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166D7F16A1D12400A1396C /* libSDL3_test.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL3_test.a; sourceTree = BUILT_PRODUCTS_DIR; }; DB166D8416A1D1A500A1396C /* SDL_test_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_assert.c; sourceTree = ""; }; DB166D8516A1D1A500A1396C /* SDL_test_common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_common.c; sourceTree = ""; }; DB166D8616A1D1A500A1396C /* SDL_test_compare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_compare.c; sourceTree = ""; }; @@ -793,26 +1295,20 @@ 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 = ""; }; - DB166DD516A1D36A00A1396C /* testmessage */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testmessage; path = testmessage.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166DEE16A1D50C00A1396C /* testrelative */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testrelative; path = testrelative.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E0516A1D57C00A1396C /* testrendercopyex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testrendercopyex; path = testrendercopyex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E1C16A1D5AD00A1396C /* testrendertarget */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testrendertarget; path = testrendertarget.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E3816A1D64D00A1396C /* testrumble */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testrumble; path = testrumble.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E5216A1D69000A1396C /* testscale */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testscale; path = testscale.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E6816A1D6F300A1396C /* testshader */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testshader; path = testshader.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E7E16A1D78400A1396C /* testspriteminimal */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = testspriteminimal; path = testspriteminimal.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E9116A1D78C00A1396C /* teststreaming */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = teststreaming; path = teststreaming.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; name = testhotplug; path = testhotplug.app; 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 /* gamepadmap.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gamepadmap.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 /* gamepadmap.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = gamepadmap.bmp; sourceTree = ""; }; - DBEC54EA1A1A81C3005B1EAB /* gamepadmap */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = gamepadmap; path = gamepadmap.app; sourceTree = BUILT_PRODUCTS_DIR; }; F35E56AA298312CB00A43A5F /* testautomation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testautomation.app; sourceTree = BUILT_PRODUCTS_DIR; }; F35E56B62983130A00A43A5F /* testautomation_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_main.c; sourceTree = ""; }; F35E56B72983130A00A43A5F /* testautomation_hints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_hints.c; sourceTree = ""; }; @@ -837,9 +1333,11 @@ F35E56CB2983130F00A43A5F /* testautomation_surface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_surface.c; sourceTree = ""; }; F35E56CC2983130F00A43A5F /* testautomation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation.c; sourceTree = ""; }; F35E56CD2983130F00A43A5F /* testautomation_mouse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_mouse.c; sourceTree = ""; }; + F399C6492A78929400C86979 /* gamepadutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gamepadutils.c; sourceTree = ""; }; + F399C6502A7892D800C86979 /* testautomation_intrinsics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_intrinsics.c; sourceTree = ""; }; + F399C6542A78933000C86979 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 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 /* gamepadmap_back.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = gamepadmap_back.bmp; 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 */ @@ -849,6 +1347,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56932A78971600766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -856,6 +1355,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56962A78971F00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -863,7 +1363,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DA316A1D1FA00A1396C /* libSDL_test.a in Frameworks */, + F3CB56B42A78977000766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -871,6 +1371,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56B72A78977D00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -878,7 +1379,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DA216A1D1E900A1396C /* libSDL_test.a in Frameworks */, + F3CB569F2A78973700766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -886,7 +1387,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DA716A1D24D00A1396C /* libSDL_test.a in Frameworks */, + F3CB56C02A78979600766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -894,7 +1395,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DAA16A1D27700A1396C /* libSDL_test.a in Frameworks */, + F3CB56C32A78979C00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -902,6 +1403,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56C92A7897AE00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -909,6 +1411,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56D22A7897C600766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -916,6 +1419,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56D52A7897CD00766177 /* SDL3.framework in Frameworks */, + F399C6552A78933100C86979 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -923,6 +1428,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56DF2A7897F000766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -930,6 +1436,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56EB2A78980D00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -937,7 +1444,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DAB16A1D27C00A1396C /* libSDL_test.a in Frameworks */, + F3CB56892A7895F800766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -945,7 +1452,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DAC16A1D29000A1396C /* libSDL_test.a in Frameworks */, + F3CB570C2A78986000766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -953,6 +1460,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56AB2A78975A00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -960,6 +1468,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56BD2A78979000766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -967,6 +1476,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56D92A7897E200766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -974,6 +1484,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56DC2A7897E900766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -981,7 +1492,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DA416A1D21700A1396C /* libSDL_test.a in Frameworks */, + F3CB56FA2A78983200766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -989,6 +1500,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB569C2A78972F00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -996,7 +1508,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F3C17C6B28E4022A00E1A26D /* libSDL_test.a in Frameworks */, + F3CB568C2A7896BF00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1004,6 +1516,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56902A7896F900766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1011,6 +1524,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56A82A78975100766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1018,13 +1532,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BEC567370761D90400A33029 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( + F3CB57032A78984A00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1032,6 +1540,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56C62A7897A500766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1039,6 +1548,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56CC2A7897B500766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1046,6 +1556,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56F42A78982300766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1053,6 +1564,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB57062A78985400766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1060,6 +1572,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB57092A78985A00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1067,6 +1580,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB570F2A78986700766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1074,6 +1588,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56A22A78974000766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1081,6 +1596,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56AE2A78976200766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1095,6 +1611,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56CF2A7897BE00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1102,7 +1619,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166DEA16A1D50C00A1396C /* libSDL_test.a in Frameworks */, + F3CB56E22A7897F800766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1110,7 +1627,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166E0116A1D57C00A1396C /* libSDL_test.a in Frameworks */, + F3CB56E52A7897FE00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1118,7 +1635,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166E1816A1D5AD00A1396C /* libSDL_test.a in Frameworks */, + F3CB56E82A78980600766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1126,6 +1643,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56EE2A78981500766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1133,7 +1651,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB166E4B16A1D69000A1396C /* libSDL_test.a in Frameworks */, + F3CB56F12A78981C00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1141,6 +1659,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56F72A78982B00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1148,6 +1667,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB56FD2A78983C00766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1155,6 +1675,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F3CB57002A78984300766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1162,7 +1683,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DB445EF418184B7000B306B0 /* libSDL_test.a in Frameworks */, + F3CB56A52A78974800766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1170,13 +1691,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DBEC54DC1A1A81C3005B1EAB /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( + F3CB56BA2A78978700766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1184,7 +1699,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F35E56A6298312CB00A43A5F /* libSDL_test.a in Frameworks */, + F3CB56992A78972700766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1192,7 +1707,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F3C17CED28E417F400E1A26D /* libSDL_test.a in Frameworks */, + F3CB56B12A78976800766177 /* SDL3.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1203,15 +1718,6 @@ isa = PBXGroup; children = ( 003FA643093FFD41000C53B3 /* SDL3.framework */, - F3C17C5D28E3FB2900E1A26D /* SDL3.framework */, - F3C17C5F28E3FB2900E1A26D /* SDL3.framework */, - 003FA645093FFD41000C53B3 /* libSDL3.a */, - F3C17C6328E3FB2900E1A26D /* libSDL3.a */, - F3C17C6528E3FB2900E1A26D /* libSDL3.a */, - DB1D40D717B3F30D00D74CFC /* libSDL3.dylib */, - F3C17C6728E3FB2900E1A26D /* libSDL3.dylib */, - F3C17C6928E3FB2900E1A26D /* libSDL3.dylib */, - 003FA649093FFD41000C53B3 /* SDL3 */, ); name = Products; sourceTree = ""; @@ -1219,17 +1725,12 @@ 00794E4609D207B4003FC8A1 /* Resources */ = { isa = PBXGroup; children = ( - DBEC54D61A1A8145005B1EAB /* axis.bmp */, - DBEC54D71A1A8145005B1EAB /* button.bmp */, - F3C17C7528E40B6B00E1A26D /* gamepadmap_back.bmp */, - DBEC54D81A1A8145005B1EAB /* gamepadmap.bmp */, 00794E5D09D20839003FC8A1 /* icon.bmp */, 00794E5E09D20839003FC8A1 /* moose.dat */, 00794E5F09D20839003FC8A1 /* picture.xbm */, 00794E6109D20839003FC8A1 /* sample.bmp */, 00794E6209D20839003FC8A1 /* sample.wav */, DB166ECF16A1D87000A1396C /* shapes */, - DBBC552C182831D700F3CA8D /* TestDropFile-Info.plist */, 00794E6309D20839003FC8A1 /* utf8.txt */, ); name = Resources; @@ -1245,6 +1746,7 @@ DB166D8316A1D17E00A1396C /* SDL_Test */, 00794E4609D207B4003FC8A1 /* Resources */, 1AB674ADFE9D54B511CA2CBB /* Products */, + F399C6532A78933000C86979 /* 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; @@ -1254,7 +1756,7 @@ isa = PBXGroup; children = ( 092D6D10FFB30A2C7F000001 /* checkkeys.c */, - DBEC54D11A1A811D005B1EAB /* gamepadmap.c */, + F399C6492A78929400C86979 /* gamepadutils.c */, 083E4872006D84C97F000001 /* loopwave.c */, 0017958F1074216E00F5D044 /* testatomic.c */, 001795B01074222D00F5D044 /* testaudioinfo.c */, @@ -1264,6 +1766,7 @@ F35E56C92983130E00A43A5F /* testautomation_guid.c */, F35E56B72983130A00A43A5F /* testautomation_hints.c */, F35E56BF2983130C00A43A5F /* testautomation_images.c */, + F399C6502A7892D800C86979 /* testautomation_intrinsics.c */, F35E56C62983130D00A43A5F /* testautomation_joystick.c */, F35E56C72983130E00A43A5F /* testautomation_keyboard.c */, F35E56B62983130A00A43A5F /* testautomation_main.c */, @@ -1281,13 +1784,13 @@ F35E56BD2983130B00A43A5F /* testautomation_timer.c */, F35E56C12983130C00A43A5F /* testautomation_video.c */, F35E56CC2983130F00A43A5F /* testautomation.c */, + BBFC088E164C6820003E6A99 /* testcontroller.c */, 001797711074320D00F5D044 /* testdraw.c */, DB0F48D717CA51D2008798C5 /* testdrawchessboard.c */, DB445EFA18184BB600B306B0 /* testdropfile.c */, 083E4878006D85357F000001 /* testerror.c */, 002F341709CA1C5B00EBEB88 /* testfile.c */, DB0F48D817CA51D2008798C5 /* testfilesystem.c */, - BBFC088E164C6820003E6A99 /* testgamepad.c */, F3C17CD628E416AC00E1A26D /* testgeometry.c */, 0017972710742FB900F5D044 /* testgl.c */, DB166CBC16A1C74100A1396C /* testgles.c */, @@ -1296,7 +1799,6 @@ 002F343609CA1F6F00EBEB88 /* testiconv.c */, 00179791107432FA00F5D044 /* testime.c */, 001797B31074339C00F5D044 /* testintersections.c */, - 092D6D62FFB312AA7F000001 /* testjoystick.c */, 092D6D6CFFB313437F000001 /* testkeys.c */, 001797D31074343E00F5D044 /* testloadso.c */, 092D6D75FFB313BB7F000001 /* testlock.c */, @@ -1336,52 +1838,50 @@ 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 /* testoverlay */, - 002F346A09CA204F00EBEB88 /* testplatform */, - 0017958C10741F7900F5D044 /* testatomic */, - 001795AD107421BF00F5D044 /* testaudioinfo */, + BEC566B60761D90300A33029 /* checkkeys.app */, + BEC566D10761D90300A33029 /* loopwave.app */, + BEC567060761D90400A33029 /* testerror.app */, + BEC5672E0761D90400A33029 /* testthread.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 /* testoverlay.app */, + 002F346A09CA204F00EBEB88 /* testplatform.app */, + 0017958C10741F7900F5D044 /* testatomic.app */, + 001795AD107421BF00F5D044 /* testaudioinfo.app */, 0017972110742F3200F5D044 /* testgl.app */, - 00179748107430D600F5D044 /* testhaptic */, - 0017976E107431B300F5D044 /* testdraw */, - 0017978E107432AE00F5D044 /* testime */, - 001797AE1074334C00F5D044 /* testintersections */, - 001797D0107433C600F5D044 /* testloadso */, - 001798121074355200F5D044 /* testmultiaudio */, + 00179748107430D600F5D044 /* testhaptic.app */, + 0017976E107431B300F5D044 /* testdraw.app */, + 0017978E107432AE00F5D044 /* testime.app */, + 001797AE1074334C00F5D044 /* testintersections.app */, + 001797D0107433C600F5D044 /* testloadso.app */, + 001798121074355200F5D044 /* testmultiaudio.app */, 001798941074392D00F5D044 /* testnative.app */, - 001798B5107439DF00F5D044 /* testpower */, - 001798F210743BEC00F5D044 /* testresample */, - 0017991610743F1000F5D044 /* testsprite */, - 0017993810743FB700F5D044 /* testwm */, - 4537749212091504002F0F45 /* testshape */, - BBFC08CD164C6862003E6A99 /* testgamepad */, - DB166D7F16A1D12400A1396C /* libSDL_test.a */, - DB166DD516A1D36A00A1396C /* testmessage */, - DB166DEE16A1D50C00A1396C /* testrelative */, - DB166E0516A1D57C00A1396C /* testrendercopyex */, - DB166E1C16A1D5AD00A1396C /* testrendertarget */, - DB166E3816A1D64D00A1396C /* testrumble */, - DB166E5216A1D69000A1396C /* testscale */, - DB166E6816A1D6F300A1396C /* testshader */, - DB166E7E16A1D78400A1396C /* testspriteminimal */, - DB166E9116A1D78C00A1396C /* teststreaming */, - DB0F48EC17CA51E5008798C5 /* testdrawchessboard */, - DB0F490117CA5212008798C5 /* testfilesystem */, - DB89957E18A19ABA0092407C /* testhotplug */, + 001798B5107439DF00F5D044 /* testpower.app */, + 001798F210743BEC00F5D044 /* testresample.app */, + 0017991610743F1000F5D044 /* testsprite.app */, + 0017993810743FB700F5D044 /* testwm.app */, + 4537749212091504002F0F45 /* testshape.app */, + BBFC08CD164C6862003E6A99 /* testcontroller.app */, + DB166D7F16A1D12400A1396C /* libSDL3_test.a */, + 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 /* gamepadmap */, F3C17CDC28E416CF00E1A26D /* testgeometry.app */, F35E56AA298312CB00A43A5F /* testautomation.app */, ); @@ -1407,6 +1907,14 @@ path = ../../src/test; sourceTree = ""; }; + F399C6532A78933000C86979 /* Frameworks */ = { + isa = PBXGroup; + children = ( + F399C6542A78933000C86979 /* Cocoa.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1426,6 +1934,7 @@ buildPhases = ( 0017957910741F7900F5D044 /* Sources */, 0017957A10741F7900F5D044 /* Frameworks */, + F3CB56952A78971600766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1433,7 +1942,7 @@ ); name = testatomic; productName = testalpha; - productReference = 0017958C10741F7900F5D044 /* testatomic */; + productReference = 0017958C10741F7900F5D044 /* testatomic.app */; productType = "com.apple.product-type.application"; }; 00179595107421BF00F5D044 /* testaudioinfo */ = { @@ -1442,6 +1951,7 @@ buildPhases = ( 0017959A107421BF00F5D044 /* Sources */, 0017959B107421BF00F5D044 /* Frameworks */, + F3CB56982A78971F00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1449,7 +1959,7 @@ ); name = testaudioinfo; productName = testalpha; - productReference = 001795AD107421BF00F5D044 /* testaudioinfo */; + productReference = 001795AD107421BF00F5D044 /* testaudioinfo.app */; productType = "com.apple.product-type.application"; }; 0017970910742F3200F5D044 /* testgl */ = { @@ -1458,6 +1968,7 @@ buildPhases = ( 0017970E10742F3200F5D044 /* Sources */, 0017970F10742F3200F5D044 /* Frameworks */, + F3CB56B62A78977000766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1474,6 +1985,7 @@ buildPhases = ( 00179735107430D600F5D044 /* Sources */, 00179736107430D600F5D044 /* Frameworks */, + F3CB56B92A78977D00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1481,7 +1993,7 @@ ); name = testhaptic; productName = testalpha; - productReference = 00179748107430D600F5D044 /* testhaptic */; + productReference = 00179748107430D600F5D044 /* testhaptic.app */; productType = "com.apple.product-type.application"; }; 00179756107431B300F5D044 /* testdraw */ = { @@ -1490,6 +2002,7 @@ buildPhases = ( 0017975B107431B300F5D044 /* Sources */, 0017975C107431B300F5D044 /* Frameworks */, + F3CB56A12A78973700766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1497,7 +2010,7 @@ ); name = testdraw; productName = testalpha; - productReference = 0017976E107431B300F5D044 /* testdraw */; + productReference = 0017976E107431B300F5D044 /* testdraw.app */; productType = "com.apple.product-type.application"; }; 00179776107432AE00F5D044 /* testime */ = { @@ -1506,6 +2019,7 @@ buildPhases = ( 0017977B107432AE00F5D044 /* Sources */, 0017977C107432AE00F5D044 /* Frameworks */, + F3CB56C22A78979600766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1513,7 +2027,7 @@ ); name = testime; productName = testalpha; - productReference = 0017978E107432AE00F5D044 /* testime */; + productReference = 0017978E107432AE00F5D044 /* testime.app */; productType = "com.apple.product-type.application"; }; 001797961074334C00F5D044 /* testintersections */ = { @@ -1522,6 +2036,7 @@ buildPhases = ( 0017979B1074334C00F5D044 /* Sources */, 0017979C1074334C00F5D044 /* Frameworks */, + F3CB56C52A78979C00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1529,7 +2044,7 @@ ); name = testintersections; productName = testalpha; - productReference = 001797AE1074334C00F5D044 /* testintersections */; + productReference = 001797AE1074334C00F5D044 /* testintersections.app */; productType = "com.apple.product-type.application"; }; 001797B8107433C600F5D044 /* testloadso */ = { @@ -1538,6 +2053,7 @@ buildPhases = ( 001797BD107433C600F5D044 /* Sources */, 001797BE107433C600F5D044 /* Frameworks */, + F3CB56CB2A7897AE00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1545,7 +2061,7 @@ ); name = testloadso; productName = testalpha; - productReference = 001797D0107433C600F5D044 /* testloadso */; + productReference = 001797D0107433C600F5D044 /* testloadso.app */; productType = "com.apple.product-type.application"; }; 001797FA1074355200F5D044 /* testmultiaudio */ = { @@ -1555,6 +2071,7 @@ 001797FF1074355200F5D044 /* Sources */, 001798001074355200F5D044 /* Frameworks */, F3C17D3828E424B100E1A26D /* Resources */, + F3CB56D42A7897C600766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1562,7 +2079,7 @@ ); name = testmultiaudio; productName = testalpha; - productReference = 001798121074355200F5D044 /* testmultiaudio */; + productReference = 001798121074355200F5D044 /* testmultiaudio.app */; productType = "com.apple.product-type.application"; }; 001798781074392D00F5D044 /* testnative */ = { @@ -1572,6 +2089,7 @@ 0017987E1074392D00F5D044 /* Sources */, 001798821074392D00F5D044 /* Frameworks */, DB166DDA16A1D40F00A1396C /* CopyFiles */, + F3CB56D72A7897CE00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1588,6 +2106,7 @@ buildPhases = ( 001798A2107439DF00F5D044 /* Sources */, 001798A3107439DF00F5D044 /* Frameworks */, + F3CB56E12A7897F000766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1595,7 +2114,7 @@ ); name = testpower; productName = testalpha; - productReference = 001798B5107439DF00F5D044 /* testpower */; + productReference = 001798B5107439DF00F5D044 /* testpower.app */; productType = "com.apple.product-type.application"; }; 001798DA10743BEC00F5D044 /* testresample */ = { @@ -1604,6 +2123,7 @@ buildPhases = ( 001798DF10743BEC00F5D044 /* Sources */, 001798E010743BEC00F5D044 /* Frameworks */, + F3CB56ED2A78980D00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1611,7 +2131,7 @@ ); name = testresample; productName = testalpha; - productReference = 001798F210743BEC00F5D044 /* testresample */; + productReference = 001798F210743BEC00F5D044 /* testresample.app */; productType = "com.apple.product-type.application"; }; 001798FE10743F1000F5D044 /* testsprite */ = { @@ -1621,6 +2141,7 @@ 0017990310743F1000F5D044 /* Sources */, 0017990410743F1000F5D044 /* Frameworks */, F3C17D3A28E4252200E1A26D /* Resources */, + F3CB568B2A7895F800766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1628,7 +2149,7 @@ ); name = testsprite; productName = testalpha; - productReference = 0017991610743F1000F5D044 /* testsprite */; + productReference = 0017991610743F1000F5D044 /* testsprite.app */; productType = "com.apple.product-type.application"; }; 0017992010743FB700F5D044 /* testwm */ = { @@ -1637,6 +2158,7 @@ buildPhases = ( 0017992510743FB700F5D044 /* Sources */, 0017992610743FB700F5D044 /* Frameworks */, + F3CB570E2A78986000766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1644,7 +2166,7 @@ ); name = testwm; productName = testalpha; - productReference = 0017993810743FB700F5D044 /* testwm */; + productReference = 0017993810743FB700F5D044 /* testwm.app */; productType = "com.apple.product-type.application"; }; 002F340109CA1BFF00EBEB88 /* testfile */ = { @@ -1653,6 +2175,7 @@ buildPhases = ( 002F340709CA1BFF00EBEB88 /* Sources */, 002F340809CA1BFF00EBEB88 /* Frameworks */, + F3CB56AD2A78975A00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1660,7 +2183,7 @@ ); name = testfile; productName = testalpha; - productReference = 002F341209CA1BFF00EBEB88 /* testfile */; + productReference = 002F341209CA1BFF00EBEB88 /* testfile.app */; productType = "com.apple.product-type.application"; }; 002F342009CA1F0300EBEB88 /* testiconv */ = { @@ -1670,6 +2193,7 @@ 002F342609CA1F0300EBEB88 /* Sources */, 002F342709CA1F0300EBEB88 /* Frameworks */, 00794EEC09D2371F003FC8A1 /* CopyFiles */, + F3CB56BF2A78979000766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1677,7 +2201,7 @@ ); name = testiconv; productName = testalpha; - productReference = 002F343109CA1F0300EBEB88 /* testiconv */; + productReference = 002F343109CA1F0300EBEB88 /* testiconv.app */; productType = "com.apple.product-type.application"; }; 002F343C09CA1FB300EBEB88 /* testoverlay */ = { @@ -1687,6 +2211,7 @@ 002F344209CA1FB300EBEB88 /* Sources */, 002F344309CA1FB300EBEB88 /* Frameworks */, 00794EF409D237C7003FC8A1 /* CopyFiles */, + F3CB56DB2A7897E200766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1694,7 +2219,7 @@ ); name = testoverlay; productName = testalpha; - productReference = 002F344D09CA1FB300EBEB88 /* testoverlay */; + productReference = 002F344D09CA1FB300EBEB88 /* testoverlay.app */; productType = "com.apple.product-type.application"; }; 002F345909CA204F00EBEB88 /* testplatform */ = { @@ -1703,6 +2228,7 @@ buildPhases = ( 002F345F09CA204F00EBEB88 /* Sources */, 002F346009CA204F00EBEB88 /* Frameworks */, + F3CB56DE2A7897E900766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1710,7 +2236,7 @@ ); name = testplatform; productName = testalpha; - productReference = 002F346A09CA204F00EBEB88 /* testplatform */; + productReference = 002F346A09CA204F00EBEB88 /* testplatform.app */; productType = "com.apple.product-type.application"; }; 4537749112091504002F0F45 /* testshape */ = { @@ -1720,6 +2246,7 @@ 4537748F12091504002F0F45 /* Sources */, 4537749012091504002F0F45 /* Frameworks */, DB166ECE16A1D85400A1396C /* CopyFiles */, + F3CB56FC2A78983200766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1727,24 +2254,24 @@ ); name = testshape; productName = testshape; - productReference = 4537749212091504002F0F45 /* testshape */; + productReference = 4537749212091504002F0F45 /* testshape.app */; productType = "com.apple.product-type.application"; }; - BBFC08B7164C6862003E6A99 /* testgamepad */ = { + BBFC08B7164C6862003E6A99 /* testcontroller */ = { isa = PBXNativeTarget; - buildConfigurationList = BBFC08CA164C6862003E6A99 /* Build configuration list for PBXNativeTarget "testgamepad" */; + buildConfigurationList = BBFC08CA164C6862003E6A99 /* Build configuration list for PBXNativeTarget "testcontroller" */; buildPhases = ( BBFC08BC164C6862003E6A99 /* Sources */, BBFC08BE164C6862003E6A99 /* Frameworks */, - F3C17D3528E4242100E1A26D /* Resources */, + F3CB569E2A78973000766177 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( ); - name = testgamepad; + name = testcontroller; productName = testjoystick; - productReference = BBFC08CD164C6862003E6A99 /* testgamepad */; + productReference = BBFC08CD164C6862003E6A99 /* testcontroller.app */; productType = "com.apple.product-type.application"; }; BEC566AB0761D90300A33029 /* checkkeys */ = { @@ -1753,6 +2280,7 @@ buildPhases = ( BEC566B00761D90300A33029 /* Sources */, BEC566B20761D90300A33029 /* Frameworks */, + F3CB568E2A7896BF00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1760,7 +2288,7 @@ ); name = checkkeys; productName = checkkeys; - productReference = BEC566B60761D90300A33029 /* checkkeys */; + productReference = BEC566B60761D90300A33029 /* checkkeys.app */; productType = "com.apple.product-type.application"; }; BEC566C50761D90300A33029 /* loopwave */ = { @@ -1770,6 +2298,7 @@ BEC566CA0761D90300A33029 /* Sources */, BEC566CC0761D90300A33029 /* Frameworks */, 00794E6409D2084F003FC8A1 /* CopyFiles */, + F3CB56922A7896F900766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1777,7 +2306,7 @@ ); name = loopwave; productName = loopwave; - productReference = BEC566D10761D90300A33029 /* loopwave */; + productReference = BEC566D10761D90300A33029 /* loopwave.app */; productType = "com.apple.product-type.application"; }; BEC566FB0761D90300A33029 /* testerror */ = { @@ -1786,6 +2315,7 @@ buildPhases = ( BEC567000761D90300A33029 /* Sources */, BEC567020761D90300A33029 /* Frameworks */, + F3CB56AA2A78975100766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1793,7 +2323,7 @@ ); name = testerror; productName = testerror; - productReference = BEC567060761D90400A33029 /* testerror */; + productReference = BEC567060761D90400A33029 /* testerror.app */; productType = "com.apple.product-type.application"; }; BEC567230761D90400A33029 /* testthread */ = { @@ -1802,6 +2332,7 @@ buildPhases = ( BEC567280761D90400A33029 /* Sources */, BEC5672A0761D90400A33029 /* Frameworks */, + F3CB57052A78984A00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1809,23 +2340,7 @@ ); name = testthread; productName = testthread; - productReference = BEC5672E0761D90400A33029 /* testthread */; - productType = "com.apple.product-type.application"; - }; - BEC567300761D90400A33029 /* testjoystick */ = { - isa = PBXNativeTarget; - buildConfigurationList = 001B596008BDB826006539E9 /* Build configuration list for PBXNativeTarget "testjoystick" */; - buildPhases = ( - BEC567350761D90400A33029 /* Sources */, - BEC567370761D90400A33029 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = testjoystick; - productName = testjoystick; - productReference = BEC5673B0761D90400A33029 /* testjoystick */; + productReference = BEC5672E0761D90400A33029 /* testthread.app */; productType = "com.apple.product-type.application"; }; BEC5673D0761D90400A33029 /* testkeys */ = { @@ -1834,6 +2349,7 @@ buildPhases = ( BEC567420761D90400A33029 /* Sources */, BEC567440761D90400A33029 /* Frameworks */, + F3CB56C82A7897A500766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1841,7 +2357,7 @@ ); name = testkeys; productName = testkeys; - productReference = BEC567480761D90400A33029 /* testkeys */; + productReference = BEC567480761D90400A33029 /* testkeys.app */; productType = "com.apple.product-type.application"; }; BEC5674A0761D90400A33029 /* testlock */ = { @@ -1850,6 +2366,7 @@ buildPhases = ( BEC5674F0761D90400A33029 /* Sources */, BEC567510761D90400A33029 /* Frameworks */, + F3CB56CE2A7897B500766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1857,7 +2374,7 @@ ); name = testlock; productName = testlock; - productReference = BEC567550761D90400A33029 /* testlock */; + productReference = BEC567550761D90400A33029 /* testlock.app */; productType = "com.apple.product-type.application"; }; BEC567720761D90500A33029 /* testsem */ = { @@ -1866,6 +2383,7 @@ buildPhases = ( BEC567770761D90500A33029 /* Sources */, BEC567790761D90500A33029 /* Frameworks */, + F3CB56F62A78982400766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1873,7 +2391,7 @@ ); name = testsem; productName = testsem; - productReference = BEC5677D0761D90500A33029 /* testsem */; + productReference = BEC5677D0761D90500A33029 /* testsem.app */; productType = "com.apple.product-type.application"; }; BEC5678D0761D90500A33029 /* testtimer */ = { @@ -1882,6 +2400,7 @@ buildPhases = ( BEC567920761D90500A33029 /* Sources */, BEC567940761D90500A33029 /* Frameworks */, + F3CB57082A78985400766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1889,7 +2408,7 @@ ); name = testtimer; productName = testtimer; - productReference = BEC567980761D90500A33029 /* testtimer */; + productReference = BEC567980761D90500A33029 /* testtimer.app */; productType = "com.apple.product-type.application"; }; BEC567A70761D90500A33029 /* testversion */ = { @@ -1898,6 +2417,7 @@ buildPhases = ( BEC567AC0761D90500A33029 /* Sources */, BEC567AE0761D90500A33029 /* Frameworks */, + F3CB570B2A78985A00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1905,7 +2425,7 @@ ); name = testversion; productName = testversion; - productReference = BEC567B20761D90500A33029 /* testversion */; + productReference = BEC567B20761D90500A33029 /* testversion.app */; productType = "com.apple.product-type.application"; }; BEC567EA0761D90600A33029 /* torturethread */ = { @@ -1914,6 +2434,7 @@ buildPhases = ( BEC567EF0761D90600A33029 /* Sources */, BEC567F10761D90600A33029 /* Frameworks */, + F3CB57112A78986700766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1921,7 +2442,7 @@ ); name = torturethread; productName = torturethread; - productReference = BEC567F50761D90600A33029 /* torturethread */; + productReference = BEC567F50761D90600A33029 /* torturethread.app */; productType = "com.apple.product-type.application"; }; DB0F48D917CA51E5008798C5 /* testdrawchessboard */ = { @@ -1930,6 +2451,7 @@ buildPhases = ( DB0F48DA17CA51E5008798C5 /* Sources */, DB0F48DC17CA51E5008798C5 /* Frameworks */, + F3CB56A42A78974000766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1937,7 +2459,7 @@ ); name = testdrawchessboard; productName = testalpha; - productReference = DB0F48EC17CA51E5008798C5 /* testdrawchessboard */; + productReference = DB0F48EC17CA51E5008798C5 /* testdrawchessboard.app */; productType = "com.apple.product-type.application"; }; DB0F48EF17CA5212008798C5 /* testfilesystem */ = { @@ -1946,6 +2468,7 @@ buildPhases = ( DB0F48F017CA5212008798C5 /* Sources */, DB0F48F217CA5212008798C5 /* Frameworks */, + F3CB56B02A78976200766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1953,12 +2476,12 @@ ); name = testfilesystem; productName = testalpha; - productReference = DB0F490117CA5212008798C5 /* testfilesystem */; + productReference = DB0F490117CA5212008798C5 /* testfilesystem.app */; productType = "com.apple.product-type.application"; }; - DB166D7E16A1D12400A1396C /* SDL_test */ = { + DB166D7E16A1D12400A1396C /* SDL3_test */ = { isa = PBXNativeTarget; - buildConfigurationList = DB166D8016A1D12400A1396C /* Build configuration list for PBXNativeTarget "SDL_test" */; + buildConfigurationList = DB166D8016A1D12400A1396C /* Build configuration list for PBXNativeTarget "SDL3_test" */; buildPhases = ( DB166D7B16A1D12400A1396C /* Sources */, DB166D7C16A1D12400A1396C /* Frameworks */, @@ -1968,9 +2491,9 @@ ); dependencies = ( ); - name = SDL_test; + name = SDL3_test; productName = SDL_test; - productReference = DB166D7F16A1D12400A1396C /* libSDL_test.a */; + productReference = DB166D7F16A1D12400A1396C /* libSDL3_test.a */; productType = "com.apple.product-type.library.static"; }; DB166DC416A1D36A00A1396C /* testmessage */ = { @@ -1979,6 +2502,7 @@ buildPhases = ( DB166DC516A1D36A00A1396C /* Sources */, DB166DC716A1D36A00A1396C /* Frameworks */, + F3CB56D12A7897BE00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -1986,7 +2510,7 @@ ); name = testmessage; productName = testalpha; - productReference = DB166DD516A1D36A00A1396C /* testmessage */; + productReference = DB166DD516A1D36A00A1396C /* testmessage.app */; productType = "com.apple.product-type.application"; }; DB166DDC16A1D50C00A1396C /* testrelative */ = { @@ -1995,6 +2519,7 @@ buildPhases = ( DB166DDD16A1D50C00A1396C /* Sources */, DB166DDF16A1D50C00A1396C /* Frameworks */, + F3CB56E42A7897F800766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2002,7 +2527,7 @@ ); name = testrelative; productName = testalpha; - productReference = DB166DEE16A1D50C00A1396C /* testrelative */; + productReference = DB166DEE16A1D50C00A1396C /* testrelative.app */; productType = "com.apple.product-type.application"; }; DB166DF316A1D57C00A1396C /* testrendercopyex */ = { @@ -2012,6 +2537,7 @@ DB166DF416A1D57C00A1396C /* Sources */, DB166DF616A1D57C00A1396C /* Frameworks */, DB166E2116A1D5DF00A1396C /* CopyFiles */, + F3CB56E72A7897FE00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2019,7 +2545,7 @@ ); name = testrendercopyex; productName = testalpha; - productReference = DB166E0516A1D57C00A1396C /* testrendercopyex */; + productReference = DB166E0516A1D57C00A1396C /* testrendercopyex.app */; productType = "com.apple.product-type.application"; }; DB166E0A16A1D5AD00A1396C /* testrendertarget */ = { @@ -2029,6 +2555,7 @@ DB166E0B16A1D5AD00A1396C /* Sources */, DB166E0D16A1D5AD00A1396C /* Frameworks */, DB166E2416A1D61000A1396C /* CopyFiles */, + F3CB56EA2A78980600766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2036,7 +2563,7 @@ ); name = testrendertarget; productName = testalpha; - productReference = DB166E1C16A1D5AD00A1396C /* testrendertarget */; + productReference = DB166E1C16A1D5AD00A1396C /* testrendertarget.app */; productType = "com.apple.product-type.application"; }; DB166E2716A1D64D00A1396C /* testrumble */ = { @@ -2045,6 +2572,7 @@ buildPhases = ( DB166E2816A1D64D00A1396C /* Sources */, DB166E2A16A1D64D00A1396C /* Frameworks */, + F3CB56F02A78981500766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2052,7 +2580,7 @@ ); name = testrumble; productName = testalpha; - productReference = DB166E3816A1D64D00A1396C /* testrumble */; + productReference = DB166E3816A1D64D00A1396C /* testrumble.app */; productType = "com.apple.product-type.application"; }; DB166E3D16A1D69000A1396C /* testscale */ = { @@ -2062,6 +2590,7 @@ DB166E3E16A1D69000A1396C /* Sources */, DB166E4016A1D69000A1396C /* Frameworks */, DB166E4C16A1D69000A1396C /* CopyFiles */, + F3CB56F32A78981C00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2069,7 +2598,7 @@ ); name = testscale; productName = testalpha; - productReference = DB166E5216A1D69000A1396C /* testscale */; + productReference = DB166E5216A1D69000A1396C /* testscale.app */; productType = "com.apple.product-type.application"; }; DB166E5716A1D6F300A1396C /* testshader */ = { @@ -2078,6 +2607,7 @@ buildPhases = ( DB166E5816A1D6F300A1396C /* Sources */, DB166E5A16A1D6F300A1396C /* Frameworks */, + F3CB56F92A78982B00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2085,7 +2615,7 @@ ); name = testshader; productName = testsem; - productReference = DB166E6816A1D6F300A1396C /* testshader */; + productReference = DB166E6816A1D6F300A1396C /* testshader.app */; productType = "com.apple.product-type.application"; }; DB166E6D16A1D78400A1396C /* testspriteminimal */ = { @@ -2095,6 +2625,7 @@ DB166E6E16A1D78400A1396C /* Sources */, DB166E7016A1D78400A1396C /* Frameworks */, DB166E9B16A1D7FC00A1396C /* CopyFiles */, + F3CB56FF2A78983C00766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2102,7 +2633,7 @@ ); name = testspriteminimal; productName = testspriteminimal; - productReference = DB166E7E16A1D78400A1396C /* testspriteminimal */; + productReference = DB166E7E16A1D78400A1396C /* testspriteminimal.app */; productType = "com.apple.product-type.application"; }; DB166E8016A1D78C00A1396C /* teststreaming */ = { @@ -2112,6 +2643,7 @@ DB166E8116A1D78C00A1396C /* Sources */, DB166E8316A1D78C00A1396C /* Frameworks */, DB166E9916A1D7EE00A1396C /* CopyFiles */, + F3CB57022A78984300766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2119,7 +2651,7 @@ ); name = teststreaming; productName = teststreaming; - productReference = DB166E9116A1D78C00A1396C /* teststreaming */; + productReference = DB166E9116A1D78C00A1396C /* teststreaming.app */; productType = "com.apple.product-type.application"; }; DB445EE618184B7000B306B0 /* testdropfile */ = { @@ -2128,6 +2660,7 @@ buildPhases = ( DB445EE718184B7000B306B0 /* Sources */, DB445EE918184B7000B306B0 /* Frameworks */, + F3CB56A72A78974800766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2144,6 +2677,7 @@ buildPhases = ( DB89956E18A19ABA0092407C /* Sources */, DB89957018A19ABA0092407C /* Frameworks */, + F3CB56BC2A78978800766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2151,24 +2685,7 @@ ); name = testhotplug; productName = testalpha; - productReference = DB89957E18A19ABA0092407C /* testhotplug */; - productType = "com.apple.product-type.application"; - }; - DBEC54D91A1A81C3005B1EAB /* gamepadmap */ = { - isa = PBXNativeTarget; - buildConfigurationList = DBEC54E71A1A81C3005B1EAB /* Build configuration list for PBXNativeTarget "gamepadmap" */; - buildPhases = ( - DBEC54DA1A1A81C3005B1EAB /* Sources */, - DBEC54DC1A1A81C3005B1EAB /* Frameworks */, - DBEC54EC1A1A827C005B1EAB /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = gamepadmap; - productName = checkkeys; - productReference = DBEC54EA1A1A81C3005B1EAB /* gamepadmap */; + productReference = DB89957E18A19ABA0092407C /* testhotplug.app */; productType = "com.apple.product-type.application"; }; F35E56A2298312CB00A43A5F /* testautomation */ = { @@ -2177,6 +2694,7 @@ buildPhases = ( F35E56A3298312CB00A43A5F /* Sources */, F35E56A5298312CB00A43A5F /* Frameworks */, + F3CB569B2A78972700766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2193,6 +2711,7 @@ buildPhases = ( F3C17CD828E416CF00E1A26D /* Sources */, F3C17CD928E416CF00E1A26D /* Frameworks */, + F3CB56B32A78976900766177 /* Embed Frameworks */, ); buildRules = ( ); @@ -2212,8 +2731,141 @@ LastSwiftUpdateCheck = 1400; LastUpgradeCheck = 0420; TargetAttributes = { + 0017957410741F7900F5D044 = { + ProvisioningStyle = Automatic; + }; + 00179595107421BF00F5D044 = { + ProvisioningStyle = Automatic; + }; + 0017970910742F3200F5D044 = { + ProvisioningStyle = Automatic; + }; + 00179730107430D600F5D044 = { + ProvisioningStyle = Automatic; + }; + 00179756107431B300F5D044 = { + ProvisioningStyle = Automatic; + }; + 00179776107432AE00F5D044 = { + ProvisioningStyle = Automatic; + }; + 001797961074334C00F5D044 = { + ProvisioningStyle = Automatic; + }; + 001797B8107433C600F5D044 = { + ProvisioningStyle = Automatic; + }; + 001797FA1074355200F5D044 = { + ProvisioningStyle = Automatic; + }; + 001798781074392D00F5D044 = { + ProvisioningStyle = Automatic; + }; + 0017989D107439DF00F5D044 = { + ProvisioningStyle = Automatic; + }; + 001798DA10743BEC00F5D044 = { + ProvisioningStyle = Automatic; + }; + 001798FE10743F1000F5D044 = { + ProvisioningStyle = Automatic; + }; + 0017992010743FB700F5D044 = { + ProvisioningStyle = Automatic; + }; + 002F340109CA1BFF00EBEB88 = { + ProvisioningStyle = Automatic; + }; + 002F342009CA1F0300EBEB88 = { + ProvisioningStyle = Automatic; + }; + 002F343C09CA1FB300EBEB88 = { + ProvisioningStyle = Automatic; + }; + 002F345909CA204F00EBEB88 = { + ProvisioningStyle = Automatic; + }; + 4537749112091504002F0F45 = { + ProvisioningStyle = Automatic; + }; + BBFC08B7164C6862003E6A99 = { + ProvisioningStyle = Automatic; + }; + BEC566AB0761D90300A33029 = { + ProvisioningStyle = Automatic; + }; + BEC566C50761D90300A33029 = { + ProvisioningStyle = Automatic; + }; + BEC566FB0761D90300A33029 = { + ProvisioningStyle = Automatic; + }; + BEC567230761D90400A33029 = { + ProvisioningStyle = Automatic; + }; + BEC5673D0761D90400A33029 = { + ProvisioningStyle = Automatic; + }; + BEC5674A0761D90400A33029 = { + ProvisioningStyle = Automatic; + }; + BEC567720761D90500A33029 = { + ProvisioningStyle = Automatic; + }; + BEC5678D0761D90500A33029 = { + ProvisioningStyle = Automatic; + }; + BEC567A70761D90500A33029 = { + ProvisioningStyle = Automatic; + }; + BEC567EA0761D90600A33029 = { + ProvisioningStyle = Automatic; + }; + DB0F48D917CA51E5008798C5 = { + ProvisioningStyle = Automatic; + }; + DB0F48EF17CA5212008798C5 = { + ProvisioningStyle = Automatic; + }; + DB166DC416A1D36A00A1396C = { + ProvisioningStyle = Automatic; + }; + DB166DDC16A1D50C00A1396C = { + ProvisioningStyle = Automatic; + }; + DB166DF316A1D57C00A1396C = { + ProvisioningStyle = Automatic; + }; + DB166E0A16A1D5AD00A1396C = { + ProvisioningStyle = Automatic; + }; + DB166E2716A1D64D00A1396C = { + ProvisioningStyle = Automatic; + }; + DB166E3D16A1D69000A1396C = { + ProvisioningStyle = Automatic; + }; + DB166E5716A1D6F300A1396C = { + ProvisioningStyle = Automatic; + }; + DB166E6D16A1D78400A1396C = { + ProvisioningStyle = Automatic; + }; + DB166E8016A1D78C00A1396C = { + ProvisioningStyle = Automatic; + }; + DB445EE618184B7000B306B0 = { + ProvisioningStyle = Automatic; + }; + DB89956D18A19ABA0092407C = { + ProvisioningStyle = Automatic; + }; + F35E56A2298312CB00A43A5F = { + ProvisioningStyle = Automatic; + }; F3C17CDB28E416CF00E1A26D = { CreatedOnToolsVersion = 14.0.1; + ProvisioningStyle = Automatic; }; }; }; @@ -2240,20 +2892,19 @@ projectRoot = ""; targets = ( BEC566920761D90300A33029 /* All */, - DB166D7E16A1D12400A1396C /* SDL_test */, + DB166D7E16A1D12400A1396C /* SDL3_test */, BEC566AB0761D90300A33029 /* checkkeys */, - DBEC54D91A1A81C3005B1EAB /* gamepadmap */, BEC566C50761D90300A33029 /* loopwave */, 0017957410741F7900F5D044 /* testatomic */, 00179595107421BF00F5D044 /* testaudioinfo */, F35E56A2298312CB00A43A5F /* testautomation */, + BBFC08B7164C6862003E6A99 /* testcontroller */, 00179756107431B300F5D044 /* testdraw */, DB0F48D917CA51E5008798C5 /* testdrawchessboard */, DB445EE618184B7000B306B0 /* testdropfile */, BEC566FB0761D90300A33029 /* testerror */, 002F340109CA1BFF00EBEB88 /* testfile */, DB0F48EF17CA5212008798C5 /* testfilesystem */, - BBFC08B7164C6862003E6A99 /* testgamepad */, F3C17CDB28E416CF00E1A26D /* testgeometry */, 0017970910742F3200F5D044 /* testgl */, 00179730107430D600F5D044 /* testhaptic */, @@ -2261,7 +2912,6 @@ 002F342009CA1F0300EBEB88 /* testiconv */, 00179776107432AE00F5D044 /* testime */, 001797961074334C00F5D044 /* testintersections */, - BEC567300761D90400A33029 /* testjoystick */, BEC5673D0761D90400A33029 /* testkeys */, 001797B8107433C600F5D044 /* testloadso */, BEC5674A0761D90400A33029 /* testlock */, @@ -2300,83 +2950,9 @@ remoteRef = 003FA642093FFD41000C53B3 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 003FA645093FFD41000C53B3 /* libSDL3.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL3.a; - remoteRef = 003FA644093FFD41000C53B3 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 003FA649093FFD41000C53B3 /* SDL3 */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = SDL3; - remoteRef = 003FA648093FFD41000C53B3 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - DB1D40D717B3F30D00D74CFC /* libSDL3.dylib */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = libSDL3.dylib; - remoteRef = DB1D40D617B3F30D00D74CFC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3C17C5D28E3FB2900E1A26D /* SDL3.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = SDL3.framework; - remoteRef = F3C17C5C28E3FB2900E1A26D /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3C17C5F28E3FB2900E1A26D /* SDL3.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = SDL3.framework; - remoteRef = F3C17C5E28E3FB2900E1A26D /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3C17C6328E3FB2900E1A26D /* libSDL3.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL3.a; - remoteRef = F3C17C6228E3FB2900E1A26D /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3C17C6528E3FB2900E1A26D /* libSDL3.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL3.a; - remoteRef = F3C17C6428E3FB2900E1A26D /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3C17C6728E3FB2900E1A26D /* libSDL3.dylib */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = libSDL3.dylib; - remoteRef = F3C17C6628E3FB2900E1A26D /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F3C17C6928E3FB2900E1A26D /* libSDL3.dylib */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = libSDL3.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 /* gamepadmap_back.bmp in Resources */, - F3C17D3F28E4277D00E1A26D /* gamepadmap.bmp in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; F3C17D3828E424B100E1A26D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2560,8 +3136,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BBFC08D0164C6876003E6A99 /* testgamepad.c in Sources */, + BBFC08D0164C6876003E6A99 /* testcontroller.c in Sources */, F3C17C7928E40C6E00E1A26D /* testutils.c in Sources */, + F399C64E2A78929400C86979 /* gamepadutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2598,14 +3175,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BEC567350761D90400A33029 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BEC567360761D90400A33029 /* testjoystick.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; BEC567420761D90400A33029 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2651,6 +3220,8 @@ buildActionMask = 2147483647; files = ( BEC567F00761D90600A33029 /* torturethread.c in Sources */, + F399C64F2A78929400C86979 /* gamepadutils.c in Sources */, + F399C6522A7892D800C86979 /* testautomation_intrinsics.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2781,21 +3352,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DBEC54DA1A1A81C3005B1EAB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DBEC54EB1A1A8205005B1EAB /* gamepadmap.c in Sources */, - F3C17C7428E40AF000E1A26D /* testutils.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; F35E56A3298312CB00A43A5F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F35E56D12983130F00A43A5F /* testautomation_render.c in Sources */, F35E56E22983130F00A43A5F /* testautomation_syswm.c in Sources */, + F399C6512A7892D800C86979 /* testautomation_intrinsics.c in Sources */, F35E56D22983130F00A43A5F /* testautomation_rwops.c in Sources */, F35E56E32983130F00A43A5F /* testautomation_surface.c in Sources */, F35E56DB2983130F00A43A5F /* testautomation_platform.c in Sources */, @@ -2869,6 +3432,9 @@ }; 001799661074403E00F5D044 /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilters = ( + macos, + ); target = 0017970910742F3200F5D044 /* testgl */; targetProxy = 001799651074403E00F5D044 /* PBXContainerItemProxy */; }; @@ -2897,11 +3463,6 @@ target = 001797961074334C00F5D044 /* testintersections */; targetProxy = 0017996F1074403E00F5D044 /* PBXContainerItemProxy */; }; - 001799721074403E00F5D044 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = BEC567300761D90400A33029 /* testjoystick */; - targetProxy = 001799711074403E00F5D044 /* PBXContainerItemProxy */; - }; 001799741074403E00F5D044 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = BEC5673D0761D90400A33029 /* testkeys */; @@ -2924,6 +3485,9 @@ }; 001799801074403E00F5D044 /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilters = ( + macos, + ); target = 001798781074392D00F5D044 /* testnative */; targetProxy = 0017997F1074403E00F5D044 /* PBXContainerItemProxy */; }; @@ -2989,7 +3553,7 @@ }; DB166D6E16A1CEAA00A1396C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BBFC08B7164C6862003E6A99 /* testgamepad */; + target = BBFC08B7164C6862003E6A99 /* testcontroller */; targetProxy = DB166D6D16A1CEAA00A1396C /* PBXContainerItemProxy */; }; DB166D7016A1CEAF00A1396C /* PBXTargetDependency */ = { @@ -3047,42 +3611,72 @@ target = F35E56A2298312CB00A43A5F /* testautomation */; targetProxy = F35E56E62983133F00A43A5F /* PBXContainerItemProxy */; }; + F3E1F7FF2A78C3AD00AC76D3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DB89956D18A19ABA0092407C /* testhotplug */; + targetProxy = F3E1F7FE2A78C3AD00AC76D3 /* PBXContainerItemProxy */; + }; + F3E1F8012A78C3BE00AC76D3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DB445EE618184B7000B306B0 /* testdropfile */; + targetProxy = F3E1F8002A78C3BE00AC76D3 /* PBXContainerItemProxy */; + }; + F3E1F8032A78C3C500AC76D3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F3C17CDB28E416CF00E1A26D /* testgeometry */; + targetProxy = F3E1F8022A78C3C500AC76D3 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 0017958910741F7900F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testatomic; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 0017958A10741F7900F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testatomic; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 001795AA107421BF00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testaudioinfo; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 001795AB107421BF00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testaudioinfo; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 0017971E10742F3200F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; GCC_PREPROCESSOR_DEFINITIONS = HAVE_OPENGL; PRODUCT_NAME = testgl; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = macosx; }; name = Debug; @@ -3090,8 +3684,11 @@ 0017971F10742F3200F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; GCC_PREPROCESSOR_DEFINITIONS = HAVE_OPENGL; PRODUCT_NAME = testgl; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = macosx; }; name = Release; @@ -3099,91 +3696,130 @@ 00179745107430D600F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testhaptic; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 00179746107430D600F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testhaptic; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 0017976B107431B300F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testdraw; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 0017976C107431B300F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testdraw; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 0017978B107432AE00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testime; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 0017978C107432AE00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testime; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 001797AB1074334C00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testintersections; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 001797AC1074334C00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testintersections; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 001797CD107433C600F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testloadso; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 001797CE107433C600F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testloadso; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 0017980F1074355200F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testmultiaudio; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 001798101074355200F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testmultiaudio; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 001798911074392D00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testnative; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = macosx; }; name = Debug; @@ -3191,7 +3827,10 @@ 001798921074392D00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testnative; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = macosx; }; name = Release; @@ -3199,56 +3838,80 @@ 001798B2107439DF00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testpower; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 001798B3107439DF00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testpower; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 001798EF10743BEC00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testresample; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 001798F010743BEC00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testresample; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 0017991310743F1000F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testsprite; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 0017991410743F1000F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testsprite; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 0017993510743FB700F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testwm; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 0017993610743FB700F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testwm; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; @@ -3275,7 +3938,8 @@ OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)"; SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos"; - SUPPORTS_MACCATALYST = YES; + SUPPORTS_MACCATALYST = NO; + TARGETED_DEVICE_FAMILY = "1,2,3"; TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Debug; @@ -3290,105 +3954,140 @@ 002A85B41073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = checkkeys; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85B61073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = loopwave; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85BC1073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testerror; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85BD1073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testfile; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85C01073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testiconv; - }; - name = Debug; - }; - 002A85C11073008E007319AE /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = testjoystick; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85C21073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testkeys; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85C31073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testlock; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85C51073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testoverlay; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85C71073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testplatform; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85C81073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testsem; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85CA1073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testthread; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85CB1073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testtimer; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85CC1073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testversion; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 002A85D11073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = torturethread; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; @@ -3412,7 +4111,8 @@ OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)"; SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos"; - SUPPORTS_MACCATALYST = YES; + SUPPORTS_MACCATALYST = NO; + TARGETED_DEVICE_FAMILY = "1,2,3"; TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Release; @@ -3427,161 +4127,222 @@ 002A85D61073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = checkkeys; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85D81073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = loopwave; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85DE1073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testerror; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85DF1073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testfile; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85E21073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testiconv; - }; - name = Release; - }; - 002A85E31073009D007319AE /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = testjoystick; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85E41073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testkeys; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85E51073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testlock; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85E71073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testoverlay; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85E91073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testplatform; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85EA1073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testsem; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85EC1073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testthread; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85ED1073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testtimer; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85EE1073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testversion; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 002A85F31073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = torturethread; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 4537749712091509002F0F45 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testshape; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 4537749812091509002F0F45 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testshape; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; BBFC08CB164C6862003E6A99 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - PRODUCT_NAME = testgamepad; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Steam Controller support"; + PRODUCT_NAME = testcontroller; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; BBFC08CC164C6862003E6A99 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - PRODUCT_NAME = testgamepad; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Steam Controller support"; + PRODUCT_NAME = testcontroller; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB0F48EA17CA51E5008798C5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testdrawchessboard; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB0F48EB17CA51E5008798C5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testdrawchessboard; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB0F48FF17CA5212008798C5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testfilesystem; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB0F490017CA5212008798C5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testfilesystem; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; @@ -3610,198 +4371,260 @@ DB166DD316A1D36A00A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testmessage; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166DD416A1D36A00A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testmessage; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166DEC16A1D50C00A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrelative; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166DED16A1D50C00A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrelative; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E0316A1D57C00A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrendercopyex; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E0416A1D57C00A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrendercopyex; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E1A16A1D5AD00A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrendertarget; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E1B16A1D5AD00A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrendertarget; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E3616A1D64D00A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrumble; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E3716A1D64D00A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testrumble; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E5016A1D69000A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testscale; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E5116A1D69000A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testscale; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E6616A1D6F300A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testshader; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E6716A1D6F300A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testshader; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E7C16A1D78400A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testspriteminimal; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E7D16A1D78400A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testspriteminimal; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB166E8F16A1D78C00A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = teststreaming; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB166E9016A1D78C00A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = teststreaming; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB445EF618184B7000B306B0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - INFOPLIST_FILE = "TestDropFile-Info.plist"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testdropfile; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB445EF718184B7000B306B0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - INFOPLIST_FILE = "TestDropFile-Info.plist"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testdropfile; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; DB89957C18A19ABA0092407C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testhotplug; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; DB89957D18A19ABA0092407C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = testhotplug; - }; - name = Release; - }; - DBEC54E81A1A81C3005B1EAB /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = gamepadmap; - }; - name = Debug; - }; - DBEC54E91A1A81C3005B1EAB /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = gamepadmap; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; F35E56A8298312CB00A43A5F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; F35E56A9298312CB00A43A5F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; F3C17CE928E416D000E1A26D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; F3C17CEA28E416D000E1A26D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; @@ -3970,15 +4793,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - 001B596008BDB826006539E9 /* Build configuration list for PBXNativeTarget "testjoystick" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 002A85C11073008E007319AE /* Debug */, - 002A85E31073009D007319AE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; 001B596408BDB826006539E9 /* Build configuration list for PBXNativeTarget "testkeys" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -4096,7 +4910,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - BBFC08CA164C6862003E6A99 /* Build configuration list for PBXNativeTarget "testgamepad" */ = { + BBFC08CA164C6862003E6A99 /* Build configuration list for PBXNativeTarget "testcontroller" */ = { isa = XCConfigurationList; buildConfigurations = ( BBFC08CB164C6862003E6A99 /* Debug */, @@ -4123,7 +4937,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - DB166D8016A1D12400A1396C /* Build configuration list for PBXNativeTarget "SDL_test" */ = { + DB166D8016A1D12400A1396C /* Build configuration list for PBXNativeTarget "SDL3_test" */ = { isa = XCConfigurationList; buildConfigurations = ( DB166D8116A1D12400A1396C /* Debug */, @@ -4231,15 +5045,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - DBEC54E71A1A81C3005B1EAB /* Build configuration list for PBXNativeTarget "gamepadmap" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DBEC54E81A1A81C3005B1EAB /* Debug */, - DBEC54E91A1A81C3005B1EAB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; F35E56A7298312CB00A43A5F /* Build configuration list for PBXNativeTarget "testautomation" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Xcode/SDLTest/TestDropFile-Info.plist b/Xcode/SDLTest/TestDropFile-Info.plist deleted file mode 100644 index c9f6cb83..00000000 --- a/Xcode/SDLTest/TestDropFile-Info.plist +++ /dev/null @@ -1,35 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleDocumentTypes - - - CFBundleTypeRole - Viewer - LSHandlerRank - Alternate - LSItemContentTypes - - public.data - - - - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - org.libsdl.test-dropfile - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1.0 - LSMinimumSystemVersion - 10.7 - - diff --git a/Xcode/SDLTest/config.xcconfig b/Xcode/SDLTest/config.xcconfig index 1e6a3ff4..64479226 100644 --- a/Xcode/SDLTest/config.xcconfig +++ b/Xcode/SDLTest/config.xcconfig @@ -7,8 +7,8 @@ // https://help.apple.com/xcode/#/dev745c5c974 // Include any optional config for this build +// This allows you to set DEVELOPMENT_TEAM for all targets, for example. #include? "build.xcconfig" -CONFIG_FRAMEWORK_LDFLAGS[sdk=macos*] = $(inherited) -framework SDL3 -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 SDL3 -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 SDL3 -framework AVFoundation -framework AudioToolbox -framework CoreGraphics -framework CoreHaptics -framework Foundation -framework GameController -framework Metal -framework OpenGLES -framework QuartzCore -framework UIKit +CONFIG_FRAMEWORK_LDFLAGS = -lSDL3_test + diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java index 2a6751e4..8c84b1c2 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java @@ -21,8 +21,6 @@ public class SDLAudioManager { protected static AudioRecord mAudioRecord; protected static Context mContext; - private static final int[] NO_DEVICES = {}; - private static AudioDeviceCallback mAudioDeviceCallback; public static void initialize() { @@ -36,7 +34,7 @@ public class SDLAudioManager { @Override public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { for (AudioDeviceInfo deviceInfo : addedDevices) { - addAudioDevice(deviceInfo.isSink(), deviceInfo.getId()); + addAudioDevice(deviceInfo.isSink(), deviceInfo.getProductName().toString(), deviceInfo.getId()); } } @@ -52,13 +50,10 @@ public class SDLAudioManager { public static void setContext(Context context) { mContext = context; - if (context != null) { - registerAudioDeviceCallback(); - } } public static void release(Context context) { - unregisterAudioDeviceCallback(context); + // no-op atm } // Audio @@ -311,65 +306,30 @@ public class SDLAudioManager { return null; } - private static void registerAudioDeviceCallback() { + public static void registerAudioDeviceCallback() { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) { AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + // get an initial list now, before hotplug callbacks fire. + for (AudioDeviceInfo dev : audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)) { + if (dev.getType() == AudioDeviceInfo.TYPE_TELEPHONY) { + continue; // Device cannot be opened + } + addAudioDevice(dev.isSink(), dev.getProductName().toString(), dev.getId()); + } + for (AudioDeviceInfo dev : audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)) { + addAudioDevice(dev.isSink(), dev.getProductName().toString(), dev.getId()); + } audioManager.registerAudioDeviceCallback(mAudioDeviceCallback, null); } } - private static void unregisterAudioDeviceCallback(Context context) { + public static void unregisterAudioDeviceCallback() { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) { - AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); audioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback); } } - private static int[] ArrayListToArray(ArrayList integers) - { - int[] ret = new int[integers.size()]; - for (int i=0; i < ret.length; i++) { - ret[i] = integers.get(i).intValue(); - } - return ret; - } - - /** - * This method is called by SDL using JNI. - */ - public static int[] getAudioOutputDevices() { - if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) { - AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - ArrayList arrlist = new ArrayList(); - for (AudioDeviceInfo dev : audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)) { - /* Device cannot be opened */ - if (dev.getType() == AudioDeviceInfo.TYPE_TELEPHONY) { - continue; - } - arrlist.add(dev.getId()); - } - return ArrayListToArray(arrlist); - } else { - return NO_DEVICES; - } - } - - /** - * This method is called by SDL using JNI. - */ - public static int[] getAudioInputDevices() { - if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) { - AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - ArrayList arrlist = new ArrayList(); - for (AudioDeviceInfo dev : audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)) { - arrlist.add(dev.getId()); - } - return ArrayListToArray(arrlist); - } else { - return NO_DEVICES; - } - } - /** * This method is called by SDL using JNI. */ @@ -535,6 +495,6 @@ public class SDLAudioManager { public static native void removeAudioDevice(boolean isCapture, int deviceId); - public static native void addAudioDevice(boolean isCapture, int deviceId); + public static native void addAudioDevice(boolean isCapture, String name, int deviceId); } diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci index 441112b8..a2243cff 100644 --- a/build-scripts/SDL_migration.cocci +++ b/build-scripts/SDL_migration.cocci @@ -308,10 +308,10 @@ expression e; + SDL_PauseAudioDevice(e) | - SDL_PauseAudioDevice(e, 0) -+ SDL_PlayAudioDevice(e) ++ SDL_ResumeAudioDevice(e) | - SDL_PauseAudioDevice(e, SDL_FALSE) -+ SDL_PlayAudioDevice(e) ++ SDL_ResumeAudioDevice(e) ) @@ @@ -321,7 +321,7 @@ expression e, pause_on; + if (pause_on) { + SDL_PauseAudioDevice(e); + } else { -+ SDL_PlayAudioDevice(e); ++ SDL_ResumeAudioDevice(e); + } @@ -940,19 +940,19 @@ typedef SDL_ControllerTouchpadEvent, SDL_GamepadTouchpadEvent; @@ @@ - SDL_CONTROLLER_BUTTON_PADDLE1 -+ SDL_GAMEPAD_BUTTON_PADDLE1 ++ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 @@ @@ - SDL_CONTROLLER_BUTTON_PADDLE2 -+ SDL_GAMEPAD_BUTTON_PADDLE2 ++ SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 @@ @@ - SDL_CONTROLLER_BUTTON_PADDLE3 -+ SDL_GAMEPAD_BUTTON_PADDLE3 ++ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 @@ @@ - SDL_CONTROLLER_BUTTON_PADDLE4 -+ SDL_GAMEPAD_BUTTON_PADDLE4 ++ SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 @@ @@ - SDL_CONTROLLER_BUTTON_RIGHTSHOULDER @@ -2690,3 +2690,63 @@ typedef SDL_cond, SDL_Condition; - SDL_strtokr + SDL_strtok_r (...) +@@ +@@ +- SDL_ReadLE16 ++ SDL_ReadU16LE + (...) +@@ +@@ +- SDL_ReadLE32 ++ SDL_ReadU32LE + (...) +@@ +@@ +- SDL_ReadBE32 ++ SDL_ReadU32BE + (...) +@@ +@@ +- SDL_ReadBE16 ++ SDL_ReadU16BE + (...) +@@ +@@ +- SDL_ReadLE64 ++ SDL_ReadU64LE + (...) +@@ +@@ +- SDL_ReadBE64 ++ SDL_ReadU64BE + (...) +@@ +@@ +- SDL_WriteLE16 ++ SDL_WriteU16LE + (...) +@@ +@@ +- SDL_WriteBE16 ++ SDL_WriteU16BE + (...) +@@ +@@ +- SDL_WriteLE32 ++ SDL_WriteU32LE + (...) +@@ +@@ +- SDL_WriteBE32 ++ SDL_WriteU32BE + (...) +@@ +@@ +- SDL_WriteLE64 ++ SDL_WriteU64LE + (...) +@@ +@@ +- SDL_WriteBE64 ++ SDL_WriteU64BE + (...) diff --git a/cmake/FindRPi_BcmHost.cmake b/cmake/FindRPi_BcmHost.cmake deleted file mode 100644 index fe0b0661..00000000 --- a/cmake/FindRPi_BcmHost.cmake +++ /dev/null @@ -1,75 +0,0 @@ -include(FeatureSummary) -set_package_properties(RPi_BcmHost PROPERTIES - URL "https://github.com/raspberrypi/firmware" - DESCRIPTION "Broadcom VideoCore host API library" -) - -set(RPi_BcmHost_PKG_CONFIG_SPEC bcm_host) - -find_package(PkgConfig QUIET) -pkg_check_modules(PC_RPi_BcmHost QUIET ${RPi_BcmHost_PKG_CONFIG_SPEC}) - -find_library(RPi_BcmHost_bcm_host_LIBRARY - NAMES bcm_host - HINTS - ${PC_RPi_BcmHost_LIBRARY_DIRS} - /opt/vc/lib -) - -find_path(RPi_BcmHost_bcm_host_h_PATH - NAMES bcm_host.h - HINTS - ${PC_RPi_BcmHost_INCLUDE_DIRS} - /opt/vc/include -) - -if(PC_RPi_BcmHost_FOUND) - include("${CMAKE_CURRENT_LIST_DIR}/PkgConfigHelper.cmake") - get_flags_from_pkg_config("${RPi_BcmHost_bcm_host_LIBRARY}" "PC_RPi_BcmHost" "_RPi_BcmHost") -else() - set(_RPi_BcmHost_include_dirs - /opt/vc/include - /opt/vc/include/interface/vcos/pthreads - /opt/vc/include/interface/vmcs_host/linux - ) - set(_RPi_BcmHost_compile_options - -DUSE_VCHIQ_ARM - ) - set(_RPi_BcmHost_link_libraries - -lvcos -lvchiq_arm - ) - set(_RPi_BcmHost_link_options - -pthread - ) - set(_RPi_BcmHost_link_directories - /opt/vc/lib - ) -endif() - -set(RPi_BcmHost_INCLUDE_DIRS "${_RPi_BcmHost_include_dirs}" CACHE STRING "Extra include dirs of bcm_host") - -set(RPi_BcmHost_COMPILE_OPTIONS "${_RPi_BcmHost_compile_options}" CACHE STRING "Extra compile options of bcm_host") - -set(RPi_BcmHost_LINK_LIBRARIES "${_RPi_BcmHost_link_libraries}" CACHE STRING "Extra link libraries of bcm_host") - -set(RPi_BcmHost_LINK_OPTIONS "${_RPi_BcmHost_link_options}" CACHE STRING "Extra link flags of bcm_host") - -set(RPi_BcmHost_LINK_DIRECTORIES "${_RPi_BcmHost_link_directories}" CACHE PATH "Extra link directories of bcm_host") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(RPi_BcmHost - REQUIRED_VARS RPi_BcmHost_bcm_host_LIBRARY RPi_BcmHost_bcm_host_h_PATH -) - -if(RPi_BcmHost_FOUND) - if(NOT TARGET RPi_BcmHost::RPi_BcmHost) - add_library(RPi_BcmHost::RPi_BcmHost INTERFACE IMPORTED) - set_target_properties(RPi_BcmHost::RPi_BcmHost PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${RPi_BcmHost_INCLUDE_DIRS}" - INTERFACE_COMPILE_OPTIONS "${RPi_BcmHost_COMPILE_OPTIONS}" - INTERFACE_LINK_LIBRARIES "${RPi_BcmHost_LINK_LIBRARIES}" - INTERFACE_LINK_OPTIONS "${RPi_BcmHost_LINK_OPTIONS}" - INTERFACE_LINK_DIRECTORIES "${RPi_BcmHost_LINK_DIRECTORIES}" - ) - endif() -endif() diff --git a/cmake/FindRPi_BrcmEGL.cmake b/cmake/FindRPi_BrcmEGL.cmake deleted file mode 100644 index be4a4478..00000000 --- a/cmake/FindRPi_BrcmEGL.cmake +++ /dev/null @@ -1,59 +0,0 @@ -include(FeatureSummary) -set_package_properties(RPi_BrcmEGL PROPERTIES - URL "https://github.com/raspberrypi/firmware" - DESCRIPTION "Fake brcmEGL package for RPi" -) - -set(RPi_BrcmEGL_PKG_CONFIG_SPEC brcmegl) - -find_package(PkgConfig QUIET) -pkg_check_modules(PC_RPi_BrcmEGL QUIET ${RPi_BrcmEGL_PKG_CONFIG_SPEC}) - -find_package(RPi_BcmHost) - -find_library(RPi_BrcmEGL_brcmEGL_LIBRARY - NAMES brcmEGL - HINTS - ${PC_RPi_BrcmEGL_LIBRARY_DIRS} - /opt/vc/lib -) - -find_path(RPi_BrcmEGL_EGL_eglplatform_h_PATH - NAMES EGL/eglplatform.h - HINTS - ${PC_RPi_BrcmEGL_INCLUDE_DIRS} - /opt/vc/include -) - -if(PC_RPi_BrcmEGL_FOUND) - include("${CMAKE_CURRENT_LIST_DIR}/PkgConfigHelper.cmake") - get_flags_from_pkg_config("${RPi_BrcmEGL_brcmEGL_LIBRARY}" "PC_RPi_BrcmEGL" "_RPi_BrcmEGL") -endif() - -set(RPi_BrcmEGL_INCLUDE_DIRS "${_RPi_BrcmEGL_include_dirs}" CACHE STRING "Extra include dirs of brcmEGL") - -set(RPi_BrcmEGL_COMPILE_OPTIONS "${_RPi_BrcmEGL_compile_options}" CACHE STRING "Extra compile options of brcmEGL") - -set(RPi_BrcmEGL_LINK_LIBRARIES "${_RPi_BrcmEGL_link_libraries}" CACHE STRING "Extra link libraries of brcmEGL") - -set(RPi_BrcmEGL_LINK_OPTIONS "${_RPi_BrcmEGL_link_options}" CACHE STRING "Extra link flags of brcmEGL") - -set(RPi_BrcmEGL_LINK_DIRECTORIES "${_RPi_BrcmEGL_link_directories}" CACHE PATH "Extra link directories of brcmEGL") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(RPi_BrcmEGL - REQUIRED_VARS RPi_BrcmEGL_brcmEGL_LIBRARY RPi_BrcmEGL_EGL_eglext_brcm_h_PATH RPi_BcmHost_FOUND -) - -if(RPi_BrcmEGL_FOUND) - if(NOT TARGET RPi_BcmHost::RPi_BcmHost) - add_library(RPi_BcmHost::RPi_BcmHost INTERFACE IMPORTED) - set_target_properties(RPi_BcmHost::RPi_BcmHost PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${RPi_BrcmEGL_INCLUDE_DIRS}" - INTERFACE_COMPILE_OPTIONS "${RPi_BrcmEGL_COMPILE_OPTIONS}" - INTERFACE_LINK_LIBRARIES "${RPi_BrcmEGL_LINK_LIBRARIES};RPi_BcmHost::RPi_BcmHost" - INTERFACE_LINK_OPTIONS "${RPi_BrcmEGL_LINK_OPTIONS}" - INTERFACE_LINK_DIRECTORIES "${RPi_BrcmEGL_LINK_DIRECTORIES}" - ) - endif() -endif() diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 20bb1d8f..f12b7e3e 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1028,7 +1028,7 @@ macro(CheckHIDAPI) pkg_check_modules(PC_LIBUSB IMPORTED_TARGET ${LibUSB_PKG_CONFIG_SPEC}) if(PC_LIBUSB_FOUND) cmake_push_check_state() - list(APPEND CMAKE_REQUIRED_INCLUDES ${LibUSB_INCLUDE_DIRS}) + list(APPEND CMAKE_REQUIRED_INCLUDES ${PC_LIBUSB_INCLUDE_DIRS}) check_include_file(libusb.h HAVE_LIBUSB_H) cmake_pop_check_state() if(HAVE_LIBUSB_H) @@ -1041,7 +1041,7 @@ macro(CheckHIDAPI) if(USB_1.0_LIB) set(SDL_LIBUSB_DYNAMIC "\"${USB_1.0_LIB_SONAME}\"") endif() - sdl_link_dependency(hidapi INCLUDES $) + sdl_link_dependency(hidapi INCLUDES $) endif() endif() endif() @@ -1079,17 +1079,22 @@ endmacro() # - n/a macro(CheckRPI) if(SDL_RPI) - # presence of bcm_host means raspberry pi - find_package(RPi_BcmHost) - if(RPi_BcmHost_FOUND) + set(BCM_HOST_PKG_CONFIG_SPEC bcm_host) + set(BRCMEGL_PKG_CONFIG_SPEC brcmegl) + + set(original_PKG_CONFIG_PATH $ENV{PKG_CONFIG_PATH}) + set(ENV{PKG_CONFIG_PATH} "${original_PKG_CONFIG_PATH}:/opt/vc/lib/pkgconfig") + pkg_check_modules(PC_BCM_HOST IMPORTED_TARGET QUIET ${BCM_HOST_PKG_CONFIG_SPEC}) + pkg_check_modules(PC_BRCMEGL IMPORTED_TARGET QUIET ${BRCMEGL_PKG_CONFIG_SPEC}) + set(ENV{PKG_CONFIG_PATH} "${original_PKG_CONFIG_PATH}") + + if(TARGET PkgConfig::PC_BCM_HOST AND TARGET PkgConfig::PC_BRCMEGL) set(HAVE_RPI TRUE) - sdl_link_dependency(rpi LIBS RPi_BcmHost::RPi_BcmHost CMAKE_MODULE RPi_BcmHost PKG_CONFIG_SPECS ${RPi_BcmHost_PKG_CONFIG_SPEC}) - find_package(RPi_BrcmEGL) - if(SDL_VIDEO AND RPi_BrcmEGL_FOUND) + if(SDL_VIDEO) set(HAVE_SDL_VIDEO TRUE) set(SDL_VIDEO_DRIVER_RPI 1) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/video/raspberry/*.c") - sdl_link_dependency(rpi-video LIBS RPi_BrcmEGL::RPi_BrcmEGL CMAKE_MODULE RPi_BrcmEGL PKG_CONFIG_SPECS ${RPi_BrcmEGL_PKG_CONFIG_SPEC}) + sdl_link_dependency(rpi-video LIBS PkgConfig::PC_BCM_HOST PKG_CONFIG_PREFIX PC_BCM_HOST PKG_CONFIG_SPECS ${BCM_HOST_PKG_CONFIG_SPEC}) endif() endif() endif() diff --git a/cmake/sdlplatform.cmake b/cmake/sdlplatform.cmake index ebb2077f..b402cc03 100644 --- a/cmake/sdlplatform.cmake +++ b/cmake/sdlplatform.cmake @@ -14,6 +14,9 @@ macro(SDL_DetectCMakePlatform) set(SDL_CMAKE_PLATFORM tvOS) elseif(CMAKE_SYSTEM_NAME MATCHES ".*iOS.*") set(SDL_CMAKE_PLATFORM iOS) + elseif (CMAKE_SYSTEM_NAME MATCHES "visionOS") + set(SDL_CMAKE_PLATFORM visionOS) + set(VISIONOS ON) # CMAKE does not set this automatically yet endif() elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku.*") set(SDL_CMAKE_PLATFORM Haiku) diff --git a/cmake/test/CMakeLists.txt b/cmake/test/CMakeLists.txt index da7c1505..83ee81dc 100644 --- a/cmake/test/CMakeLists.txt +++ b/cmake/test/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.12) project(sdl_test LANGUAGES C) +if(WINDOWS_STORE) + enable_language(CXX) + add_compile_options(/ZW) + set_source_files_properties(ain_cli.c main_gui.c PROPERTIES LANGUAGE CXX) +endif() include(GenerateExportHeader) diff --git a/cmake/xxd.py b/cmake/xxd.py index 27afbcd3..5254cd1f 100755 --- a/cmake/xxd.py +++ b/cmake/xxd.py @@ -17,7 +17,7 @@ def main(): binary_data = args.input.open("rb").read() - with open(args.output, "w") as fout: + with args.output.open("w") as fout: fout.write("unsigned char {}[] = {{\n".format(varname)) bytes_written = 0 while bytes_written < len(binary_data): diff --git a/docs/README-cmake.md b/docs/README-cmake.md index 098f35d2..4accbcf5 100644 --- a/docs/README-cmake.md +++ b/docs/README-cmake.md @@ -35,6 +35,14 @@ cmake --install ~/build --prefix /usr/local # '--install' requires CMake This will install SDL to /usr/local. +### Building SDL tests + +You can build the SDL test programs by adding `-DSDL_TESTS=ON` to the first cmake command above: +```sh +cmake -S ~/sdl -B ~/build -DSDL_TEST_LIBRARY=ON -DSDL_TESTS=ON +``` +and then building normally. In this example, the test programs will be built and can be run from `~/build/tests/`. + ## Including SDL in your project SDL can be included in your project in 2 major ways: @@ -197,6 +205,22 @@ To use, set the following CMake variables when running CMake's configuration sta cmake ~/sdl -DCMAKE_TOOLCHAIN_FILE=~/sdl/build-scripts/cmake-toolchain-qnx-aarch64le.cmake -DSDL_X11=0 ``` +## SDL-specific CMake options + +SDL can be customized through (platform-specific) CMake options. +The following table shows generic options that are available for most platforms. +At the end of SDL CMake configuration, a table shows all CMake options along with its detected value. + +| CMake option | Valid values | Description | +|-------------------------------|--------------|-----------------------------------------------------------------------------------------------------| +| `-DSDL_SHARED=` | `ON`/`OFF` | Build SDL shared library (not all platforms support this) (`libSDL3.so`/`libSDL3.dylib`/`SDL3.dll`) | +| `-DSDL_STATIC=` | `ON`/`OFF` | Build SDL static library (`libSDL3.a`/`SDL3-static.lib`) | +| `-DSDL_TEST_LIBRARY=` | `ON`/`OFF` | Build SDL test library (`libSDL3_test.a`/`SDL3_test.lib`) | +| `-DSDL_TESTS=` | `ON`/`OFF` | Build SDL test programs (**requires `-DSDL_TEST_LIBRARY=ON`**) | +| `-DSDL_DISABLE_INSTALL=` | `ON`/`OFF` | Don't create a SDL install target | +| `-DSDL_DISABLE_INSTALL_DOCS=` | `ON`/`OFF` | Don't install the SDL documentation | +| `-DSDL_INSTALL_TESTS=` | `ON`/`OFF` | Install the SDL test programs | + ## Help, it doesn't work! Below, a SDL3 CMake project can be found that builds 99.9% of time (assuming you have internet connectivity). diff --git a/docs/README-migration.md b/docs/README-migration.md index 19b30414..21ac569f 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -53,13 +53,128 @@ The following structures have been renamed: ## SDL_audio.h +The audio subsystem in SDL3 is dramatically different than SDL2. The primary way to play audio is no longer an audio callback; instead you bind SDL_AudioStreams to devices. + +The SDL 1.2 audio compatibility API has also been removed, as it was a simplified version of the audio callback interface. + +SDL3 will not implicitly initialize the audio subsystem on your behalf if you open a device without doing so. Please explicitly call SDL_Init(SDL_INIT_AUDIO) at some point. + +If your app depends on the callback method, there is a similar approach you can take. But first, this is the new approach: + +In SDL2, you might have done something like this to play audio: + +```c + void SDLCALL MyAudioCallback(void *userdata, Uint8 * stream, int len) + { + /* calculate a little more audio here, maybe using `userdata`, write it to `stream` */ + } + + /* ...somewhere near startup... */ + SDL_AudioSpec my_desired_audio_format; + SDL_zero(my_desired_audio_format); + my_desired_audio_format.format = AUDIO_S16; + my_desired_audio_format.channels = 2; + my_desired_audio_format.freq = 44100; + my_desired_audio_format.samples = 1024; + my_desired_audio_format.callback = MyAudioCallback; + my_desired_audio_format.userdata = &my_audio_callback_user_data; + SDL_AudioDeviceID my_audio_device = SDL_OpenAudioDevice(NULL, 0, &my_desired_audio_format, NULL, 0); + SDL_PauseAudioDevice(my_audio_device, 0); +``` + +in SDL3: + +```c + /* ...somewhere near startup... */ + SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 }; + SDL_AudioDeviceID my_audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec); + SDL_AudioSteam *stream = SDL_CreateAndBindAudioStream(my_audio_device, &spec); + + /* ...in your main loop... */ + /* calculate a little more audio into `buf`, add it to `stream` */ + SDL_PutAudioStreamData(stream, buf, buflen); +``` + +If you absolutely require the callback method, SDL_AudioStreams can use a callback whenever more data is to be read from them, which can be used to simulate SDL2 semantics: + +```c + void SDLCALL MyAudioCallback(SDL_AudioStream *stream, int len, void *userdata) + { + /* calculate a little more audio here, maybe using `userdata`, write it to `stream` */ + SDL_PutAudioStreamData(stream, newdata, len); + } + + /* ...somewhere near startup... */ + SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 }; + SDL_AudioDeviceID my_audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec); + SDL_AudioSteam *stream = SDL_CreateAndBindAudioStream(my_audio_device, &spec); + SDL_SetAudioStreamGetCallback(stream, MyAudioCallback); + + /* MyAudioCallback will be called whenever the device requests more audio data. */ +``` + SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSystem() and SDL_QuitSubSystem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint. -SDL_PauseAudioDevice() is only used to pause audio playback. Use SDL_PlayAudioDevice() to start playing audio. +The `SDL_AUDIO_ALLOW_*` symbols have been removed; now one may request the format they desire from the audio device, but ultimately SDL_AudioStream will manage the difference. One can use SDL_GetAudioDeviceFormat() to see what the final format is, if any "allowed" changes should be accomodated by the app. + +SDL_AudioDeviceID now represents both an open audio device's handle (a "logical" device) and the instance ID that the hardware owns as long as it exists on the system (a "physical" device). The separation between device instances and device indexes is gone. + +Devices are opened by physical device instance ID, and a new logical instance ID is generated by the open operation; This allows any device to be opened multiple times, possibly by unrelated pieces of code. SDL will manage the logical devices to provide a single stream of audio to the physical device behind the scenes. + +Devices are not opened by an arbitrary string name anymore, but by device instance ID (or magic numbers to request a reasonable default, like a NULL string in SDL2). In SDL2, the string was used to open both a standard list of system devices, but also allowed for arbitrary devices, such as hostnames of network sound servers. In SDL3, many of the backends that supported arbitrary device names are obsolete and have been removed; of those that remain, arbitrary devices will be opened with a default device ID and an SDL_hint, so specific end-users can set an environment variable to fit their needs and apps don't have to concern themselves with it. + +Many functions that would accept a device index and an `iscapture` parameter now just take an SDL_AudioDeviceID, as they are unique across all devices, instead of separate indices into output and capture device lists. + +Rather than iterating over audio devices using a device index, there is a new function, SDL_GetAudioDevices(), to get the current list of devices, and new functions to get information about devices from their instance ID: + +```c +{ + if (SDL_InitSubSystem(SDL_INIT_AUDIO) == 0) { + int i, num_devices; + SDL_AudioDeviceID *devices = SDL_GetAudioDevices(/*iscapture=*/SDL_FALSE, &num_devices); + if (devices) { + for (i = 0; i < num_devices; ++i) { + SDL_AudioDeviceID instance_id = devices[i]; + char *name = SDL_GetAudioDeviceName(instance_id); + SDL_Log("AudioDevice %" SDL_PRIu32 ": %s\n", instance_id, name); + SDL_free(name); + } + SDL_free(devices); + } + SDL_QuitSubSystem(SDL_INIT_AUDIO); + } +} +``` + +SDL_LockAudioDevice() and SDL_UnlockAudioDevice() have been removed, since there is no callback in another thread to protect. SDL's audio subsystem and SDL_AudioStream maintain their own locks internally, so audio streams are safe to use from any thread. If the app assigns a callback to a specific stream, it can use the stream's lock through SDL_LockAudioStream() if necessary. + +SDL_PauseAudioDevice() no longer takes a second argument; it always pauses the device. To unpause, use SDL_ResumeAudioDevice(). + +Audio devices, opened by SDL_OpenAudioDevice(), no longer start in a paused state, as they don't begin processing audio until a stream is bound. + +SDL_GetAudioDeviceStatus() has been removed; there is now SDL_IsAudioDevicePaused(). + +SDL_QueueAudio(), SDL_DequeueAudio, and SDL_ClearQueuedAudio and SDL_GetQueuedAudioSize() have been removed; an SDL_AudioStream bound to a device provides the exact same functionality. + +APIs that use channel counts used to use a Uint8 for the channel; now they use int. + +SDL_AudioSpec has been reduced; now it only holds format, channel, and sample rate. SDL_GetSilenceValueForFormat() can provide the information from the SDL_AudioSpec's `silence` field. The other SDL2 SDL_AudioSpec fields aren't relevant anymore. + +SDL_GetAudioDeviceSpec() is removed; use SDL_GetAudioDeviceFormat() instead. + +SDL_GetDefaultAudioInfo() is removed; SDL_GetAudioDeviceFormat() with SDL_AUDIO_DEVICE_DEFAULT_OUTPUT or SDL_AUDIO_DEVICE_DEFAULT_CAPTURE. There is no replacement for querying the default device name; the string is no longer used to open devices, and SDL3 will migrate between physical devices on the fly if the system default changes, so if you must show this to the user, a generic name like "System default" is recommended. + +SDL_MixAudio() has been removed, as it relied on legacy SDL 1.2 quirks; SDL_MixAudioFormat() remains and offers the same functionality. + +SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSystem() and SDL_QuitSubSystem() with SDL_INIT_AUDIO, which will properly refcount the subsystems. You can choose a specific audio driver using SDL_AUDIO_DRIVER hint. SDL_FreeWAV has been removed and calls can be replaced with SDL_free. -SDL_AudioCVT interface is removed, SDL_AudioStream interface or SDL_ConvertAudioSamples() helper function can be used. +SDL_LoadWAV() is a proper function now and no longer a macro (but offers the same functionality otherwise). + +SDL_LoadWAV_RW() and SDL_LoadWAV() return an int now: zero on success, -1 on error, like most of SDL. They no longer return a pointer to an SDL_AudioSpec. + +SDL_AudioCVT interface has been removed, the SDL_AudioStream interface (for audio supplied in pieces) or the new SDL_ConvertAudioSamples() function (for converting a complete audio buffer in one call) can be used instead. Code that used to look like this: ```c @@ -75,8 +190,9 @@ should be changed to: ```c Uint8 *dst_data = NULL; int dst_len = 0; - if (SDL_ConvertAudioSamples(src_format, src_channels, src_rate, src_data, src_len - dst_format, dst_channels, dst_rate, &dst_data, &dst_len) < 0) { + const SDL_AudioSpec src_spec = { src_format, src_channels, src_rate }; + const SDL_AudioSpec dst_spec = { dst_format, dst_channels, dst_rate }; + if (SDL_ConvertAudioSamples(&src_spec, src_data, src_len, &dst_spec, &dst_data, &dst_len) < 0) { /* error */ } do_something(dst_data, dst_len); @@ -103,9 +219,13 @@ If you need to convert U16 audio data to a still-supported format at runtime, th } ``` -In SDL2, SDL_AudioStream would convert/resample audio data during input (via SDL_AudioStreamPut). In SDL3, it does this work when requesting audio (via SDL_GetAudioStreamData, which would have been SDL_AudioStreamPut in SDL2. The way you use an AudioStream is roughly the same, just be aware that the workload moved to a different phase. +All remaining `AUDIO_*` symbols have been renamed to `SDL_AUDIO_*` for API consistency, but othewise are identical in value and usage. + +In SDL2, SDL_AudioStream would convert/resample audio data during input (via SDL_AudioStreamPut). In SDL3, it does this work when requesting audio (via SDL_GetAudioStreamData, which would have been SDL_AudioStreamGet in SDL2). The way you use an AudioStream is roughly the same, just be aware that the workload moved to a different phase. + In SDL2, SDL_AudioStreamAvailable() returns 0 if passed a NULL stream. In SDL3, the equivalent SDL_GetAudioStreamAvailable() call returns -1 and sets an error string, which matches other audiostream APIs' behavior. +In SDL2, SDL_AUDIODEVICEREMOVED events would fire for open devices with the `which` field set to the SDL_AudioDeviceID of the lost device, and in later SDL2 releases, would also fire this event with a `which` field of zero for unopened devices, to signify that the app might want to refresh the available device list. In SDL3, this event works the same, except it won't ever fire with a zero; in this case it'll return the physical device's SDL_AudioDeviceID. Any still-open SDL_AudioDeviceIDs generated from this device with SDL_OpenAudioDevice() will also fire a separate event. The following functions have been renamed: * SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable() @@ -118,17 +238,25 @@ The following functions have been renamed: The following functions have been removed: +* SDL_GetNumAudioDevices() +* SDL_GetAudioDeviceSpec() * SDL_ConvertAudio() * SDL_BuildAudioCVT() * SDL_OpenAudio() * SDL_CloseAudio() * SDL_PauseAudio() * SDL_GetAudioStatus() +* SDL_GetAudioDeviceStatus() +* SDL_GetDefaultAudioInfo() * SDL_LockAudio() +* SDL_LockAudioDevice() * SDL_UnlockAudio() +* SDL_UnlockAudioDevice() * SDL_MixAudio() - -Use the SDL_AudioDevice functions instead. +* SDL_QueueAudio() +* SDL_DequeueAudio() +* SDL_ClearAudioQueue() +* SDL_GetQueuedAudioSize() The following symbols have been renamed: * AUDIO_F32 => SDL_AUDIO_F32 @@ -380,10 +508,10 @@ The following symbols have been renamed: * SDL_CONTROLLER_BUTTON_LEFTSTICK => SDL_GAMEPAD_BUTTON_LEFT_STICK * SDL_CONTROLLER_BUTTON_MAX => SDL_GAMEPAD_BUTTON_MAX * SDL_CONTROLLER_BUTTON_MISC1 => SDL_GAMEPAD_BUTTON_MISC1 -* SDL_CONTROLLER_BUTTON_PADDLE1 => SDL_GAMEPAD_BUTTON_PADDLE1 -* SDL_CONTROLLER_BUTTON_PADDLE2 => SDL_GAMEPAD_BUTTON_PADDLE2 -* SDL_CONTROLLER_BUTTON_PADDLE3 => SDL_GAMEPAD_BUTTON_PADDLE3 -* SDL_CONTROLLER_BUTTON_PADDLE4 => SDL_GAMEPAD_BUTTON_PADDLE4 +* SDL_CONTROLLER_BUTTON_PADDLE1 => SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 +* SDL_CONTROLLER_BUTTON_PADDLE2 => SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 +* SDL_CONTROLLER_BUTTON_PADDLE3 => SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 +* SDL_CONTROLLER_BUTTON_PADDLE4 => SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 * SDL_CONTROLLER_BUTTON_RIGHTSHOULDER => SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER * SDL_CONTROLLER_BUTTON_RIGHTSTICK => SDL_GAMEPAD_BUTTON_RIGHT_STICK * SDL_CONTROLLER_BUTTON_START => SDL_GAMEPAD_BUTTON_START @@ -698,6 +826,8 @@ which index is the "opengl" or whatnot driver, you can just pass that string dir here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL to decide for you. +The SDL_RENDERER_TARGETTEXTURE flag has been removed, all current renderers support target texture functionality. + When a renderer is created, it will automatically set the logical size to the size of the window in points. For high DPI displays, this will set up scaling from points to pixels. You can disable this scaling with: @@ -780,33 +910,28 @@ size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxn But now they look more like POSIX: ```c -Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size); -Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size); +size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size); +size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size); ``` -SDL_RWread() previously returned 0 at end of file or other error. Now it returns the number of bytes read, 0 for end of file, -1 for another error, or -2 for data not ready (in the case of a non-blocking context). - Code that used to look like this: ``` size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) { - return (size_t)SDL_RWread(stream, ptr, size, nitems); + return SDL_RWread(stream, ptr, size, nitems); } ``` should be changed to: ``` size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream) { - Sint64 amount = SDL_RWread(stream, ptr, size * nitems); - if (amount <= 0) { - return 0; + if (size > 0 && nitems > 0) { + return SDL_RWread(stream, ptr, size * nitems) / size; } - return (size_t)(amount / size); + return 0; } ``` -Similarly, SDL_RWwrite() can return -2 for data not ready in the case of a non-blocking context. There is currently no way to create a non-blocking context, we have simply defined the semantic for your own custom SDL_RWops object. - SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application. You can implement this in your own code easily: @@ -814,23 +939,7 @@ You can implement this in your own code easily: #include -static Sint64 SDLCALL -stdio_size(SDL_RWops * context) -{ - Sint64 pos, size; - - pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR); - if (pos < 0) { - return -1; - } - size = SDL_RWseek(context, 0, SDL_RW_SEEK_END); - - SDL_RWseek(context, pos, SDL_RW_SEEK_SET); - 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; @@ -858,54 +967,46 @@ stdio_seek(SDL_RWops * context, Sint64 offset, int whence) return SDL_Error(SDL_EFSEEK); } -static Sint64 SDLCALL -stdio_read(SDL_RWops * context, void *ptr, Sint64 size) +static size_t SDLCALL stdio_read(SDL_RWops *context, void *ptr, size_t size) { - size_t nread; + size_t bytes; - nread = fread(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); - if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) { - return SDL_Error(SDL_EFREAD); + bytes = fread(ptr, 1, size, (FILE *)context->hidden.stdio.fp); + if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) { + SDL_Error(SDL_EFREAD); } - return (Sint64) nread; + return bytes; } -static Sint64 SDLCALL -stdio_write(SDL_RWops * context, const void *ptr, Sint64 size) +static size_t SDLCALL stdio_write(SDL_RWops *context, const void *ptr, size_t size) { - size_t nwrote; + size_t bytes; - nwrote = fwrite(ptr, 1, (size_t) size, (FILE *)context->hidden.stdio.fp); - if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) { - return SDL_Error(SDL_EFWRITE); + bytes = fwrite(ptr, 1, size, (FILE *)context->hidden.stdio.fp); + if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) { + SDL_Error(SDL_EFWRITE); } - return (Sint64) nwrote; + return bytes; } -static int SDLCALL -stdio_close(SDL_RWops * context) +static int SDLCALL stdio_close(SDL_RWops *context) { int status = 0; - if (context) { - if (context->hidden.stdio.autoclose) { - /* WARNING: Check the return value here! */ - if (fclose((FILE *)context->hidden.stdio.fp) != 0) { - status = SDL_Error(SDL_EFWRITE); - } + if (context->hidden.stdio.autoclose) { + if (fclose((FILE *)context->hidden.stdio.fp) != 0) { + status = SDL_Error(SDL_EFWRITE); } - SDL_DestroyRW(context); } + SDL_DestroyRW(context); return status; } -SDL_RWops * -SDL_RWFromFP(void *fp, SDL_bool autoclose) +SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose) { SDL_RWops *rwops = NULL; rwops = SDL_CreateRW(); if (rwops != NULL) { - rwops->size = stdio_size; rwops->seek = stdio_seek; rwops->read = stdio_read; rwops->write = stdio_write; @@ -918,10 +1019,23 @@ SDL_RWFromFP(void *fp, SDL_bool autoclose) } ``` +The functions SDL_ReadU8(), SDL_ReadU16LE(), SDL_ReadU16BE(), SDL_ReadU32LE(), SDL_ReadU32BE(), SDL_ReadU64LE(), and SDL_ReadU64BE() now return SDL_TRUE if the read succeeded and SDL_FALSE if it didn't, and store the data in a pointer passed in as a parameter. The following functions have been renamed: * SDL_AllocRW() => SDL_CreateRW() * SDL_FreeRW() => SDL_DestroyRW() +* SDL_ReadBE16() => SDL_ReadU16BE() +* SDL_ReadBE32() => SDL_ReadU32BE() +* SDL_ReadBE64() => SDL_ReadU64BE() +* SDL_ReadLE16() => SDL_ReadU16LE() +* SDL_ReadLE32() => SDL_ReadU32LE() +* SDL_ReadLE64() => SDL_ReadU64LE() +* SDL_WriteBE16() => SDL_WriteU16BE() +* SDL_WriteBE32() => SDL_WriteU32BE() +* SDL_WriteBE64() => SDL_WriteU64BE() +* SDL_WriteLE16() => SDL_WriteU16LE() +* SDL_WriteLE32() => SDL_WriteU32LE() +* SDL_WriteLE64() => SDL_WriteU64LE() ## SDL_sensor.h diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h index 1dd39fc6..fbef6236 100644 --- a/include/SDL3/SDL_audio.h +++ b/include/SDL3/SDL_audio.h @@ -19,12 +19,10 @@ 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 * - * \brief Access to the raw audio mixing buffer for the SDL library. + * \brief Audio functionality for the SDL library. */ #ifndef SDL_audio_h_ @@ -43,6 +41,17 @@ extern "C" { #endif +/* + * 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) + */ + /** * \brief Audio format flags. * @@ -128,63 +137,37 @@ typedef Uint16 SDL_AudioFormat; #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. + * SDL Audio Device instance IDs. */ -typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, - int len); +typedef Uint32 SDL_AudioDeviceID; + +#define SDL_AUDIO_DEVICE_DEFAULT_OUTPUT ((SDL_AudioDeviceID) 0xFFFFFFFF) +#define SDL_AUDIO_DEVICE_DEFAULT_CAPTURE ((SDL_AudioDeviceID) 0xFFFFFFFE) -/** - * The calculated values in this structure are calculated by SDL_OpenAudioDevice(). - * - * 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). */ + int channels; /**< Number of channels: 1 mono, 2 stereo, etc */ + int freq; /**< sample rate: sample frames per second */ } SDL_AudioSpec; +/* SDL_AudioStream is an audio conversion interface. + - 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. + - It can handle input/output format changes on the fly. + - You push data as you have it, and pull it when you need it + - It can also function as a basic audio data queue even if you + just have sound that needs to pass from one place to another. + - You can hook callbacks up to them when more data is added or + requested, to manage data on-the-fly. + */ +struct SDL_AudioStream; /* this is opaque to the outside world. */ +typedef struct SDL_AudioStream SDL_AudioStream; + /* Function prototypes */ @@ -211,6 +194,8 @@ typedef struct SDL_AudioSpec * * \returns the number of built-in audio drivers. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_GetAudioDriver @@ -233,6 +218,8 @@ extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); * \returns the name of the audio driver at the requested index, or NULL if an * invalid index was specified. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_GetNumAudioDrivers @@ -252,454 +239,413 @@ extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); * \returns the name of the current audio driver or NULL if no driver has been * initialized. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. */ extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); /** - * SDL Audio Device IDs. - */ -typedef Uint32 SDL_AudioDeviceID; - -/** - * Get the number of built-in audio devices. + * Get a list of currently-connected audio output devices. * - * This function is only valid after successfully initializing the audio - * subsystem. + * This returns of list of available devices that play sound, perhaps to + * speakers or headphones ("output" devices). If you want devices that record + * audio, like a microphone ("capture" devices), use + * SDL_GetAudioCaptureDevices() instead. * - * 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 only returns a list of physical devices; it will not have any device + * IDs returned by SDL_OpenAudioDevice(). * - * 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(). + * \param count a pointer filled in with the number of devices returned + * \returns a 0 terminated array of device instance IDs which should be freed + * with SDL_free(), or NULL on error; call SDL_GetError() for more + * details. * - * 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. + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetAudioDeviceName * \sa SDL_OpenAudioDevice + * \sa SDL_GetAudioCaptureDevices */ -extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); +extern DECLSPEC SDL_AudioDeviceID *SDLCALL SDL_GetAudioOutputDevices(int *count); + +/** + * Get a list of currently-connected audio capture devices. + * + * This returns of list of available devices that record audio, like a + * microphone ("capture" devices). If you want devices that play sound, + * perhaps to speakers or headphones ("output" devices), use + * SDL_GetAudioOutputDevices() instead. + * + * This only returns a list of physical devices; it will not have any device + * IDs returned by SDL_OpenAudioDevice(). + * + * \param count a pointer filled in with the number of devices returned + * \returns a 0 terminated array of device instance IDs which should be freed + * with SDL_free(), or NULL on error; call SDL_GetError() for more + * details. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_OpenAudioDevice + * \sa SDL_GetAudioOutputDevices + */ +extern DECLSPEC SDL_AudioDeviceID *SDLCALL SDL_GetAudioCaptureDevices(int *count); /** * 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. The caller should + * call SDL_free on the return value when done with it. * - * 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 devid the instance ID of the device to query. + * \returns the name of the audio device, or NULL on error. * - * \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. + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. * * \sa SDL_GetNumAudioDevices * \sa SDL_GetDefaultAudioInfo */ -extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, - int iscapture); +extern DECLSPEC char *SDLCALL SDL_GetAudioDeviceName(SDL_AudioDeviceID devid); /** - * Get the preferred audio format of a specific audio device. + * Get the current 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. + * For an opened device, this will report the format the device is currently + * using. If the device isn't yet opened, this will report the device's + * preferred format (or a reasonable default if this can't be determined). * - * `spec` will be filled with the sample rate, sample format, and channel - * count. + * You may also specify SDL_AUDIO_DEVICE_DEFAULT_OUTPUT or + * SDL_AUDIO_DEVICE_DEFAULT_CAPTURE here, which is useful for getting a + * reasonable recommendation before opening the system-recommended default + * device. * - * \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. + * \param devid the instance ID of the device to query. + * \param spec On return, will be filled with device 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 3.0.0. - * - * \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 or a negative error code on failure; call - * SDL_GetError() for more information. + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetAudioDeviceName - * \sa SDL_GetAudioDeviceSpec - * \sa SDL_OpenAudioDevice */ -extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, - SDL_AudioSpec *spec, - int iscapture); +extern DECLSPEC int SDLCALL SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec); /** * Open a specific audio device. * - * Passing in a `device` name of NULL requests the most reasonable default. - * 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. + * You can open both output and capture devices through this function. Output + * devices will take data from bound audio streams, mix it, and send it to the + * hardware. Capture devices will feed any bound audio streams with a copy of + * any incoming data. * - * An opened audio device starts out paused, and should be enabled for playing - * by calling SDL_PlayAudioDevice(devid) 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. + * An opened audio device starts out with no audio streams bound. To start + * audio playing, bind a stream and supply audio data to it. Unlike SDL2, + * there is no audio callback; you only bind audio streams and make sure they + * have data flowing into them (although, as an optional feature, each audio + * stream may have its own callback, which can be used to simulate SDL2's + * semantics). * - * 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. + * If you don't care about opening a specific device, pass a `devid` of either + * `SDL_AUDIO_DEVICE_DEFAULT_OUTPUT` or `SDL_AUDIO_DEVICE_DEFAULT_CAPTURE`. In + * this case, SDL will try to pick the most reasonable default, and may also + * switch between physical devices seamlessly later, if the most reasonable + * default changes during the lifetime of this opened device (user changed the + * default in the OS's system preferences, the default got unplugged so the + * system jumped to a new default, the user plugged in headphones on a mobile + * device, etc). Unless you have a good reason to choose a specific device, + * this is probably what you want. * - * Managing the audio spec via 'desired' and 'obtained': + * You may request a specific format for the audio device, but there is no + * promise the device will honor that request for several reasons. As such, + * it's only meant to be a hint as to what data your app will provide. Audio + * streams will accept data in whatever format you specify and manage + * conversion for you as appropriate. SDL_GetAudioDeviceFormat can tell you + * the preferred format for the device before opening and the actual format + * the device is using after opening. * - * When filling in the desired audio spec structure: + * It's legal to open the same device ID more than once; each successful open + * will generate a new logical SDL_AudioDeviceID that is managed separately + * from others on the same physical device. This allows libraries to open a + * device separately from the main app and bind its own streams without + * conflicting. * - * - `desired->freq` should be the frequency in sample-frames-per-second (Hz). - * - `desired->format` should be the audio format (`SDL_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. + * It is also legal to open a device ID returned by a previous call to this + * function; doing so just creates another logical device on the same physical + * device. This may be useful for making logical groupings of audio streams. * - * `allowed_changes` can have the following flags OR'd together: + * This function returns the opened device ID on success. This is a new, + * unique SDL_AudioDeviceID that represents a logical device. * - * - `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` + * Some backends might offer arbitrary devices (for example, a networked audio + * protocol that can connect to an arbitrary server). For these, as a change + * from SDL2, you should open a default device ID and use an SDL hint to + * specify the target if you care, or otherwise let the backend figure out a + * reasonable default. Most backends don't offer anything like this, and often + * this would be an end user setting an environment variable for their custom + * need, and not something an application should specifically manage. * - * 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. + * When done with an audio device, possibly at the end of the app's life, one + * should call SDL_CloseAudioDevice() on the returned device id. * - * 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. + * \param devid the device instance id to open, or + * SDL_AUDIO_DEVICE_DEFAULT_OUTPUT or + * SDL_AUDIO_DEVICE_DEFAULT_CAPTURE for the most reasonable + * default device. + * \param spec the requested device configuration. Can be NULL to use + * reasonable defaults. + * \returns The device ID on success, 0 on error; call SDL_GetError() for more + * information. * - * 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 - * \param obtained an SDL_AudioSpec structure filled in with the actual output - * format - * \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. + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. * * \sa SDL_CloseAudioDevice - * \sa SDL_GetAudioDeviceName - * \sa SDL_LockAudioDevice - * \sa SDL_PlayAudioDevice - * \sa SDL_PauseAudioDevice - * \sa SDL_UnlockAudioDevice + * \sa SDL_GetAudioDeviceFormat */ -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; - -/** - * 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 3.0.0. - * - * \sa SDL_PlayAudioDevice - * \sa SDL_PauseAudioDevice - */ -extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); -/* @} *//* Audio State */ - -/** - * Use this function to play audio on a specified device. - * - * Newly-opened audio devices start in the paused state, so you must call this - * function 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. - * - * \param dev a device opened by SDL_OpenAudioDevice() - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_LockAudioDevice - * \sa SDL_PauseAudioDevice - */ -extern DECLSPEC int SDLCALL SDL_PlayAudioDevice(SDL_AudioDeviceID dev); - - +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec); /** * Use this function to pause audio playback on a specified device. * - * This function pauses the audio callback processing for a given 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. + * This function pauses audio processing for a given device. Any bound audio + * streams will not progress, and no audio will be generated. Pausing one + * device does not prevent other unpaused devices from running. * - * 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(). + * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app + * has to bind a stream before any audio will flow. Pausing a paused device is + * a legal no-op. + * + * Pausing a device can be useful to halt all audio without unbinding all the + * audio streams. This might be useful while a game is paused, or a level is + * loading, etc. + * + * Physical devices can not be paused or unpaused, only logical devices + * created through SDL_OpenAudioDevice() can be. * * \param dev a device opened by SDL_OpenAudioDevice() * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * - * \sa SDL_LockAudioDevice - * \sa SDL_PlayAudioDevice + * \sa SDL_ResumeAudioDevice + * \sa SDL_IsAudioDevicePaused */ extern DECLSPEC int SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev); - /** - * Load the audio data of a WAVE file into memory. + * Use this function to unpause audio playback on a specified device. * - * 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. + * This function unpauses audio processing for a given device that has + * previously been paused with SDL_PauseAudioDevice(). Once unpaused, any + * bound audio streams will begin to progress again, and audio can be + * generated. * - * 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. + * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app + * has to bind a stream before any audio will flow. Unpausing an unpaused + * device is a legal no-op. * - * 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. + * Physical devices can not be paused or unpaused, only logical devices + * created through SDL_OpenAudioDevice() can be. * - * It's necessary to use SDL_free() to free the audio data returned in - * `audio_buf` when it is no longer used. + * \param dev a device opened by SDL_OpenAudioDevice() + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * 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 SDL_TRUE, calls SDL_RWclose() on `src` before returning, - * even in the case of an error - * \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_free() to dispose of it. + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. * - * \sa SDL_free - * \sa SDL_LoadWAV + * \sa SDL_ResumeAudioDevice + * \sa SDL_IsAudioDevicePaused */ -extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, - SDL_bool freesrc, - SDL_AudioSpec * spec, - Uint8 ** audio_buf, - Uint32 * audio_len); +extern DECLSPEC int SDLCALL SDL_ResumeAudioDevice(SDL_AudioDeviceID dev); /** - * Loads a WAV from a file. - * Compatibility convenience function. + * Use this function to query if an audio device is paused. + * + * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app + * has to bind a stream before any audio will flow. + * + * Physical devices can not be paused or unpaused, only logical devices + * created through SDL_OpenAudioDevice() can be. Physical and invalid device + * IDs will report themselves as unpaused here. + * + * \param dev a device opened by SDL_OpenAudioDevice() + * \returns SDL_TRUE if device is valid and paused, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_PauseAudioDevice + * \sa SDL_ResumeAudioDevice + * \sa SDL_IsAudioDevicePaused */ -#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ - SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) +extern DECLSPEC SDL_bool SDLCALL SDL_IsAudioDevicePaused(SDL_AudioDeviceID dev); - -/* SDL_AudioStream is an audio conversion interface. - - 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 - - It can also function as a basic audio data queue even if you - just have sound that needs to pass from one place to another. +/** + * Close a previously-opened audio device. + * + * The application should close open audio devices once they are no longer + * needed. + * + * 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 if terminating immediately afterwards. + * + * \param devid an audio device id previously returned by + * SDL_OpenAudioDevice() + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_OpenAudioDevice */ -struct SDL_AudioStream; /* this is opaque to the outside world. */ -typedef struct SDL_AudioStream SDL_AudioStream; +extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid); + +/** + * Bind a list of audio streams to an audio device. + * + * Audio data will flow through any bound streams. For an output device, data + * for all bound streams will be mixed together and fed to the device. For a + * capture device, a copy of recorded data will be provided to each bound + * stream. + * + * Audio streams can only be bound to an open device. This operation is + * atomic--all streams bound in the same call will start processing at the + * same time, so they can stay in sync. Also: either all streams will be bound + * or none of them will be. + * + * It is an error to bind an already-bound stream; it must be explicitly + * unbound first. + * + * Binding a stream to a device will set its output format for output devices, + * and its input format for capture devices, so they match the device's + * settings. The caller is welcome to change the other end of the stream's + * format at any time. + * + * \param devid an audio device to bind a stream to. + * \param streams an array of audio streams to unbind. + * \param num_streams Number streams listed in the `streams` array. + * \returns 0 on success, -1 on error; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStreams + * \sa SDL_UnbindAudioStream + * \sa SDL_GetAudioStreamBinding + */ +extern DECLSPEC int SDLCALL SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int num_streams); + +/** + * Bind a single audio stream to an audio device. + * + * This is a convenience function, equivalent to calling + * `SDL_BindAudioStreams(devid, &stream, 1)`. + * + * \param devid an audio device to bind a stream to. + * \param stream an audio stream to bind to a device. + * \returns 0 on success, -1 on error; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStreams + * \sa SDL_UnbindAudioStream + * \sa SDL_GetAudioStreamBinding + */ +extern DECLSPEC int SDLCALL SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream); + +/** + * Unbind a list of audio streams from their audio devices. + * + * The streams being unbound do not all have to be on the same device. All + * streams on the same device will be unbound atomically (data will stop + * flowing through them all unbound streams on the same device at the same + * time). + * + * Unbinding a stream that isn't bound to a device is a legal no-op. + * + * \param streams an array of audio streams to unbind. + * \param num_streams Number streams listed in the `streams` array. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_BindAudioStreams + * \sa SDL_BindAudioStream + * \sa SDL_UnbindAudioStream + * \sa SDL_GetAudioStreamBinding + */ +extern DECLSPEC void SDLCALL SDL_UnbindAudioStreams(SDL_AudioStream **streams, int num_streams); + +/** + * Unbind a single audio stream from its audio device. + * + * This is a convenience function, equivalent to calling + * `SDL_UnbindAudioStreams(&stream, 1)`. + * + * \param stream an audio stream to unbind from a device. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_BindAudioStream + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStreams + * \sa SDL_GetAudioStreamBinding + */ +extern DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream); + +/** + * Query an audio stream for its currently-bound device. + * + * This reports the audio device that an audio stream is currently bound to. + * + * If not bound, or invalid, this returns zero, which is not a valid device + * ID. + * + * \param stream the audio stream to query. + * \returns The bound audio device, or 0 if not bound or invalid. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_BindAudioStream + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStream + * \sa SDL_UnbindAudioStreams + */ +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_GetAudioStreamBinding(SDL_AudioStream *stream); + /** * 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 + * \param src_spec The format details of the input audio + * \param dst_spec The format details of the output audio * \returns 0 on success, or -1 on error. * * \threadsafety It is safe to call this function from any thread. @@ -714,26 +660,15 @@ typedef struct SDL_AudioStream SDL_AudioStream; * \sa SDL_ChangeAudioStreamOutput * \sa SDL_DestroyAudioStream */ -extern DECLSPEC SDL_AudioStream *SDLCALL SDL_CreateAudioStream(SDL_AudioFormat src_format, - int src_channels, - int src_rate, - SDL_AudioFormat dst_format, - int dst_channels, - int dst_rate); +extern DECLSPEC SDL_AudioStream *SDLCALL SDL_CreateAudioStream(const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec); /** * Query the current format of an audio stream. * * \param stream the SDL_AudioStream to query. - * \param src_format Where to store the input audio format; ignored if NULL. - * \param src_channels Where to store the input channel count; ignored if - * NULL. - * \param src_rate Where to store the input sample rate; ignored if NULL. - * \param dst_format Where to store the output audio format; ignored if NULL. - * \param dst_channels Where to store the output channel count; ignored if - * NULL. - * \param dst_rate Where to store the output sample rate; ignored if NULL. + * \param src_spec Where to store the input audio format; ignored if NULL. + * \param dst_spec Where to store the output audio format; ignored if NULL. * \returns 0 on success, or -1 on error. * * \threadsafety It is safe to call this function from any thread, as it holds @@ -742,12 +677,8 @@ extern DECLSPEC SDL_AudioStream *SDLCALL SDL_CreateAudioStream(SDL_AudioFormat s * \since This function is available since SDL 3.0.0. */ extern DECLSPEC int SDLCALL SDL_GetAudioStreamFormat(SDL_AudioStream *stream, - SDL_AudioFormat *src_format, - int *src_channels, - int *src_rate, - SDL_AudioFormat *dst_format, - int *dst_channels, - int *dst_rate); + SDL_AudioSpec *src_spec, + SDL_AudioSpec *dst_spec); /** * Change the input and output formats of an audio stream. @@ -757,12 +688,10 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamFormat(SDL_AudioStream *stream, * must provide data in the new input formats. * * \param stream The stream the format is being changed - * \param src_format The format of the audio input - * \param src_channels The number of channels of the audio input - * \param src_rate The sampling rate of the audio input - * \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 + * \param src_spec The new format of the audio input; if NULL, it is not + * changed. + * \param dst_spec The new format of the audio output; if NULL, it is not + * changed. * \returns 0 on success, or -1 on error. * * \threadsafety It is safe to call this function from any thread, as it holds @@ -776,12 +705,8 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamFormat(SDL_AudioStream *stream, * \sa SDL_GetAudioStreamAvailable */ extern DECLSPEC int SDLCALL SDL_SetAudioStreamFormat(SDL_AudioStream *stream, - SDL_AudioFormat src_format, - int src_channels, - int src_rate, - SDL_AudioFormat dst_format, - int dst_channels, - int dst_rate); + const SDL_AudioSpec *src_spec, + const SDL_AudioSpec *dst_spec); /** * Add data to be converted/resampled to the stream. @@ -800,6 +725,10 @@ extern DECLSPEC int SDLCALL SDL_SetAudioStreamFormat(SDL_AudioStream *stream, * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * + * \threadsafety It is safe to call this function from any thread, but if the + * stream has a callback set, the caller might need to manage + * extra locking. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream @@ -828,6 +757,10 @@ extern DECLSPEC int SDLCALL SDL_PutAudioStreamData(SDL_AudioStream *stream, cons * \param len The maximum number of bytes to fill * \returns the number of bytes read from the stream, or -1 on error * + * \threadsafety It is safe to call this function from any thread, but if the + * stream has a callback set, the caller might need to manage + * extra locking. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream @@ -856,6 +789,8 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamData(SDL_AudioStream *stream, void * \param stream The audio stream to query * \returns the number of converted/resampled bytes available. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream @@ -879,6 +814,8 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamAvailable(SDL_AudioStream *stream) * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream @@ -897,6 +834,8 @@ extern DECLSPEC int SDLCALL SDL_FlushAudioStream(SDL_AudioStream *stream); * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream @@ -908,11 +847,177 @@ extern DECLSPEC int SDLCALL SDL_FlushAudioStream(SDL_AudioStream *stream); */ extern DECLSPEC int SDLCALL SDL_ClearAudioStream(SDL_AudioStream *stream); +/** + * Lock an audio stream for serialized access. + * + * Each SDL_AudioStream has an internal mutex it uses to protect its data + * structures from threading conflicts. This function allows an app to lock + * that mutex, which could be useful if registering callbacks on this stream. + * + * One does not need to lock a stream to use in it most cases, as the stream + * manages this lock internally. However, this lock is held during callbacks, + * which may run from arbitrary threads at any time, so if an app needs to + * protect shared data during those callbacks, locking the stream guarantees + * that the callback is not running while the lock is held. + * + * As this is just a wrapper over SDL_LockMutex for an internal lock, it has + * all the same attributes (recursive locks are allowed, etc). + * + * \param stream The audio stream to lock. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_UnlockAudioStream + * \sa SDL_SetAudioStreamPutCallback + * \sa SDL_SetAudioStreamGetCallback + */ +extern DECLSPEC int SDLCALL SDL_LockAudioStream(SDL_AudioStream *stream); + + +/** + * Unlock an audio stream for serialized access. + * + * This unlocks an audio stream after a call to SDL_LockAudioStream. + * + * \param stream The audio stream to unlock. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \threadsafety You should only call this from the same thread that + * previously called SDL_LockAudioStream. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_LockAudioStream + * \sa SDL_SetAudioStreamPutCallback + * \sa SDL_SetAudioStreamGetCallback + */ +extern DECLSPEC int SDLCALL SDL_UnlockAudioStream(SDL_AudioStream *stream); + +/** + * A callback that fires when data passes through an SDL_AudioStream. + * + * Apps can (optionally) register a callback with an audio stream that + * is called when data is added with SDL_PutAudioStreamData, or requested + * with SDL_GetAudioStreamData. These callbacks may run from any + * thread, so if you need to protect shared data, you should use + * SDL_LockAudioStream to serialize access; this lock will be held by + * before your callback is called, so your callback does not need to + * manage the lock explicitly. + * + * \param stream The SDL audio stream associated with this callback. + * \param approx_request The _approximate_ amout of data, in bytes, that is requested. + * This might be slightly overestimated due to buffering or + * resampling, and may change from call to call anyhow. + * \param userdata An opaque pointer provided by the app for their personal use. + */ +typedef void (SDLCALL *SDL_AudioStreamRequestCallback)(SDL_AudioStream *stream, int approx_request, void *userdata); + +/** + * Set a callback that runs when data is requested from an audio stream. + * + * This callback is called _before_ data is obtained from the stream, giving + * the callback the chance to add more on-demand. + * + * The callback can (optionally) call SDL_PutAudioStreamData() to add more + * audio to the stream during this call; if needed, the request that triggered + * this callback will obtain the new data immediately. + * + * The callback's `approx_request` argument is roughly how many bytes of + * _unconverted_ data (in the stream's input format) is needed by the caller, + * although this may overestimate a little for safety. This takes into account + * how much is already in the stream and only asks for any extra necessary to + * resolve the request, which means the callback may be asked for zero bytes, + * and a different amount on each call. + * + * The callback is not required to supply exact amounts; it is allowed to + * supply too much or too little or none at all. The caller will get what's + * available, up to the amount they requested, regardless of this callback's + * outcome. + * + * Clearing or flushing an audio stream does not call this callback. + * + * This function obtains the stream's lock, which means any existing callback + * (get or put) in progress will finish running before setting the new + * callback. + * + * Setting a NULL function turns off the callback. + * + * \param stream the audio stream to set the new callback on. + * \param callback the new callback function to call when data is added to the + * stream. + * \param userdata an opaque pointer provided to the callback for its own + * personal use. + * \returns 0 on success, -1 on error. This only fails if `stream` is NULL. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_SetAudioStreamPutCallback + */ +extern DECLSPEC int SDLCALL SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamRequestCallback callback, void *userdata); + +/** + * Set a callback that runs when data is added to an audio stream. + * + * This callback is called _after_ the data is added to the stream, giving the + * callback the chance to obtain it immediately. + * + * The callback can (optionally) call SDL_GetAudioStreamData() to obtain audio + * from the stream during this call. + * + * The callback's `approx_request` argument is how many bytes of _converted_ + * data (in the stream's output format) was provided by the caller, although + * this may underestimate a little for safety. This value might be less than + * what is currently available in the stream, if data was already there, and + * might be less than the caller provided if the stream needs to keep a buffer + * to aid in resampling. Which means the callback may be provided with zero + * bytes, and a different amount on each call. + * + * The callback may call SDL_GetAudioStreamAvailable to see the total amount + * currently available to read from the stream, instead of the total provided + * by the current call. + * + * The callback is not required to obtain all data. It is allowed to read less + * or none at all. Anything not read now simply remains in the stream for + * later access. + * + * Clearing or flushing an audio stream does not call this callback. + * + * This function obtains the stream's lock, which means any existing callback + * (get or put) in progress will finish running before setting the new + * callback. + * + * Setting a NULL function turns off the callback. + * + * \param stream the audio stream to set the new callback on. + * \param callback the new callback function to call when data is added to the + * stream. + * \param userdata an opaque pointer provided to the callback for its own + * personal use. + * \returns 0 on success, -1 on error. This only fails if `stream` is NULL. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_SetAudioStreamGetCallback + */ +extern DECLSPEC int SDLCALL SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamRequestCallback callback, void *userdata); + + /** * Free an audio stream * * \param stream The audio stream to free * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream @@ -924,6 +1029,162 @@ extern DECLSPEC int SDLCALL SDL_ClearAudioStream(SDL_AudioStream *stream); */ extern DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream); + +/** + * Convenience function to create and bind an audio stream in one step. + * + * This manages the creation of an audio stream, and setting its format + * correctly to match both the app and the audio device's needs. This is + * optional, but slightly less cumbersome to set up for a common use case. + * + * The `spec` parameter represents the app's side of the audio stream. That + * is, for recording audio, this will be the output format, and for playing + * audio, this will be the input format. This function will set the other side + * of the audio stream to the device's format. + * + * \param devid an audio device to bind a stream to. This must be an opened + * device, and can not be zero. + * \param spec the audio stream's input format + * \returns a bound audio stream on success, ready to use. NULL on error; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStreams + * \sa SDL_UnbindAudioStream + */ +extern DECLSPEC SDL_AudioStream *SDLCALL SDL_CreateAndBindAudioStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec); + + +/** + * 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. + * + * 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 return value is zero 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_free() 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 function 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 SDL_TRUE, calls SDL_RWclose() on `src` before returning, + * even in the case of an error + * \param spec A pointer to an SDL_AudioSpec that will be set to the WAVE + * data's format details on successful return + * \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 0. `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 -1 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_free() to dispose of it. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_free + * \sa SDL_LoadWAV + */ +extern DECLSPEC int SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, SDL_bool freesrc, + SDL_AudioSpec * spec, Uint8 ** audio_buf, + Uint32 * audio_len); + +/** + * Loads a WAV from a file path. + * + * This is a convenience function that is effectively the same as: + * + * ```c + * SDL_LoadWAV_RW(SDL_RWFromFile(path, "rb"), 1, spec, audio_buf, audio_len); + * ``` + * + * Note that in SDL2, this was a preprocessor macro and not a real function. + * + * \param path The file path of the WAV file to open. + * \param spec A pointer to an SDL_AudioSpec that will be set to the WAVE + * data's format details on successful return. + * \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 0. `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 -1 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_free() to dispose of it. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_free + * \sa SDL_LoadWAV_RW + */ +extern DECLSPEC int SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec * spec, + Uint8 ** audio_buf, Uint32 * audio_len); + + + #define SDL_MIX_MAXVOLUME 128 /** @@ -956,6 +1217,8 @@ extern DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream); * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. */ extern DECLSPEC int SDLCALL SDL_MixAudioFormat(Uint8 * dst, @@ -963,263 +1226,6 @@ extern DECLSPEC int SDLCALL SDL_MixAudioFormat(Uint8 * dst, 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 SDL 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 3.0.0. - * - * \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 3.0.0. - * - * \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 3.0.0. - * - * \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 - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetQueuedAudioSize - * \sa SDL_QueueAudio - * \sa SDL_DequeueAudio - */ -extern DECLSPEC int 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. - */ -/* @{ */ - -/** - * 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 - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_UnlockAudioDevice - */ -extern DECLSPEC int SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); - -/** - * 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 3.0.0. - * - * \sa SDL_LockAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); -/* @} *//* Audio lock functions */ - -/** - * 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 3.0.0. - * - * \sa SDL_OpenAudioDevice - */ -extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); - /** * Convert some audio data of one format to another format. * @@ -1233,14 +1239,10 @@ extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); * use, so it's also less efficient than using one directly, if you need to * convert multiple times. * - * \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 src_spec The format details of the input audio * \param src_data The audio data to be converted * \param src_len The len of src_data - * \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 + * \param dst_spec The format details of the output audio * \param dst_data Will be filled with a pointer to converted audio data, * which should be freed with SDL_free(). On error, it will be * NULL. @@ -1248,21 +1250,37 @@ extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateAudioStream */ -extern DECLSPEC int SDLCALL SDL_ConvertAudioSamples(SDL_AudioFormat src_format, - Uint8 src_channels, - int src_rate, +extern DECLSPEC int SDLCALL SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, - SDL_AudioFormat dst_format, - Uint8 dst_channels, - int dst_rate, + const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len); + +/** + * Get the appropriate memset value for silencing an audio format. + * + * The value returned by this function can be used as the second argument to + * memset (or SDL_memset) to set an audio buffer in a specific format to + * silence. + * + * \param format the audio data format to query. + * \returns A byte value that can be passed to memset. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetSilenceValueForFormat(SDL_AudioFormat format); + + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/include/SDL3/SDL_begin_code.h b/include/SDL3/SDL_begin_code.h index 99d7aa76..6f52f9fb 100644 --- a/include/SDL3/SDL_begin_code.h +++ b/include/SDL3/SDL_begin_code.h @@ -36,6 +36,8 @@ #ifndef SDL_DEPRECATED # 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 diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index cc3ee292..f21e2516 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -152,7 +152,7 @@ typedef enum SDL_EVENT_JOYSTICK_ADDED, /**< A new joystick has been inserted into the system */ SDL_EVENT_JOYSTICK_REMOVED, /**< An opened joystick has been removed */ SDL_EVENT_JOYSTICK_BATTERY_UPDATED, /**< Joystick battery level change */ - SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, /**< Joystick update is complete (disabled by default) */ + SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, /**< Joystick update is complete */ /* Gamepad events */ SDL_EVENT_GAMEPAD_AXIS_MOTION = 0x650, /**< Gamepad axis motion */ @@ -165,7 +165,7 @@ typedef enum SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION, /**< Gamepad touchpad finger was moved */ SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */ SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */ - SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete (disabled by default) */ + SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete */ /* Touch events */ SDL_EVENT_FINGER_DOWN = 0x700, @@ -493,7 +493,7 @@ typedef struct SDL_AudioDeviceEvent { Uint32 type; /**< ::SDL_EVENT_AUDIO_DEVICE_ADDED, or ::SDL_EVENT_AUDIO_DEVICE_REMOVED */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ - SDL_AudioDeviceID which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ + SDL_AudioDeviceID which; /**< SDL_AudioDeviceID for the device being added or removed */ Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ Uint8 padding1; Uint8 padding2; diff --git a/include/SDL3/SDL_filesystem.h b/include/SDL3/SDL_filesystem.h index a672365c..ae8139c1 100644 --- a/include/SDL3/SDL_filesystem.h +++ b/include/SDL3/SDL_filesystem.h @@ -159,11 +159,11 @@ extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); * | SAVEDGAMES | Vista+ | | | | | | * | SCREENSHOTS | Vista+ | | | | | | * | TEMPLATES | X | X | | X | | | - * | VIDEOS | X | X | | X | | | + * | VIDEOS | X | X* | | X | | | * - * Note that on macOS/iOS, the Videos folder is called "Movies". + * * Note that on macOS/iOS, the Videos folder is called "Movies". * - * \sa SDL_GetPath + * \sa SDL_GetUserFolder */ typedef enum { @@ -206,13 +206,18 @@ typedef enum } SDL_Folder; /** - * Finds the most suitable OS-provided folder for @p folder, and returns its - * path in OS-specific notation. + * Finds the most suitable user folder for @p purpose, and returns its path in + * OS-specific notation. * * Many OSes provide certain standard folders for certain purposes, such as * storing pictures, music or videos for a certain user. This function gives * the path for many of those special locations. * + * This function is specifically for _user_ folders, which are meant for the + * user to access and manage. For application-specific folders, meant to hold + * data for the application to manage, see SDL_GetBasePath() and + * SDL_GetPrefPath(). + * * Note that the function is expensive, and should be called once at the * beginning of the execution and kept for as long as needed. * @@ -229,7 +234,7 @@ typedef enum * * \sa SDL_Folder */ -extern DECLSPEC char *SDLCALL SDL_GetPath(SDL_Folder folder); +extern DECLSPEC char *SDLCALL SDL_GetUserFolder(SDL_Folder folder); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h index 93f7a7da..484aee49 100644 --- a/include/SDL3/SDL_gamepad.h +++ b/include/SDL3/SDL_gamepad.h @@ -95,11 +95,11 @@ typedef enum SDL_GAMEPAD_BUTTON_DPAD_DOWN, SDL_GAMEPAD_BUTTON_DPAD_LEFT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, - SDL_GAMEPAD_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */ - SDL_GAMEPAD_BUTTON_PADDLE1, /* Xbox Elite paddle P1 (upper left, facing the back) */ - SDL_GAMEPAD_BUTTON_PADDLE2, /* Xbox Elite paddle P3 (upper right, facing the back) */ - SDL_GAMEPAD_BUTTON_PADDLE3, /* Xbox Elite paddle P2 (lower left, facing the back) */ - SDL_GAMEPAD_BUTTON_PADDLE4, /* Xbox Elite paddle P4 (lower right, facing the back) */ + SDL_GAMEPAD_BUTTON_MISC1, /* Additional button (e.g. Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button) */ + SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, /* Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) */ + SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, /* Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) */ + SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, /* Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) */ + SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, /* Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) */ SDL_GAMEPAD_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */ SDL_GAMEPAD_BUTTON_MAX } SDL_GamepadButton; @@ -176,7 +176,8 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping); * constrained environment. * * \param src the data stream for the mappings to be added - * \param freesrc non-zero to close the stream after being read + * \param freesrc if SDL_TRUE, calls SDL_RWclose() on `src` before returning, + * even in the case of an error * \returns the number of mappings added or -1 on error; call SDL_GetError() * for more information. * @@ -186,7 +187,7 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping); * \sa SDL_AddGamepadMappingsFromFile * \sa SDL_GetGamepadMappingForGUID */ -extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_RWops *src, int freesrc); +extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_RWops *src, SDL_bool freesrc); /** * Load a set of gamepad mappings from a file. @@ -321,7 +322,6 @@ extern DECLSPEC SDL_JoystickID *SDLCALL SDL_GetGamepads(int *count); * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetGamepadNameForIndex * \sa SDL_OpenGamepad */ extern DECLSPEC SDL_bool SDLCALL SDL_IsGamepad(SDL_JoystickID instance_id); @@ -478,7 +478,6 @@ extern DECLSPEC char *SDLCALL SDL_GetGamepadInstanceMapping(SDL_JoystickID insta * \since This function is available since SDL 3.0.0. * * \sa SDL_CloseGamepad - * \sa SDL_GetGamepadNameForIndex * \sa SDL_IsGamepad */ extern DECLSPEC SDL_Gamepad *SDLCALL SDL_OpenGamepad(SDL_JoystickID instance_id); @@ -532,7 +531,7 @@ extern DECLSPEC SDL_JoystickID SDLCALL SDL_GetGamepadInstanceID(SDL_Gamepad *gam * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetGamepadNameForIndex + * \sa SDL_GetGamepadInstanceName * \sa SDL_OpenGamepad */ extern DECLSPEC const char *SDLCALL SDL_GetGamepadName(SDL_Gamepad *gamepad); diff --git a/include/SDL3/SDL_mutex.h b/include/SDL3/SDL_mutex.h index 63b2c595..19c6b555 100644 --- a/include/SDL3/SDL_mutex.h +++ b/include/SDL3/SDL_mutex.h @@ -34,6 +34,10 @@ /******************************************************************************/ /* Enable thread safety attributes only with clang. * The attributes can be safely erased when compiling with other compilers. + * + * To enable analysis, set these environment variables before running cmake: + * export CC=clang + * export CFLAGS="-DSDL_THREAD_SAFETY_ANALYSIS -Wthread-safety" */ #if defined(SDL_THREAD_SAFETY_ANALYSIS) && \ defined(__clang__) && (!defined(SWIG)) diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h index 494f5669..e58ec3a4 100644 --- a/include/SDL3/SDL_oldnames.h +++ b/include/SDL3/SDL_oldnames.h @@ -174,10 +174,10 @@ #define SDL_CONTROLLER_BUTTON_LEFTSTICK SDL_GAMEPAD_BUTTON_LEFT_STICK #define SDL_CONTROLLER_BUTTON_MAX SDL_GAMEPAD_BUTTON_MAX #define SDL_CONTROLLER_BUTTON_MISC1 SDL_GAMEPAD_BUTTON_MISC1 -#define SDL_CONTROLLER_BUTTON_PADDLE1 SDL_GAMEPAD_BUTTON_PADDLE1 -#define SDL_CONTROLLER_BUTTON_PADDLE2 SDL_GAMEPAD_BUTTON_PADDLE2 -#define SDL_CONTROLLER_BUTTON_PADDLE3 SDL_GAMEPAD_BUTTON_PADDLE3 -#define SDL_CONTROLLER_BUTTON_PADDLE4 SDL_GAMEPAD_BUTTON_PADDLE4 +#define SDL_CONTROLLER_BUTTON_PADDLE1 SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 +#define SDL_CONTROLLER_BUTTON_PADDLE2 SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 +#define SDL_CONTROLLER_BUTTON_PADDLE3 SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 +#define SDL_CONTROLLER_BUTTON_PADDLE4 SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 #define SDL_CONTROLLER_BUTTON_RIGHTSHOULDER SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER #define SDL_CONTROLLER_BUTTON_RIGHTSTICK SDL_GAMEPAD_BUTTON_RIGHT_STICK #define SDL_CONTROLLER_BUTTON_START SDL_GAMEPAD_BUTTON_START @@ -423,6 +423,18 @@ #define RW_SEEK_SET SDL_RW_SEEK_SET #define SDL_AllocRW SDL_CreateRW #define SDL_FreeRW SDL_DestroyRW +#define SDL_ReadBE16 SDL_ReadU16BE +#define SDL_ReadBE32 SDL_ReadU32BE +#define SDL_ReadBE64 SDL_ReadU64BE +#define SDL_ReadLE16 SDL_ReadU16LE +#define SDL_ReadLE32 SDL_ReadU32LE +#define SDL_ReadLE64 SDL_ReadU64LE +#define SDL_WriteBE16 SDL_WriteU16BE +#define SDL_WriteBE32 SDL_WriteU32BE +#define SDL_WriteBE64 SDL_WriteU64BE +#define SDL_WriteLE16 SDL_WriteU16LE +#define SDL_WriteLE32 SDL_WriteU32LE +#define SDL_WriteLE64 SDL_WriteU64LE /* ##SDL_sensor.h */ #define SDL_SensorClose SDL_CloseSensor @@ -613,10 +625,10 @@ #define SDL_CONTROLLER_BUTTON_LEFTSTICK SDL_CONTROLLER_BUTTON_LEFTSTICK_renamed_SDL_GAMEPAD_BUTTON_LEFT_STICK #define SDL_CONTROLLER_BUTTON_MAX SDL_CONTROLLER_BUTTON_MAX_renamed_SDL_GAMEPAD_BUTTON_MAX #define SDL_CONTROLLER_BUTTON_MISC1 SDL_CONTROLLER_BUTTON_MISC1_renamed_SDL_GAMEPAD_BUTTON_MISC1 -#define SDL_CONTROLLER_BUTTON_PADDLE1 SDL_CONTROLLER_BUTTON_PADDLE1_renamed_SDL_GAMEPAD_BUTTON_PADDLE1 -#define SDL_CONTROLLER_BUTTON_PADDLE2 SDL_CONTROLLER_BUTTON_PADDLE2_renamed_SDL_GAMEPAD_BUTTON_PADDLE2 -#define SDL_CONTROLLER_BUTTON_PADDLE3 SDL_CONTROLLER_BUTTON_PADDLE3_renamed_SDL_GAMEPAD_BUTTON_PADDLE3 -#define SDL_CONTROLLER_BUTTON_PADDLE4 SDL_CONTROLLER_BUTTON_PADDLE4_renamed_SDL_GAMEPAD_BUTTON_PADDLE4 +#define SDL_CONTROLLER_BUTTON_PADDLE1 SDL_CONTROLLER_BUTTON_PADDLE1_renamed_SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 +#define SDL_CONTROLLER_BUTTON_PADDLE2 SDL_CONTROLLER_BUTTON_PADDLE2_renamed_SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 +#define SDL_CONTROLLER_BUTTON_PADDLE3 SDL_CONTROLLER_BUTTON_PADDLE3_renamed_SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 +#define SDL_CONTROLLER_BUTTON_PADDLE4 SDL_CONTROLLER_BUTTON_PADDLE4_renamed_SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 #define SDL_CONTROLLER_BUTTON_RIGHTSHOULDER SDL_CONTROLLER_BUTTON_RIGHTSHOULDER_renamed_SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER #define SDL_CONTROLLER_BUTTON_RIGHTSTICK SDL_CONTROLLER_BUTTON_RIGHTSTICK_renamed_SDL_GAMEPAD_BUTTON_RIGHT_STICK #define SDL_CONTROLLER_BUTTON_START SDL_CONTROLLER_BUTTON_START_renamed_SDL_GAMEPAD_BUTTON_START @@ -863,6 +875,18 @@ #define RW_SEEK_SET RW_SEEK_SET_renamed_SDL_RW_SEEK_SET #define SDL_AllocRW SDL_AllocRW_renamed_SDL_CreateRW #define SDL_FreeRW SDL_FreeRW_renamed_SDL_DestroyRW +#define SDL_ReadBE16 SDL_ReadBE16_renamed_SDL_ReadU16BE +#define SDL_ReadBE32 SDL_ReadBE32_renamed_SDL_ReadU32BE +#define SDL_ReadBE64 SDL_ReadBE64_renamed_SDL_ReadU64BE +#define SDL_ReadLE16 SDL_ReadLE16_renamed_SDL_ReadU16LE +#define SDL_ReadLE32 SDL_ReadLE32_renamed_SDL_ReadU32LE +#define SDL_ReadLE64 SDL_ReadLE64_renamed_SDL_ReadU64LE +#define SDL_WriteBE16 SDL_WriteBE16_renamed_SDL_WriteU16BE +#define SDL_WriteBE32 SDL_WriteBE32_renamed_SDL_WriteU32BE +#define SDL_WriteBE64 SDL_WriteBE64_renamed_SDL_WriteU64BE +#define SDL_WriteLE16 SDL_WriteLE16_renamed_SDL_WriteU16LE +#define SDL_WriteLE32 SDL_WriteLE32_renamed_SDL_WriteU32LE +#define SDL_WriteLE64 SDL_WriteLE64_renamed_SDL_WriteU64LE /* ##SDL_sensor.h */ #define SDL_SensorClose SDL_SensorClose_renamed_SDL_CloseSensor diff --git a/include/SDL3/SDL_pixels.h b/include/SDL3/SDL_pixels.h index 75f8234c..6da0b93a 100644 --- a/include/SDL3/SDL_pixels.h +++ b/include/SDL3/SDL_pixels.h @@ -91,6 +91,8 @@ typedef enum { SDL_ARRAYORDER_NONE, SDL_ARRAYORDER_RGB, + SDL_ARRAYORDER_UNUSED1, /* Left for compatibility with SDL2 */ + SDL_ARRAYORDER_UNUSED2, /* Left for compatibility with SDL2 */ SDL_ARRAYORDER_BGR } SDL_ArrayOrder; @@ -263,11 +265,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) */ diff --git a/include/SDL3/SDL_platform_defines.h b/include/SDL3/SDL_platform_defines.h index e84fd8d8..565a0943 100644 --- a/include/SDL3/SDL_platform_defines.h +++ b/include/SDL3/SDL_platform_defines.h @@ -94,6 +94,9 @@ #ifndef TARGET_OS_SIMULATOR #define TARGET_OS_SIMULATOR 0 #endif +#ifndef TARGET_OS_XR +#define TARGET_OS_XR 0 +#endif #if TARGET_OS_TV #undef __TVOS__ diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h index 61f47a5a..d33b99bb 100644 --- a/include/SDL3/SDL_render.h +++ b/include/SDL3/SDL_render.h @@ -778,10 +778,6 @@ extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture *texture); /** * 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`. @@ -1558,7 +1554,7 @@ extern DECLSPEC void *SDLCALL SDL_GetRenderMetalLayer(SDL_Renderer *renderer); * 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 backbacker. Check your return values! + * 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 diff --git a/include/SDL3/SDL_rwops.h b/include/SDL3/SDL_rwops.h index b3bc41c1..27e1f316 100644 --- a/include/SDL3/SDL_rwops.h +++ b/include/SDL3/SDL_rwops.h @@ -38,13 +38,21 @@ 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 */ +/* RWops types */ +#define SDL_RWOPS_UNKNOWN 0 /**< Unknown stream type */ +#define SDL_RWOPS_WINFILE 1 /**< Win32 file */ +#define SDL_RWOPS_STDFILE 2 /**< Stdio file */ +#define SDL_RWOPS_JNIFILE 3 /**< Android asset */ +#define SDL_RWOPS_MEMORY 4 /**< Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5 /**< Read-Only memory stream */ + +/* RWops status, set by a read or write operation */ +#define SDL_RWOPS_STATUS_READY 0 /**< Everything is ready */ +#define SDL_RWOPS_STATUS_ERROR 1 /**< Read or write I/O error */ +#define SDL_RWOPS_STATUS_EOF 2 /**< End of file */ +#define SDL_RWOPS_STATUS_NOT_READY 3 /**< Non blocking I/O, not ready */ +#define SDL_RWOPS_STATUS_READONLY 4 /**< Tried to write a read-only buffer */ +#define SDL_RWOPS_STATUS_WRITEONLY 5 /**< Tried to read a write-only buffer */ /** * This is the read/write operation structure -- very basic. @@ -52,9 +60,11 @@ extern "C" { typedef struct SDL_RWops { /** - * Return the size of the file in this rwops, or -1 if unknown + * Return the number of bytes in this rwops + * + * \return the total size of the data stream, or -1 on error. */ - Sint64 (SDLCALL * size) (struct SDL_RWops * context); + Sint64 (SDLCALL *size)(struct SDL_RWops *context); /** * Seek to \c offset relative to \c whence, one of stdio's whence values: @@ -62,45 +72,33 @@ typedef struct SDL_RWops * * \return the final offset in the data stream, or -1 on error. */ - Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, - int whence); + Sint64 (SDLCALL *seek)(struct SDL_RWops *context, Sint64 offset, int whence); /** * Read up to \c size bytes from the data stream to the area pointed * at by \c ptr. * - * It is an error to use a negative \c size, but this parameter is - * signed so you definitely cannot overflow the return value on a - * successful run with enormous amounts of data. - * - * \return the number of objects read, or 0 on end of file, or -1 on error. + * \return the number of bytes read */ - Sint64 (SDLCALL * read) (struct SDL_RWops * context, void *ptr, - Sint64 size); + size_t (SDLCALL *read)(struct SDL_RWops *context, void *ptr, size_t size); /** * Write exactly \c size bytes from the area pointed at by \c ptr - * to data stream. May write less than requested (error, non-blocking i/o, - * etc). Returns -1 on error when nothing was written. + * to data stream. * - * It is an error to use a negative \c size, but this parameter is - * signed so you definitely cannot overflow the return value on a - * successful run with enormous amounts of data. - * - * \return the number of bytes written, which might be less than \c size, - * and -1 on error. + * \return the number of bytes written */ - Sint64 (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, - Sint64 size); + size_t (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, size_t size); /** * 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); + int (SDLCALL *close)(struct SDL_RWops *context); Uint32 type; + Uint32 status; union { #ifdef __ANDROID__ @@ -109,7 +107,7 @@ typedef struct SDL_RWops void *asset; } androidio; -#elif defined(__WIN32__) || defined(__GDK__) +#elif defined(__WIN32__) || defined(__GDK__) || defined(__WINRT__) struct { SDL_bool append; @@ -213,8 +211,7 @@ typedef struct SDL_RWops * \sa SDL_RWtell * \sa SDL_RWwrite */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, - const char *mode); +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, const char *mode); /** * Use this function to prepare a read-write memory buffer for use with @@ -279,8 +276,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, size_t size); * \sa SDL_RWseek * \sa SDL_RWtell */ -extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, - size_t size); +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, size_t size); /* @} *//* RWFrom functions */ @@ -289,7 +285,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, * 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 + * their own SDL_RWops implementation. If you just need an 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. * @@ -315,7 +311,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_CreateRW(void); * SDL_CreateRW(). * * 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 + * their own SDL_RWops implementation. If you just need an 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 @@ -327,13 +323,13 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_CreateRW(void); * the programmer must be responsible for managing that memory in their * **close** method. * - * \param area the SDL_RWops structure to be freed + * \param context the SDL_RWops structure to be freed * * \since This function is available since SDL 3.0.0. * * \sa SDL_CreateRW */ -extern DECLSPEC void SDLCALL SDL_DestroyRW(SDL_RWops * area); +extern DECLSPEC void SDLCALL SDL_DestroyRW(SDL_RWops *context); #define SDL_RW_SEEK_SET 0 /**< Seek from the beginning of data */ #define SDL_RW_SEEK_CUR 1 /**< Seek relative to current read point */ @@ -342,12 +338,10 @@ extern DECLSPEC void SDLCALL SDL_DestroyRW(SDL_RWops * area); /** * 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. + * \returns the size of the data stream in the SDL_RWops on success or a + * negative error code on failure; call SDL_GetError() for more + * information. * * \since This function is available since SDL 3.0.0. */ @@ -369,14 +363,13 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); * 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 `SDL_RW_SEEK_SET`, `SDL_RW_SEEK_CUR`, * `SDL_RW_SEEK_END` - * \returns the final offset in the data stream after the seek or -1 on error. + * \returns the final offset in the data stream after the seek or a negative + * error code on failure; call SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. * @@ -388,8 +381,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); * \sa SDL_RWtell * \sa SDL_RWwrite */ -extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, - Sint64 offset, int whence); +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. @@ -398,10 +390,8 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, * method, with an offset of 0 bytes from `SDL_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 + * \param context an 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. * @@ -438,8 +428,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); * \param context a pointer to an SDL_RWops structure * \param ptr a pointer to a buffer to read data into * \param size the number of bytes to read from the data source. - * \returns the number of bytes read, 0 at end of file, -1 on error, and -2 - * for data not ready with a non-blocking context. + * \returns the number of bytes read, or 0 on end of file or other error. * * \since This function is available since SDL 3.0.0. * @@ -450,7 +439,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); * \sa SDL_RWseek * \sa SDL_RWwrite */ -extern DECLSPEC Sint64 SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size); +extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, size_t size); /** * Write to an SDL_RWops data stream. @@ -488,8 +477,7 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, Sint64 * \sa SDL_RWread * \sa SDL_RWseek */ -extern DECLSPEC Sint64 SDLCALL SDL_RWwrite(SDL_RWops *context, - const void *ptr, Sint64 size); +extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size); /** * Close and free an allocated SDL_RWops structure. @@ -502,8 +490,6 @@ extern DECLSPEC Sint64 SDLCALL SDL_RWwrite(SDL_RWops *context, * 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. @@ -536,9 +522,7 @@ extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); * * \since This function is available since SDL 3.0.0. */ -extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, - size_t *datasize, - SDL_bool freesrc); +extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc); /** * Load all the data from a file path. @@ -549,9 +533,6 @@ extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, * * 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. @@ -571,14 +552,13 @@ extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() + * for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_WriteU8 */ -extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU8(SDL_RWops *src, Uint8 *value); /** * Use this function to read 16 bits of little-endian data from an SDL_RWops @@ -588,13 +568,29 @@ extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadBE16 */ -extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU16LE(SDL_RWops *src, Uint16 *value); + +/** + * 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 + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ReadS16LE(SDL_RWops *src, Sint16 *value); /** * Use this function to read 16 bits of big-endian data from an SDL_RWops and @@ -604,13 +600,29 @@ extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadLE16 */ -extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU16BE(SDL_RWops *src, Uint16 *value); + +/** + * 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 + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ReadS16BE(SDL_RWops *src, Sint16 *value); /** * Use this function to read 32 bits of little-endian data from an SDL_RWops @@ -620,13 +632,29 @@ extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadBE32 */ -extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU32LE(SDL_RWops *src, Uint32 *value); + +/** + * 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 + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ReadS32LE(SDL_RWops *src, Sint32 *value); /** * Use this function to read 32 bits of big-endian data from an SDL_RWops and @@ -636,13 +664,29 @@ extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadLE32 */ -extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU32BE(SDL_RWops *src, Uint32 *value); + +/** + * 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 + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ReadS32BE(SDL_RWops *src, Sint32 *value); /** * Use this function to read 64 bits of little-endian data from an SDL_RWops @@ -652,13 +696,29 @@ extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadBE64 */ -extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU64LE(SDL_RWops *src, Uint64 *value); + +/** + * 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 + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ReadS64LE(SDL_RWops *src, Sint64 *value); /** * Use this function to read 64 bits of big-endian data from an SDL_RWops and @@ -668,13 +728,29 @@ extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); * 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. + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadLE64 */ -extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); +extern DECLSPEC SDL_bool SDLCALL SDL_ReadU64BE(SDL_RWops *src, Uint64 *value); + +/** + * 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 + * \param value a pointer filled in with the data read + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ReadS64BE(SDL_RWops *src, Sint64 *value); /* @} *//* Read endian functions */ /** @@ -689,17 +765,15 @@ extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); * * \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. + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_ReadU8 */ -extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU8(SDL_RWops *dst, Uint8 value); /** - * Use this function to write 16 bits in native format to a SDL_RWops as + * Use this function to write 16 bits in native format to an SDL_RWops as * little-endian data. * * SDL byteswaps the data only if necessary, so the application always @@ -708,33 +782,15 @@ extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); * * \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. + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_WriteBE16 */ -extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU16LE(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 3.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 + * Use this function to write 16 bits in native format to an SDL_RWops as * little-endian data. * * SDL byteswaps the data only if necessary, so the application always @@ -743,16 +799,15 @@ extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); * * \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. + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_WriteBE32 */ -extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); +extern DECLSPEC SDL_bool SDLCALL SDL_WriteS16LE(SDL_RWops *dst, Sint16 value); /** - * Use this function to write 32 bits in native format to a SDL_RWops as + * Use this function to write 16 bits in native format to an SDL_RWops as * big-endian data. * * SDL byteswaps the data only if necessary, so the application always @@ -760,16 +815,31 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); * * \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. + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_WriteLE32 */ -extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU16BE(SDL_RWops *dst, Uint16 value); /** - * Use this function to write 64 bits in native format to a SDL_RWops as + * Use this function to write 16 bits in native format to an 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 SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_WriteS16BE(SDL_RWops *dst, Sint16 value); + +/** + * Use this function to write 32 bits in native format to an SDL_RWops as * little-endian data. * * SDL byteswaps the data only if necessary, so the application always @@ -778,16 +848,32 @@ extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); * * \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. + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_WriteBE64 */ -extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU32LE(SDL_RWops *dst, Uint32 value); /** - * Use this function to write 64 bits in native format to a SDL_RWops as + * Use this function to write 32 bits in native format to an 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 SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_WriteS32LE(SDL_RWops *dst, Sint32 value); + +/** + * Use this function to write 32 bits in native format to an SDL_RWops as * big-endian data. * * SDL byteswaps the data only if necessary, so the application always @@ -795,13 +881,80 @@ extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); * * \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. + * \returns SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. - * - * \sa SDL_WriteLE64 */ -extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU32BE(SDL_RWops *dst, Uint32 value); + +/** + * Use this function to write 32 bits in native format to an 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 SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_WriteS32BE(SDL_RWops *dst, Sint32 value); + +/** + * Use this function to write 64 bits in native format to an 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 SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU64LE(SDL_RWops *dst, Uint64 value); + +/** + * Use this function to write 64 bits in native format to an 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 SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_WriteS64LE(SDL_RWops *dst, Sint64 value); + +/** + * Use this function to write 64 bits in native format to an 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 SDL_TRUE on successful write, SDL_FALSE on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU64BE(SDL_RWops *dst, Uint64 value); + +extern DECLSPEC SDL_bool SDLCALL SDL_WriteU64BE(SDL_RWops *dst, Uint64 value); /* @} *//* Write endian functions */ /* Ends C function definitions when using C++ */ diff --git a/include/SDL3/SDL_surface.h b/include/SDL3/SDL_surface.h index 88cc6e0f..77483247 100644 --- a/include/SDL3/SDL_surface.h +++ b/include/SDL3/SDL_surface.h @@ -131,12 +131,15 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateSurface (int width, int height, Uint32 format); /** - * Allocate a new RGB surface with with a specific pixel format and existing - * pixel data. + * Allocate a new RGB surface with a specific pixel format and existing pixel + * data. * * 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. * + * Pitch is the offset in bytes from one row of pixels to the next, e.g. + * `width*4` for `SDL_PIXELFORMAT_RGBA8888`. + * * You may pass NULL for pixels and 0 for pitch to create a surface that you * will fill in with valid values later. * @@ -270,7 +273,8 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP(const char *file); * * \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 + * \param freedst if SDL_TRUE, calls SDL_RWclose() on `dst` before returning, + * even in the case of an error * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * @@ -279,7 +283,7 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP(const char *file); * \sa SDL_LoadBMP_RW * \sa SDL_SaveBMP */ -extern DECLSPEC int SDLCALL SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst); +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, SDL_bool freedst); /** * Save a surface to a file. diff --git a/include/SDL3/SDL_test_common.h b/include/SDL3/SDL_test_common.h index 4c151471..f2d66e51 100644 --- a/include/SDL3/SDL_test_common.h +++ b/include/SDL3/SDL_test_common.h @@ -97,7 +97,9 @@ typedef struct /* Audio info */ const char *audiodriver; - SDL_AudioSpec audiospec; + SDL_AudioFormat audio_format; + int audio_channels; + int audio_freq; SDL_AudioDeviceID audio_id; /* GL settings */ diff --git a/include/SDL3/SDL_thread.h b/include/SDL3/SDL_thread.h index 8f1eeddb..313dd3fb 100644 --- a/include/SDL3/SDL_thread.h +++ b/include/SDL3/SDL_thread.h @@ -155,7 +155,7 @@ SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); - +#if !defined(__BUILDING_SDL2_COMPAT__) /* do not conflict with sdl2-compat::sdl3_include_wrapper.h */ #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) @@ -165,6 +165,7 @@ SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, #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 +#endif /* !__BUILDING_SDL2_COMPAT__ */ #else diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 528ce8b3..aadc5c22 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -118,6 +118,7 @@ typedef enum * \sa SDL_SetWindowResizable() * \sa SDL_SetWindowTitle() * \sa SDL_ShowWindow() + * \sa SDL_ShowWindowSystemMenu() */ typedef struct SDL_Window SDL_Window; @@ -1675,6 +1676,29 @@ extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window *modal_window, SDL_ */ extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window *window); +/** + * Display the system-level window menu. + * + * This default window menu is provided by the system and on some platforms + * provides functionality for setting or changing privileged state on the + * window, such as moving it between workspaces or displays, or toggling the + * always-on-top property. + * + * On platforms or desktops where this is unsupported, this function does + * nothing. + * + * \param window the window for which the menu will be displayed + * \param x the x coordinate of the menu, relative to the origin (top-left) of + * the client area + * \param y the y coordinate of the menu, relative to the origin (top-left) of + * the client area + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC int SDLCALL SDL_ShowWindowSystemMenu(SDL_Window *window, int x, int y); + /** * Possible return values from the SDL_HitTest callback. * diff --git a/src/SDL.c b/src/SDL.c index e0381f9f..f099b048 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -632,9 +632,9 @@ SDL_bool SDL_IsTablet(void) #ifdef __WIN32__ #if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB) -/* Need to include DllMain() on Watcom C for some reason.. */ +/* FIXME: Still need to include DllMain() on Watcom C ? */ -BOOL APIENTRY _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 80f65588..c4162738 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -20,17 +20,12 @@ */ #include "SDL_internal.h" -/* Allow access to a raw mixing buffer */ - #include "SDL_audio_c.h" #include "SDL_sysaudio.h" #include "../thread/SDL_systhread.h" #include "../SDL_utils_c.h" -static SDL_AudioDriver current_audio; -static SDL_AudioDevice *open_devices[16]; - -/* Available audio drivers */ +// Available audio drivers static const AudioBootStrap *const bootstrap[] = { #ifdef SDL_AUDIO_DRIVER_PULSEAUDIO &PULSEAUDIO_bootstrap, @@ -57,7 +52,7 @@ static const AudioBootStrap *const bootstrap[] = { &COREAUDIO_bootstrap, #endif #ifdef SDL_AUDIO_DRIVER_AAUDIO - &aaudio_bootstrap, + &AAUDIO_bootstrap, #endif #ifdef SDL_AUDIO_DRIVER_OPENSLES &openslES_bootstrap, @@ -101,671 +96,7 @@ static const AudioBootStrap *const bootstrap[] = { NULL }; -static SDL_AudioDevice *get_audio_device(SDL_AudioDeviceID id) -{ - id--; - if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) { - SDL_SetError("Invalid audio device ID"); - return NULL; - } - - return open_devices[id]; -} - -int get_max_num_audio_dev(void) -{ - return SDL_arraysize(open_devices); -} - -SDL_AudioDevice *get_audio_dev(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) -{ - /* 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, NULL, (void *)((size_t)0x1)); - if (current_audio.impl.HasCaptureSupport) { - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)((size_t)0x2)); - } -} - -static void SDL_AudioThreadInit_Default(SDL_AudioDevice *_this) -{ /* no-op. */ -} - -static void SDL_AudioThreadDeinit_Default(SDL_AudioDevice *_this) -{ /* no-op. */ -} - -static void SDL_AudioWaitDevice_Default(SDL_AudioDevice *_this) -{ /* no-op. */ -} - -static void SDL_AudioPlayDevice_Default(SDL_AudioDevice *_this) -{ /* no-op. */ -} - -static Uint8 *SDL_AudioGetDeviceBuf_Default(SDL_AudioDevice *_this) -{ - return NULL; -} - -static int SDL_AudioCaptureFromDevice_Default(SDL_AudioDevice *_this, void *buffer, int buflen) -{ - return -1; /* just fail immediately. */ -} - -static void SDL_AudioFlushCapture_Default(SDL_AudioDevice *_this) -{ /* no-op. */ -} - -static void SDL_AudioCloseDevice_Default(SDL_AudioDevice *_this) -{ /* no-op. */ -} - -static void SDL_AudioDeinitialize_Default(void) -{ /* no-op. */ -} - -static void SDL_AudioFreeDeviceHandle_Default(void *handle) -{ /* no-op. */ -} - -static int SDL_AudioOpenDevice_Default(SDL_AudioDevice *_this, const char *devname) -{ - return SDL_Unsupported(); -} - -static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device) -{ - SDL_LockMutex(device->mixer_lock); -} - -static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device) -{ - SDL_UnlockMutex(device->mixer_lock); -} - -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. - */ - -#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(WaitDevice); - FILL_STUB(PlayDevice); - FILL_STUB(GetDeviceBuf); - FILL_STUB(CaptureFromDevice); - FILL_STUB(FlushCapture); - FILL_STUB(CloseDevice); - FILL_STUB(LockDevice); - FILL_STUB(UnlockDevice); - FILL_STUB(FreeDeviceHandle); - FILL_STUB(Deinitialize); -#undef FILL_STUB -} - -/* device hotplug support... */ - -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(name != NULL); - - item = (SDL_AudioDeviceItem *)SDL_malloc(sizeof(SDL_AudioDeviceItem)); - if (!item) { - return SDL_OutOfMemory(); - } - - item->original_name = SDL_strdup(name); - if (!item->original_name) { - SDL_free(item); - return SDL_OutOfMemory(); - } - - 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); - - 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. */ - } - } - - if (dupenum) { - const size_t len = SDL_strlen(name) + 16; - char *replacement = (char *)SDL_malloc(len); - if (!replacement) { - SDL_UnlockMutex(current_audio.detectionLock); - SDL_free(item->original_name); - SDL_free(item); - return SDL_OutOfMemory(); - } - - (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 */ - - SDL_UnlockMutex(current_audio.detectionLock); - - return retval; -} - -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, spec, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); -} - -static SDL_INLINE int add_output_device(const char *name, SDL_AudioSpec *spec, void *handle) -{ - return add_audio_device(name, spec, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); -} - -static void free_device_list(SDL_AudioDeviceItem **devices, int *devCount) -{ - SDL_AudioDeviceItem *item, *next; - for (item = *devices; item != NULL; item = next) { - next = item->next; - if (item->handle != NULL) { - current_audio.impl.FreeDeviceHandle(item->handle); - } - /* these two pointers are the same if not a duplicate devname */ - if (item->name != item->original_name) { - SDL_free(item->name); - } - SDL_free(item->original_name); - SDL_free(item); - } - *devices = NULL; - *devCount = 0; -} - -/* The audio backends call this when a new device is plugged in. */ -void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *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_EventEnabled(SDL_EVENT_AUDIO_DEVICE_ADDED)) { - SDL_Event event; - event.type = SDL_EVENT_AUDIO_DEVICE_ADDED; - event.common.timestamp = 0; - event.adevice.which = device_index; - event.adevice.iscapture = iscapture; - SDL_PushEvent(&event); - } - } -} - -/* The audio backends call this when a currently-opened device is lost. */ -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. */ - } - - if (SDL_AtomicGet(&device->shutdown)) { - return; /* don't report disconnect if we're trying to close device. */ - } - - /* Ends the audio callback and mark the device as STOPPED, but the - app still needs to close the device to free resources. */ - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->enabled, 0); - current_audio.impl.UnlockDevice(device); - - /* Post the event, if desired */ - if (SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_REMOVED)) { - SDL_Event event; - event.type = SDL_EVENT_AUDIO_DEVICE_REMOVED; - event.common.timestamp = 0; - event.adevice.which = device->id; - event.adevice.iscapture = device->iscapture ? 1 : 0; - SDL_PushEvent(&event); - } -} - -static void mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag) -{ - SDL_AudioDeviceItem *item; - SDL_assert(handle != NULL); - for (item = devices; item != NULL; item = item->next) { - if (item->handle == handle) { - item->handle = NULL; - *removedFlag = SDL_TRUE; - return; - } - } -} - -/* The audio backends call this when a device is removed from the system. */ -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) { - mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved); - } else { - mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); - } - for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) { - device = open_devices[device_index]; - 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_EVENT_AUDIO_DEVICE_REMOVED 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_EventEnabled(SDL_EVENT_AUDIO_DEVICE_REMOVED)) { - SDL_Event event; - event.type = SDL_EVENT_AUDIO_DEVICE_REMOVED; - event.common.timestamp = 0; - 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) -{ - /* this function always holds the mixer lock before being called. */ - 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?! */ - - dequeued = SDL_ReadFromDataQueue(device->buffer_queue, stream, len); - stream += dequeued; - len -= (int)dequeued; - - if (len > 0) { /* fill any remaining space in the stream with silence. */ - SDL_assert(SDL_GetDataQueueSize(device->buffer_queue) == 0); - SDL_memset(stream, device->callbackspec.silence, 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_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 - later, but you probably have bigger problems in this case anyhow. */ - SDL_WriteToDataQueue(device->buffer_queue, stream, 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 */ - } else if (device->iscapture) { - return SDL_SetError("This is a capture device, queueing not allowed"); - } else if (device->callbackspec.callback != SDL_BufferQueueDrainCallback) { - return SDL_SetError("Audio device has a callback, queueing not allowed"); - } - - if (len > 0) { - current_audio.impl.LockDevice(device); - rc = SDL_WriteToDataQueue(device->buffer_queue, data, len); - current_audio.impl.UnlockDevice(device); - } - - return rc; -} - -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. */ - } - - current_audio.impl.LockDevice(device); - rc = (Uint32)SDL_ReadFromDataQueue(device->buffer_queue, data, len); - current_audio.impl.UnlockDevice(device); - return rc; -} - -Uint32 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) -{ - Uint32 retval = 0; - SDL_AudioDevice *device = get_audio_device(devid); - - if (!device) { - return 0; - } - - /* Nothing to do unless we're set up for queueing. */ - if (device->callbackspec.callback == SDL_BufferQueueDrainCallback || - device->callbackspec.callback == SDL_BufferQueueFillCallback) { - current_audio.impl.LockDevice(device); - retval = (Uint32)SDL_GetDataQueueSize(device->buffer_queue); - current_audio.impl.UnlockDevice(device); - } - - return retval; -} - -int SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) -{ - SDL_AudioDevice *device = get_audio_device(devid); - if (!device) { - return SDL_InvalidParamError("devid"); - } - - /* 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 memory allocation pressure. */ - SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2); - - current_audio.impl.UnlockDevice(device); - return 0; -} - -#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) -{ - SDL_AudioDevice *device = (SDL_AudioDevice *)devicep; - void *udata = device->callbackspec.userdata; - SDL_AudioCallback callback = device->callbackspec.callback; - int data_len = 0; - Uint8 *data; - - SDL_assert(!device->iscapture); - -#ifdef SDL_AUDIO_DRIVER_ANDROID - { - /* Set thread priority to THREAD_PRIORITY_AUDIO */ - Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); - } -#else - /* The audio mixing is always a high priority thread */ - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL); -#endif - - /* Perform any thread setup */ - device->threadid = SDL_ThreadID(); - current_audio.impl.ThreadInit(device); - - /* Loop, filling the audio buffers */ - while (!SDL_AtomicGet(&device->shutdown)) { - data_len = device->callbackspec.size; - - /* Fill the current buffer with sound */ - if (!device->stream && SDL_AtomicGet(&device->enabled)) { - SDL_assert((Uint32)data_len == device->spec.size); - data = current_audio.impl.GetDeviceBuf(device); - } else { - /* if the device isn't enabled, we still write to the - work_buffer, so the app's callback will fire with - a regular frequency, in case they depend on that - for timing or progress. They can use hotplug - now to know if the device failed. - Streaming playback uses work_buffer, too. */ - data = NULL; - } - - if (data == NULL) { - data = device->work_buffer; - } - - /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (SDL_AtomicGet(&device->paused)) { - SDL_memset(data, device->callbackspec.silence, data_len); - } else { - callback(udata, data, data_len); - } - SDL_UnlockMutex(device->mixer_lock); - - if (device->stream) { - /* Stream available audio to device, converting/resampling. */ - /* if this fails...oh well. We'll play silence here. */ - SDL_PutAudioStreamData(device->stream, data, data_len); - - while (SDL_GetAudioStreamAvailable(device->stream) >= ((int)device->spec.size)) { - int got; - data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL; - got = SDL_GetAudioStreamData(device->stream, data ? data : device->work_buffer, device->spec.size); - SDL_assert((got <= 0) || ((Uint32)got == device->spec.size)); - - 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? */ - } else { - if ((Uint32)got != device->spec.size) { - SDL_memset(data, device->spec.silence, device->spec.size); - } - current_audio.impl.PlayDevice(device); - current_audio.impl.WaitDevice(device); - } - } - } 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. */ - /* queue this buffer and wait for it to finish playing. */ - current_audio.impl.PlayDevice(device); - current_audio.impl.WaitDevice(device); - } - } - - /* Wait for the audio to drain. */ - SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); - - current_audio.impl.ThreadDeinit(device); - - return 0; -} - -/* !!! FIXME: this needs to deal with device spec changes. */ -/* The general capture thread function */ -static int SDLCALL SDL_CaptureAudio(void *devicep) -{ - SDL_AudioDevice *device = (SDL_AudioDevice *)devicep; - 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; - void *udata = device->callbackspec.userdata; - SDL_AudioCallback callback = device->callbackspec.callback; - - SDL_assert(device->iscapture); - -#ifdef SDL_AUDIO_DRIVER_ANDROID - { - /* Set thread priority to THREAD_PRIORITY_AUDIO */ - Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); - } -#else - /* The audio mixing is always a high priority thread */ - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); -#endif - - /* Perform any thread setup */ - device->threadid = SDL_ThreadID(); - current_audio.impl.ThreadInit(device); - - /* Loop, filling the audio buffers */ - while (!SDL_AtomicGet(&device->shutdown)) { - int still_need; - Uint8 *ptr; - - if (SDL_AtomicGet(&device->paused)) { - SDL_Delay(delay); /* just so we don't cook the CPU. */ - if (device->stream) { - SDL_ClearAudioStream(device->stream); - } - current_audio.impl.FlushCapture(device); /* dump anything pending. */ - continue; - } - - /* Fill the current buffer with sound */ - still_need = data_len; - - /* Use the work_buffer to hold data read from the device. */ - data = device->work_buffer; - SDL_assert(data != NULL); - - ptr = data; - - /* We still read from the device when "paused" to keep the state sane, - and block when there isn't data so this thread isn't eating CPU. - 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. */ - } 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. :) */ - if (rc > 0) { - still_need -= rc; - ptr += rc; - } else { /* uhoh, device failed for some reason! */ - SDL_OpenedAudioDeviceDisconnected(device); - break; - } - } - } - - if (still_need > 0) { - /* Keep any data we already read, silence the rest. */ - SDL_memset(ptr, silence, still_need); - } - - if (device->stream) { - /* if this fails...oh well. */ - SDL_PutAudioStreamData(device->stream, data, data_len); - - while (SDL_GetAudioStreamAvailable(device->stream) >= ((int)device->callbackspec.size)) { - const int got = SDL_GetAudioStreamData(device->stream, device->work_buffer, device->callbackspec.size); - SDL_assert((got < 0) || ((Uint32)got == device->callbackspec.size)); - if ((Uint32)got != device->callbackspec.size) { - SDL_memset(device->work_buffer, device->spec.silence, device->callbackspec.size); - } - - /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (!SDL_AtomicGet(&device->paused)) { - callback(udata, device->work_buffer, device->callbackspec.size); - } - SDL_UnlockMutex(device->mixer_lock); - } - } else { /* feeding user callback directly without streaming. */ - /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (!SDL_AtomicGet(&device->paused)) { - callback(udata, data, device->callbackspec.size); - } - SDL_UnlockMutex(device->mixer_lock); - } - } - - current_audio.impl.FlushCapture(device); - - current_audio.impl.ThreadDeinit(device); - - return 0; -} - -static SDL_AudioFormat SDL_ParseAudioFormat(const char *string) -{ -#define CHECK_FMT_STRING(x) \ - if (SDL_strcmp(string, #x) == 0) \ - return SDL_AUDIO_##x - CHECK_FMT_STRING(U8); - CHECK_FMT_STRING(S8); - CHECK_FMT_STRING(S16LSB); - CHECK_FMT_STRING(S16MSB); - CHECK_FMT_STRING(S16); - CHECK_FMT_STRING(S32LSB); - CHECK_FMT_STRING(S32MSB); - CHECK_FMT_STRING(S32SYS); - CHECK_FMT_STRING(S32); - CHECK_FMT_STRING(F32LSB); - CHECK_FMT_STRING(F32MSB); - CHECK_FMT_STRING(F32SYS); - CHECK_FMT_STRING(F32); -#undef CHECK_FMT_STRING - return 0; -} +static SDL_AudioDriver current_audio; int SDL_GetNumAudioDrivers(void) { @@ -780,76 +111,463 @@ const char *SDL_GetAudioDriver(int index) return NULL; } -int SDL_InitAudio(const char *driver_name) +const char *SDL_GetCurrentAudioDriver(void) { - int i; - SDL_bool initialized = SDL_FALSE, tried_to_init = SDL_FALSE; + return current_audio.name; +} - if (SDL_GetCurrentAudioDriver()) { - SDL_QuitAudio(); /* shutdown driver if already running. */ +// device management and hotplug... + + +/* SDL_AudioDevice, in SDL3, represents a piece of physical hardware, whether it is in use or not, so these objects exist as long as + the system-level device is available. + + Physical devices get destroyed for three reasons: + - They were lost to the system (a USB cable is kicked out, etc). + - They failed for some other unlikely reason at the API level (which is _also_ probably a USB cable being kicked out). + - We are shutting down, so all allocated resources are being freed. + + They are _not_ destroyed because we are done using them (when we "close" a playing device). +*/ +static void ClosePhysicalAudioDevice(SDL_AudioDevice *device); + + +// the loop in assign_audio_device_instance_id relies on this being true. +SDL_COMPILE_TIME_ASSERT(check_lowest_audio_default_value, SDL_AUDIO_DEVICE_DEFAULT_CAPTURE < SDL_AUDIO_DEVICE_DEFAULT_OUTPUT); + +static SDL_AudioDeviceID assign_audio_device_instance_id(SDL_bool iscapture, SDL_bool islogical) +{ + /* Assign an instance id! Start at 2, in case there are things from the SDL2 era that still think 1 is a special value. + There's no reasonable scenario where this rolls over, but just in case, we wrap it in a loop. + Also, make sure we don't assign SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, etc. */ + + // The bottom two bits of the instance id tells you if it's an output device (1<<0), and if it's a physical device (1<<1). Make sure these are right. + const SDL_AudioDeviceID required_mask = (iscapture ? 0 : (1<<0)) | (islogical ? 0 : (1<<1)); + + SDL_AudioDeviceID instance_id; + do { + instance_id = (SDL_AudioDeviceID) (SDL_AtomicIncRef(¤t_audio.last_device_instance_id) + 1); + } while ( (instance_id < 2) || (instance_id >= SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) || ((instance_id & 0x3) != required_mask) ); + return instance_id; +} + +// this assumes you hold the _physical_ device lock for this logical device! This will not unlock the lock or close the physical device! +static void DestroyLogicalAudioDevice(SDL_LogicalAudioDevice *logdev) +{ + // remove ourselves from the physical device's list of logical devices. + if (logdev->next) { + logdev->next->prev = logdev->prev; + } + if (logdev->prev) { + logdev->prev->next = logdev->next; + } + if (logdev->physical_device->logical_devices == logdev) { + logdev->physical_device->logical_devices = logdev->next; } - SDL_zeroa(open_devices); + // unbind any still-bound streams... + SDL_AudioStream *next; + for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = next) { + SDL_LockMutex(stream->lock); + next = stream->next_binding; + stream->next_binding = NULL; + stream->prev_binding = NULL; + stream->bound_device = NULL; + SDL_UnlockMutex(stream->lock); + } - /* Select the proper audio driver */ + SDL_free(logdev); +} + +// this must not be called while `device` is still in a device list, or while a device's audio thread is still running (except if the thread calls this while shutting down). */ +static void DestroyPhysicalAudioDevice(SDL_AudioDevice *device) +{ + if (!device) { + return; + } + + // Destroy any logical devices that still exist... + SDL_LockMutex(device->lock); + while (device->logical_devices != NULL) { + DestroyLogicalAudioDevice(device->logical_devices); + } + SDL_UnlockMutex(device->lock); + + // it's safe to not hold the lock for this (we can't anyhow, or the audio thread won't quit), because we shouldn't be in the device list at this point. + ClosePhysicalAudioDevice(device); + + current_audio.impl.FreeDeviceHandle(device); + + SDL_DestroyMutex(device->lock); + SDL_free(device->work_buffer); + SDL_free(device->name); + SDL_free(device); +} + +static SDL_AudioDevice *CreatePhysicalAudioDevice(const char *name, SDL_bool iscapture, const SDL_AudioSpec *spec, void *handle, SDL_AudioDevice **devices, SDL_AtomicInt *device_count) +{ + SDL_assert(name != NULL); + + if (SDL_AtomicGet(¤t_audio.shutting_down)) { + return NULL; // we're shutting down, don't add any devices that are hotplugged at the last possible moment. + } + + SDL_AudioDevice *device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice)); + if (!device) { + SDL_OutOfMemory(); + return NULL; + } + + device->name = SDL_strdup(name); + if (!device->name) { + SDL_free(device); + SDL_OutOfMemory(); + return NULL; + } + + device->lock = SDL_CreateMutex(); + if (!device->lock) { + SDL_free(device->name); + SDL_free(device); + return NULL; + } + + SDL_AtomicSet(&device->shutdown, 0); + SDL_AtomicSet(&device->condemned, 0); + SDL_AtomicSet(&device->zombie, 0); + device->iscapture = iscapture; + SDL_memcpy(&device->spec, spec, sizeof (SDL_AudioSpec)); + SDL_memcpy(&device->default_spec, spec, sizeof (SDL_AudioSpec)); + device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format); + device->handle = handle; + device->prev = NULL; + + device->instance_id = assign_audio_device_instance_id(iscapture, /*islogical=*/SDL_FALSE); + + SDL_LockRWLockForWriting(current_audio.device_list_lock); + + if (*devices) { + SDL_assert((*devices)->prev == NULL); + (*devices)->prev = device; + } + device->next = *devices; + *devices = device; + SDL_AtomicAdd(device_count, 1); + SDL_UnlockRWLock(current_audio.device_list_lock); + + return device; +} + +static SDL_AudioDevice *CreateAudioCaptureDevice(const char *name, const SDL_AudioSpec *spec, void *handle) +{ + SDL_assert(current_audio.impl.HasCaptureSupport); + return CreatePhysicalAudioDevice(name, SDL_TRUE, spec, handle, ¤t_audio.capture_devices, ¤t_audio.capture_device_count); +} + +static SDL_AudioDevice *CreateAudioOutputDevice(const char *name, const SDL_AudioSpec *spec, void *handle) +{ + return CreatePhysicalAudioDevice(name, SDL_FALSE, spec, handle, ¤t_audio.output_devices, ¤t_audio.output_device_count); +} + +// The audio backends call this when a new device is plugged in. +SDL_AudioDevice *SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, const SDL_AudioSpec *inspec, void *handle) +{ + const SDL_AudioFormat default_format = iscapture ? DEFAULT_AUDIO_CAPTURE_FORMAT : DEFAULT_AUDIO_OUTPUT_FORMAT; + const int default_channels = iscapture ? DEFAULT_AUDIO_CAPTURE_CHANNELS : DEFAULT_AUDIO_OUTPUT_CHANNELS; + const int default_freq = iscapture ? DEFAULT_AUDIO_CAPTURE_FREQUENCY : DEFAULT_AUDIO_OUTPUT_FREQUENCY; + + SDL_AudioSpec spec; + if (!inspec) { + spec.format = default_format; + spec.channels = default_channels; + spec.freq = default_freq; + } else { + spec.format = (inspec->format != 0) ? inspec->format : default_format; + spec.channels = (inspec->channels != 0) ? inspec->channels : default_channels; + spec.freq = (inspec->freq != 0) ? inspec->freq : default_freq; + } + + SDL_AudioDevice *device = iscapture ? CreateAudioCaptureDevice(name, &spec, handle) : CreateAudioOutputDevice(name, &spec, handle); + if (device) { + // Post the event, if desired + if (SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_ADDED)) { + SDL_Event event; + event.type = SDL_EVENT_AUDIO_DEVICE_ADDED; + event.common.timestamp = 0; + event.adevice.which = device->instance_id; + event.adevice.iscapture = iscapture; + SDL_PushEvent(&event); + } + } + + return device; +} + +// this _also_ destroys the logical device! +static void DisconnectLogicalAudioDevice(SDL_LogicalAudioDevice *logdev) +{ + if (SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_REMOVED)) { + SDL_Event event; + SDL_zero(event); + event.type = SDL_EVENT_AUDIO_DEVICE_REMOVED; + event.common.timestamp = 0; + event.adevice.which = logdev->instance_id; + event.adevice.iscapture = logdev->physical_device->iscapture ? 1 : 0; + SDL_PushEvent(&event); + } + + DestroyLogicalAudioDevice(logdev); +} + +// Called when a device is removed from the system, or it fails unexpectedly, from any thread, possibly even the audio device's thread. +void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device) +{ + if (!device) { + return; + } + + // if the current default device is going down, mark it as dead but keep it around until a replacement is decided upon, so we can migrate logical devices to it. + if ((device->instance_id == current_audio.default_output_device_id) || (device->instance_id == current_audio.default_capture_device_id)) { + SDL_LockMutex(device->lock); // make sure nothing else is messing with the device before continuing. + SDL_AtomicSet(&device->zombie, 1); + SDL_AtomicSet(&device->shutdown, 1); // tell audio thread to terminate, but don't mark it condemned, so the thread won't destroy the device. We'll join on the audio thread later. + + // dump any logical devices that explicitly opened this device. Things that opened the system default can stay. + SDL_LogicalAudioDevice *next = NULL; + for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = next) { + next = logdev->next; + if (!logdev->is_default) { // if opened as a default, leave it on the zombie device for later migration. + DisconnectLogicalAudioDevice(logdev); + } + } + SDL_UnlockMutex(device->lock); // make sure nothing else is messing with the device before continuing. + return; // done for now. Come back when a new default device is chosen! + } + + SDL_bool was_live = SDL_FALSE; + + // take it out of the device list. + SDL_LockRWLockForWriting(current_audio.device_list_lock); + SDL_LockMutex(device->lock); // make sure nothing else is messing with the device before continuing. + if (device == current_audio.output_devices) { + SDL_assert(device->prev == NULL); + current_audio.output_devices = device->next; + was_live = SDL_TRUE; + } else if (device == current_audio.capture_devices) { + SDL_assert(device->prev == NULL); + current_audio.capture_devices = device->next; + was_live = SDL_TRUE; + } + if (device->prev != NULL) { + device->prev->next = device->next; + was_live = SDL_TRUE; + } + if (device->next != NULL) { + device->next->prev = device->prev; + was_live = SDL_TRUE; + } + + device->next = NULL; + device->prev = NULL; + + if (was_live) { + SDL_AtomicAdd(device->iscapture ? ¤t_audio.capture_device_count : ¤t_audio.output_device_count, -1); + } + + SDL_UnlockRWLock(current_audio.device_list_lock); + + // now device is not in the list, and we own it, so no one should be able to find it again, except the audio thread, which holds a pointer! + SDL_AtomicSet(&device->condemned, 1); + SDL_AtomicSet(&device->shutdown, 1); // tell audio thread to terminate. + + // disconnect each attached logical device, so apps won't find their streams still bound if they get the REMOVED event before the device thread cleans up. + SDL_LogicalAudioDevice *next; + for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = next) { + next = logdev->next; + DisconnectLogicalAudioDevice(logdev); + } + + // if there's an audio thread, don't free until thread is terminating, otherwise free stuff now. + const SDL_bool should_destroy = SDL_AtomicGet(&device->thread_alive) ? SDL_FALSE : SDL_TRUE; + SDL_UnlockMutex(device->lock); + + // Post the event, if we haven't tried to before and if it's desired + if (was_live && SDL_EventEnabled(SDL_EVENT_AUDIO_DEVICE_REMOVED)) { + SDL_Event event; + SDL_zero(event); + event.type = SDL_EVENT_AUDIO_DEVICE_REMOVED; + event.common.timestamp = 0; + event.adevice.which = device->instance_id; + event.adevice.iscapture = device->iscapture ? 1 : 0; + SDL_PushEvent(&event); + } + + if (should_destroy) { + DestroyPhysicalAudioDevice(device); + } +} + + +// stubs for audio drivers that don't need a specific entry point... + +static void SDL_AudioThreadDeinit_Default(SDL_AudioDevice *device) { /* no-op. */ } +static void SDL_AudioWaitDevice_Default(SDL_AudioDevice *device) { /* no-op. */ } +static void SDL_AudioPlayDevice_Default(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { /* no-op. */ } +static void SDL_AudioWaitCaptureDevice_Default(SDL_AudioDevice *device) { /* no-op. */ } +static void SDL_AudioFlushCapture_Default(SDL_AudioDevice *device) { /* no-op. */ } +static void SDL_AudioCloseDevice_Default(SDL_AudioDevice *device) { /* no-op. */ } +static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ } +static void SDL_AudioFreeDeviceHandle_Default(SDL_AudioDevice *device) { /* no-op. */ } + +static void SDL_AudioThreadInit_Default(SDL_AudioDevice *device) +{ + SDL_SetThreadPriority(device->iscapture ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL); +} + +static void SDL_AudioDetectDevices_Default(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) +{ + // 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); + + *default_output = SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)((size_t)0x1)); + if (current_audio.impl.HasCaptureSupport) { + *default_capture = SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)((size_t)0x2)); + } +} + +static Uint8 *SDL_AudioGetDeviceBuf_Default(SDL_AudioDevice *device, int *buffer_size) +{ + *buffer_size = 0; + return NULL; +} + +static int SDL_AudioCaptureFromDevice_Default(SDL_AudioDevice *device, void *buffer, int buflen) +{ + return SDL_Unsupported(); +} + +static int SDL_AudioOpenDevice_Default(SDL_AudioDevice *device) +{ + return SDL_Unsupported(); +} + +// Fill in stub functions for unused driver entry points. This lets us blindly call them without having to check for validity first. +static void CompleteAudioEntryPoints(void) +{ + #define FILL_STUB(x) if (!current_audio.impl.x) { current_audio.impl.x = SDL_Audio##x##_Default; } + FILL_STUB(DetectDevices); + FILL_STUB(OpenDevice); + FILL_STUB(ThreadInit); + FILL_STUB(ThreadDeinit); + FILL_STUB(WaitDevice); + FILL_STUB(PlayDevice); + FILL_STUB(GetDeviceBuf); + FILL_STUB(WaitCaptureDevice); + FILL_STUB(CaptureFromDevice); + FILL_STUB(FlushCapture); + FILL_STUB(CloseDevice); + FILL_STUB(FreeDeviceHandle); + FILL_STUB(Deinitialize); + #undef FILL_STUB +} + +static SDL_AudioDeviceID GetFirstAddedAudioDeviceID(const SDL_bool iscapture) +{ + // (these are pushed to the front of the linked list as added, so the first device added is last in the list.) + SDL_LockRWLockForReading(current_audio.device_list_lock); + SDL_AudioDevice *last = NULL; + for (SDL_AudioDevice *i = iscapture ? current_audio.capture_devices : current_audio.output_devices; i != NULL; i = i->next) { + last = i; + } + const SDL_AudioDeviceID retval = last ? last->instance_id : 0; + SDL_UnlockRWLock(current_audio.device_list_lock); + return retval; +} + +// !!! FIXME: the video subsystem does SDL_VideoInit, not SDL_InitVideo. Make this match. +int SDL_InitAudio(const char *driver_name) +{ + if (SDL_GetCurrentAudioDriver()) { + SDL_QuitAudio(); // shutdown driver if already running. + } + + SDL_ChooseAudioConverters(); + + SDL_RWLock *device_list_lock = SDL_CreateRWLock(); // create this early, so if it fails we don't have to tear down the whole audio subsystem. + if (!device_list_lock) { + return -1; + } + + // Select the proper audio driver if (driver_name == NULL) { driver_name = SDL_GetHint(SDL_HINT_AUDIO_DRIVER); } + SDL_bool initialized = SDL_FALSE; + SDL_bool tried_to_init = SDL_FALSE; + if (driver_name != NULL && *driver_name != 0) { - const char *driver_attempt = driver_name; + char *driver_name_copy = SDL_strdup(driver_name); + const char *driver_attempt = driver_name_copy; + + if (driver_name_copy == NULL) { + SDL_DestroyRWLock(device_list_lock); + return SDL_OutOfMemory(); + } + 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)) { + char *driver_attempt_end = SDL_strchr(driver_attempt, ','); + if (driver_attempt_end != NULL) { + *driver_attempt_end = '\0'; + } + + // SDL 1.2 uses the name "dsound", so we'll support both. + if (SDL_strcmp(driver_attempt, "dsound") == 0) { driver_attempt = "directsound"; - driver_attempt_len = SDL_strlen("directsound"); - } -#endif - -#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)) { + } else if (SDL_strcmp(driver_attempt, "pulse") == 0) { // likewise, "pulse" was renamed to "pulseaudio" 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)) { + for (int i = 0; bootstrap[i]; ++i) { + if (SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 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); + SDL_AtomicSet(¤t_audio.last_device_instance_id, 2); // start past 1 because of SDL2's legacy interface. + current_audio.device_list_lock = device_list_lock; + if (bootstrap[i]->init(¤t_audio.impl)) { + current_audio.name = bootstrap[i]->name; + current_audio.desc = bootstrap[i]->desc; + initialized = SDL_TRUE; + } break; } } driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL; } + + SDL_free(driver_name_copy); } else { - for (i = 0; (!initialized) && (bootstrap[i]); ++i) { + for (int 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); + SDL_AtomicSet(¤t_audio.last_device_instance_id, 2); // start past 1 because of SDL2's legacy interface. + current_audio.device_list_lock = device_list_lock; + if (bootstrap[i]->init(¤t_audio.impl)) { + current_audio.name = bootstrap[i]->name; + current_audio.desc = bootstrap[i]->desc; + initialized = SDL_TRUE; + } } } if (!initialized) { - /* specific drivers will set the error message if they fail... */ + // specific drivers will set the error message if they fail, but otherwise we do it here. if (!tried_to_init) { if (driver_name) { SDL_SetError("Audio target '%s' not available", driver_name); @@ -859,637 +577,962 @@ int SDL_InitAudio(const char *driver_name) } SDL_zero(current_audio); - return -1; /* No driver was available, so fail. */ + SDL_DestroyRWLock(device_list_lock); + current_audio.device_list_lock = NULL; + return -1; // No driver was available, so fail. } - current_audio.detectionLock = SDL_CreateMutex(); + CompleteAudioEntryPoints(); - finish_audio_entry_points_init(); + // Make sure we have a list of devices available at startup... + SDL_AudioDevice *default_output = NULL; + SDL_AudioDevice *default_capture = NULL; + current_audio.impl.DetectDevices(&default_output, &default_capture); - /* Make sure we have a list of devices available at startup. */ - current_audio.impl.DetectDevices(); + // these are only set if default_* is non-NULL, in case the backend just called SDL_DefaultAudioDeviceChanged directly during DetectDevices. + if (default_output) { + current_audio.default_output_device_id = default_output->instance_id; + } + if (default_capture) { + current_audio.default_capture_device_id = default_capture->instance_id; + } + + // If no default was _ever_ specified, just take the first device we see, if any. + if (!current_audio.default_output_device_id) { + current_audio.default_output_device_id = GetFirstAddedAudioDeviceID(/*iscapture=*/SDL_FALSE); + } + if (!current_audio.default_capture_device_id) { + current_audio.default_capture_device_id = GetFirstAddedAudioDeviceID(/*iscapture=*/SDL_TRUE); + } return 0; } -/* - * Get the current audio driver name - */ -const char *SDL_GetCurrentAudioDriver(void) +void SDL_QuitAudio(void) { - return current_audio.name; -} + if (!current_audio.name) { // not initialized?! + return; + } -/* 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) -{ - SDL_AudioDeviceItem *item = *devices; - SDL_AudioDeviceItem *prev = NULL; - int total = 0; + // merge device lists so we don't have to duplicate work below. + SDL_LockRWLockForWriting(current_audio.device_list_lock); + SDL_AtomicSet(¤t_audio.shutting_down, 1); + SDL_AudioDevice *devices = NULL; + for (SDL_AudioDevice *i = current_audio.output_devices; i != NULL; i = i->next) { + devices = i; + } + if (!devices) { + devices = current_audio.capture_devices; + } else { + SDL_assert(devices->next == NULL); + devices->next = current_audio.capture_devices; + devices = current_audio.output_devices; + } + current_audio.output_devices = NULL; + current_audio.capture_devices = NULL; + SDL_AtomicSet(¤t_audio.output_device_count, 0); + SDL_AtomicSet(¤t_audio.capture_device_count, 0); + SDL_UnlockRWLock(current_audio.device_list_lock); + + // mark all devices for shutdown so all threads can begin to terminate. + for (SDL_AudioDevice *i = devices; i != NULL; i = i->next) { + SDL_AtomicSet(&i->shutdown, 1); + } - while (item) { - SDL_AudioDeviceItem *next = item->next; - if (item->handle != NULL) { - total++; - prev = item; - } else { - if (prev) { - prev->next = next; - } else { - *devices = next; - } - /* these two pointers are the same if not a duplicate devname */ - if (item->name != item->original_name) { - SDL_free(item->name); - } - SDL_free(item->original_name); - SDL_free(item); + // now wait on any audio threads... + for (SDL_AudioDevice *i = devices; i != NULL; i = i->next) { + if (i->thread) { + SDL_assert(!SDL_AtomicGet(&i->condemned)); // these shouldn't have been in the device list still, and thread should have detached. + SDL_WaitThread(i->thread, NULL); + i->thread = NULL; } - item = next; } - *devCount = total; - *removedFlag = SDL_FALSE; + while (devices) { + SDL_AudioDevice *next = devices->next; + DestroyPhysicalAudioDevice(devices); + devices = next; + } + + // Free the driver data + current_audio.impl.Deinitialize(); + + SDL_DestroyRWLock(current_audio.device_list_lock); + + SDL_zero(current_audio); } -int SDL_GetNumAudioDevices(int iscapture) + +void SDL_AudioThreadFinalize(SDL_AudioDevice *device) { - int retval = 0; + if (SDL_AtomicGet(&device->condemned)) { + if (device->thread) { + SDL_DetachThread(device->thread); // no one is waiting for us, just detach ourselves. + device->thread = NULL; + SDL_AtomicSet(&device->thread_alive, 0); + } + DestroyPhysicalAudioDevice(device); + } + SDL_AtomicSet(&device->thread_alive, 0); +} - if (!SDL_GetCurrentAudioDriver()) { - return -1; +// Output device thread. This is split into chunks, so backends that need to control this directly can use the pieces they need without duplicating effort. + +void SDL_OutputAudioThreadSetup(SDL_AudioDevice *device) +{ + SDL_assert(!device->iscapture); + current_audio.impl.ThreadInit(device); +} + +SDL_bool SDL_OutputAudioThreadIterate(SDL_AudioDevice *device) +{ + SDL_assert(!device->iscapture); + + SDL_LockMutex(device->lock); + + if (SDL_AtomicGet(&device->shutdown)) { + SDL_UnlockMutex(device->lock); + return SDL_FALSE; // we're done, shut it down. } - SDL_LockMutex(current_audio.detectionLock); - if (iscapture && current_audio.captureDevicesRemoved) { - clean_out_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount, ¤t_audio.captureDevicesRemoved); + SDL_bool retval = SDL_TRUE; + int buffer_size = device->buffer_size; + Uint8 *mix_buffer = current_audio.impl.GetDeviceBuf(device, &buffer_size); + if (!mix_buffer) { + retval = SDL_FALSE; + } else { + SDL_assert(buffer_size <= device->buffer_size); // you can ask for less, but not more. + SDL_memset(mix_buffer, device->silence_value, buffer_size); // start with silence. + + for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) { + if (SDL_AtomicGet(&logdev->paused)) { + continue; // paused? Skip this logical device. + } + + for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) { + /* this will hold a lock on `stream` while getting. We don't explicitly lock the streams + for iterating here because the binding linked list can only change while the device lock is held. + (we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind + the same stream to different devices at the same time, though.) */ + const int br = SDL_GetAudioStreamData(stream, device->work_buffer, buffer_size); + if (br < 0) { + // oh crud, we probably ran out of memory. This is possibly an overreaction to kill the audio device, but it's likely the whole thing is going down in a moment anyhow. + retval = SDL_FALSE; + break; + } else if (br > 0) { // it's okay if we get less than requested, we mix what we have. + // !!! FIXME: this needs to mix to float32 or int32, so we don't clip. + if (SDL_MixAudioFormat(mix_buffer, device->work_buffer, device->spec.format, br, SDL_MIX_MAXVOLUME) < 0) { // !!! FIXME: allow streams to specify gain? + SDL_assert(!"We probably ended up with some totally unexpected audio format here"); + retval = SDL_FALSE; // uh...? + break; + } + } + } + } + + // !!! FIXME: have PlayDevice return a value and do disconnects in here with it. + current_audio.impl.PlayDevice(device, mix_buffer, buffer_size); // this SHOULD NOT BLOCK, as we are holding a lock right now. Block in WaitDevice! } - if (!iscapture && current_audio.outputDevicesRemoved) { - clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved); - } + SDL_UnlockMutex(device->lock); - retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; - SDL_UnlockMutex(current_audio.detectionLock); + if (!retval) { + SDL_AudioDeviceDisconnected(device); // doh. + } return retval; } -const char *SDL_GetAudioDeviceName(int index, int iscapture) +void SDL_OutputAudioThreadShutdown(SDL_AudioDevice *device) { - SDL_AudioDeviceItem *item; - int i; - const char *retval; + SDL_assert(!device->iscapture); + const int samples = (device->buffer_size / (SDL_AUDIO_BITSIZE(device->spec.format) / 8)) / device->spec.channels; + // Wait for the audio to drain. !!! FIXME: don't bother waiting if device is lost. + SDL_Delay(((samples * 1000) / device->spec.freq) * 2); + current_audio.impl.ThreadDeinit(device); + SDL_AudioThreadFinalize(device); +} + +static int SDLCALL OutputAudioThread(void *devicep) // thread entry point +{ + SDL_AudioDevice *device = (SDL_AudioDevice *)devicep; + SDL_assert(device != NULL); + SDL_assert(!device->iscapture); + SDL_OutputAudioThreadSetup(device); + do { + current_audio.impl.WaitDevice(device); + } while (SDL_OutputAudioThreadIterate(device)); + + SDL_OutputAudioThreadShutdown(device); + return 0; +} + + + +// Capture device thread. This is split into chunks, so backends that need to control this directly can use the pieces they need without duplicating effort. + +void SDL_CaptureAudioThreadSetup(SDL_AudioDevice *device) +{ + SDL_assert(device->iscapture); + current_audio.impl.ThreadInit(device); +} + +SDL_bool SDL_CaptureAudioThreadIterate(SDL_AudioDevice *device) +{ + SDL_assert(device->iscapture); + + SDL_LockMutex(device->lock); + + SDL_bool retval = SDL_TRUE; + + if (SDL_AtomicGet(&device->shutdown)) { + retval = SDL_FALSE; // we're done, shut it down. + } else if (device->logical_devices == NULL) { + current_audio.impl.FlushCapture(device); // nothing wants data, dump anything pending. + } else { + // this SHOULD NOT BLOCK, as we are holding a lock right now. Block in WaitCaptureDevice! + const int rc = current_audio.impl.CaptureFromDevice(device, device->work_buffer, device->buffer_size); + if (rc < 0) { // uhoh, device failed for some reason! + retval = SDL_FALSE; + } else if (rc > 0) { // queue the new data to each bound stream. + for (SDL_LogicalAudioDevice *logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) { + if (SDL_AtomicGet(&logdev->paused)) { + continue; // paused? Skip this logical device. + } + + for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) { + /* this will hold a lock on `stream` while putting. We don't explicitly lock the streams + for iterating here because the binding linked list can only change while the device lock is held. + (we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind + the same stream to different devices at the same time, though.) */ + if (SDL_PutAudioStreamData(stream, device->work_buffer, rc) < 0) { + // oh crud, we probably ran out of memory. This is possibly an overreaction to kill the audio device, but it's likely the whole thing is going down in a moment anyhow. + retval = SDL_FALSE; + break; + } + } + } + } + } + + SDL_UnlockMutex(device->lock); + + if (!retval) { + SDL_AudioDeviceDisconnected(device); // doh. + } + + return retval; +} + +void SDL_CaptureAudioThreadShutdown(SDL_AudioDevice *device) +{ + SDL_assert(device->iscapture); + current_audio.impl.FlushCapture(device); + current_audio.impl.ThreadDeinit(device); + SDL_AudioThreadFinalize(device); +} + +static int SDLCALL CaptureAudioThread(void *devicep) // thread entry point +{ + SDL_AudioDevice *device = (SDL_AudioDevice *)devicep; + SDL_assert(device != NULL); + SDL_assert(device->iscapture); + SDL_CaptureAudioThreadSetup(device); + + do { + current_audio.impl.WaitCaptureDevice(device); + } while (SDL_CaptureAudioThreadIterate(device)); + + SDL_CaptureAudioThreadShutdown(device); + return 0; +} + + +static SDL_AudioDeviceID *GetAudioDevices(int *reqcount, SDL_AudioDevice **devices, SDL_AtomicInt *device_count) +{ + if (!SDL_GetCurrentAudioDriver()) { + SDL_SetError("Audio subsystem is not initialized"); + return NULL; + } + + SDL_LockRWLockForReading(current_audio.device_list_lock); + int num_devices = SDL_AtomicGet(device_count); + SDL_AudioDeviceID *retval = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID)); + if (retval == NULL) { + num_devices = 0; + SDL_OutOfMemory(); + } else { + const SDL_AudioDevice *dev = *devices; // pointer to a pointer so we can dereference it after the lock is held. + for (int i = 0; i < num_devices; i++) { + SDL_assert(dev != NULL); + SDL_assert(!SDL_AtomicGet((SDL_AtomicInt *) &dev->condemned)); // shouldn't be in the list if pending deletion. + retval[i] = dev->instance_id; + dev = dev->next; + } + SDL_assert(dev == NULL); // did the whole list? + retval[num_devices] = 0; // null-terminated. + } + SDL_UnlockRWLock(current_audio.device_list_lock); + + if (reqcount != NULL) { + *reqcount = num_devices; + } + + return retval; +} + +SDL_AudioDeviceID *SDL_GetAudioOutputDevices(int *count) +{ + return GetAudioDevices(count, ¤t_audio.output_devices, ¤t_audio.output_device_count); +} + +SDL_AudioDeviceID *SDL_GetAudioCaptureDevices(int *count) +{ + return GetAudioDevices(count, ¤t_audio.capture_devices, ¤t_audio.capture_device_count); +} + +// If found, this locks _the physical device_ this logical device is associated with, before returning. +static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid) +{ + if (!SDL_GetCurrentAudioDriver()) { + SDL_SetError("Audio subsystem is not initialized"); + return NULL; + } + + SDL_LogicalAudioDevice *logdev = NULL; + + const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE; + if (islogical) { // don't bother looking if it's not a logical device id value. + const SDL_bool iscapture = (devid & (1<<0)) ? SDL_FALSE : SDL_TRUE; + + SDL_LockRWLockForReading(current_audio.device_list_lock); + + for (SDL_AudioDevice *device = iscapture ? current_audio.capture_devices : current_audio.output_devices; device != NULL; device = device->next) { + SDL_LockMutex(device->lock); // caller must unlock if we choose a logical device from this guy. + SDL_assert(!SDL_AtomicGet(&device->condemned)); // shouldn't be in the list if pending deletion. + for (logdev = device->logical_devices; logdev != NULL; logdev = logdev->next) { + if (logdev->instance_id == devid) { + break; // found it! + } + } + if (logdev != NULL) { + break; + } + SDL_UnlockMutex(device->lock); // give up this lock and try the next physical device. + } + + SDL_UnlockRWLock(current_audio.device_list_lock); + } + + if (!logdev) { + SDL_SetError("Invalid audio device instance ID"); + } + + return logdev; +} + +/* this finds the physical device associated with `devid` and locks it for use. + Note that a logical device instance id will return its associated physical device! */ +static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid) +{ + // bit #1 of devid is set for physical devices and unset for logical. + const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE; + if (islogical) { + SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); + if (logdev) { + return logdev->physical_device; + } + return NULL; + } if (!SDL_GetCurrentAudioDriver()) { SDL_SetError("Audio subsystem is not initialized"); return 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); - } - SDL_assert(item != NULL); - retval = item->name; - } else { - SDL_InvalidParamError("index"); - retval = NULL; - } - SDL_UnlockMutex(current_audio.detectionLock); + // bit #0 of devid is set for output devices and unset for capture. + const SDL_bool iscapture = (devid & (1<<0)) ? SDL_FALSE : SDL_TRUE; + SDL_AudioDevice *dev = NULL; - return retval; -} + SDL_LockRWLockForReading(current_audio.device_list_lock); -int SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec) -{ - SDL_AudioDeviceItem *item; - int i, retval; - - 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; - } - - /* make sure the device is paused before we do anything else, so the - audio callback definitely won't fire again. */ - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->paused, 1); - SDL_AtomicSet(&device->shutdown, 1); - SDL_AtomicSet(&device->enabled, 0); - current_audio.impl.UnlockDevice(device); - - if (device->thread != NULL) { - SDL_WaitThread(device->thread, NULL); - } - if (device->mixer_lock != NULL) { - SDL_DestroyMutex(device->mixer_lock); - } - - SDL_free(device->work_buffer); - SDL_DestroyAudioStream(device->stream); - - if (device->id > 0) { - SDL_AudioDevice *opendev = open_devices[device->id - 1]; - SDL_assert((opendev == device) || (opendev == NULL)); - if (opendev == device) { - open_devices[device->id - 1] = NULL; - } - } - - if (device->hidden != NULL) { - current_audio.impl.CloseDevice(device); - } - - SDL_DestroyDataQueue(device->buffer_queue); - - 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 = (Uint16)((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) -{ - SDL_copyp(prepared, orig); - - if (orig->freq == 0) { - static const int DEFAULT_FREQ = 22050; - const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); - 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 != NULL) { - const SDL_AudioFormat format = SDL_ParseAudioFormat(env); - prepared->format = format != 0 ? format : SDL_AUDIO_S16; - } else { - prepared->format = SDL_AUDIO_S16; - } - } - - 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; - } - } 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 != NULL) { - Uint16 samples = (Uint16)SDL_atoi(env); - prepared->samples = samples != 0 ? samples : GetDefaultSamplesFromFreq(prepared->freq); - } else { - prepared->samples = GetDefaultSamplesFromFreq(prepared->freq); - } - } - - /* Calculate the silence and size of the audio specification */ - SDL_CalculateAudioSpec(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) -{ - const SDL_bool is_internal_thread = (desired->callback == NULL); - SDL_AudioDeviceID id = 0; - SDL_AudioSpec _obtained; - SDL_AudioDevice *device; - SDL_bool build_stream; - void *handle = NULL; - int i = 0; - - if (!SDL_GetCurrentAudioDriver()) { - SDL_SetError("Audio subsystem is not initialized"); - return 0; - } - - if (iscapture && !current_audio.impl.HasCaptureSupport) { - SDL_SetError("No capture support"); - return 0; - } - - SDL_LockMutex(current_audio.detectionLock); - /* Find an available device ID... */ - for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { - if (open_devices[id] == NULL) { + for (dev = iscapture ? current_audio.capture_devices : current_audio.output_devices; dev != NULL; dev = dev->next) { + if (dev->instance_id == devid) { // found it? + SDL_LockMutex(dev->lock); // caller must unlock. + SDL_assert(!SDL_AtomicGet(&dev->condemned)); // shouldn't be in the list if pending deletion. break; } } - if (id == SDL_arraysize(open_devices)) { - SDL_SetError("Too many open audio devices"); - SDL_UnlockMutex(current_audio.detectionLock); - return 0; + SDL_UnlockRWLock(current_audio.device_list_lock); + + if (!dev) { + SDL_SetError("Invalid audio device instance ID"); } - if (!obtained) { - obtained = &_obtained; - } - if (!prepare_audiospec(desired, obtained)) { - SDL_UnlockMutex(current_audio.detectionLock); - return 0; + return dev; +} + +SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(SDL_bool (*callback)(SDL_AudioDevice *device, void *userdata), void *userdata) +{ + if (!SDL_GetCurrentAudioDriver()) { + SDL_SetError("Audio subsystem is not initialized"); + return NULL; } - /* If app doesn't care about a specific device, let the user override. */ - if (devname == NULL) { - devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME"); + SDL_LockRWLockForReading(current_audio.device_list_lock); + + SDL_AudioDevice *dev = NULL; + for (dev = current_audio.output_devices; dev != NULL; dev = dev->next) { + if (callback(dev, userdata)) { // found it? + break; + } } - /* - * Catch device names at the high level for the simple case... - * This lets us have a basic "device enumeration" for systems that - * don't have multiple devices, but makes sure the device name is - * always NULL when it hits the low level. - * - * Also make sure that the simple case prevents multiple simultaneous - * opens of the default system device. - */ - - if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) { - if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) { - SDL_SetError("No such device"); - SDL_UnlockMutex(current_audio.detectionLock); - return 0; - } - devname = NULL; - - 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; - } - } - } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { - if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { - SDL_UnlockMutex(current_audio.detectionLock); - SDL_SetError("No such device"); - return 0; - } - devname = NULL; - - 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; - } - } - } 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 - figuring out what device this was (such as, reenumerating - everything again to find the matching human-readable name). - It might still need to open a device based on the string for, - say, a network audio server, but this optimizes some cases. */ - SDL_AudioDeviceItem *item; - for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) { - if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) { - handle = item->handle; + if (!dev) { + // !!! FIXME: code duplication, from above. + for (dev = current_audio.capture_devices; dev != NULL; dev = dev->next) { + if (callback(dev, userdata)) { // found it? break; } } } - if (!current_audio.impl.AllowsArbitraryDeviceNames) { - /* has to be in our device list, or the default device. */ - if ((handle == NULL) && (devname != NULL)) { - SDL_SetError("No such device."); - SDL_UnlockMutex(current_audio.detectionLock); - return 0; - } + SDL_UnlockRWLock(current_audio.device_list_lock); + + if (!dev) { + SDL_SetError("Device not found"); } - device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice)); - if (device == NULL) { + SDL_assert(!dev || !SDL_AtomicGet(&dev->condemned)); // shouldn't be in the list if pending deletion. + + return dev; +} + +static SDL_bool TestDeviceHandleCallback(SDL_AudioDevice *device, void *handle) +{ + return device->handle == handle; +} + +SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle) +{ + return SDL_FindPhysicalAudioDeviceByCallback(TestDeviceHandleCallback, handle); +} + +char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid) +{ + SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid); + if (!device) { + return NULL; + } + + char *retval = SDL_strdup(device->name); + if (!retval) { SDL_OutOfMemory(); - SDL_UnlockMutex(current_audio.detectionLock); - 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->paused, 1); - SDL_AtomicSet(&device->enabled, 1); - - /* Create a mutex for locking the sound buffers */ - if (current_audio.impl.LockDevice == SDL_AudioLockDevice_Default) { - device->mixer_lock = SDL_CreateMutex(); - if (device->mixer_lock == NULL) { - close_audio_device(device); - SDL_UnlockMutex(current_audio.detectionLock); - SDL_SetError("Couldn't create mixer lock"); - return 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) { - int samples = SDL_powerof2(device->spec.samples); - if (samples <= SDL_MAX_UINT16) { - device->spec.samples = (Uint16)samples; - } else { - SDL_SetError("Couldn't hold sample count %d\n", samples); - return 0; - } - } + SDL_UnlockMutex(device->lock); - if (current_audio.impl.OpenDevice(device, devname) < 0) { - close_audio_device(device); - SDL_UnlockMutex(current_audio.detectionLock); - return 0; - } - - /* if your target really doesn't need it, set it to 0x1 or something. */ - /* otherwise, close_audio_device() won't call impl.CloseDevice(). */ - SDL_assert(device->hidden != NULL); - - /* See if we need to do any conversion */ - build_stream = SDL_FALSE; - if (obtained->freq != device->spec.freq) { - if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) { - obtained->freq = device->spec.freq; - } else { - build_stream = SDL_TRUE; - } - } - if (obtained->format != device->spec.format) { - if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) { - obtained->format = device->spec.format; - } else { - build_stream = SDL_TRUE; - } - } - if (obtained->channels != device->spec.channels) { - if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) { - obtained->channels = device->spec.channels; - } else { - build_stream = SDL_TRUE; - } - } - if (device->spec.samples != obtained->samples) { - if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) { - obtained->samples = device->spec.samples; - } else { - build_stream = SDL_TRUE; - } - } - - SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */ - - device->callbackspec = *obtained; - - if (build_stream) { - if (iscapture) { - device->stream = SDL_CreateAudioStream(device->spec.format, - device->spec.channels, device->spec.freq, - obtained->format, obtained->channels, obtained->freq); - } else { - device->stream = SDL_CreateAudioStream(obtained->format, obtained->channels, - obtained->freq, device->spec.format, - device->spec.channels, device->spec.freq); - } - - if (!device->stream) { - close_audio_device(device); - SDL_UnlockMutex(current_audio.detectionLock); - return 0; - } - } - - if (device->spec.callback == NULL) { /* use buffer queueing? */ - /* pool a few packets to start. Enough for two callbacks. */ - device->buffer_queue = SDL_CreateDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2); - if (!device->buffer_queue) { - close_audio_device(device); - SDL_UnlockMutex(current_audio.detectionLock); - SDL_SetError("Couldn't create audio buffer queue"); - return 0; - } - device->callbackspec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback; - device->callbackspec.userdata = device; - } - - /* Allocate a scratch audio buffer */ - device->work_buffer_len = build_stream ? device->callbackspec.size : 0; - if (device->spec.size > device->work_buffer_len) { - device->work_buffer_len = device->spec.size; - } - SDL_assert(device->work_buffer_len > 0); - - device->work_buffer = (Uint8 *)SDL_malloc(device->work_buffer_len); - if (device->work_buffer == NULL) { - close_audio_device(device); - SDL_UnlockMutex(current_audio.detectionLock); - SDL_OutOfMemory(); - return 0; - } - - open_devices[id] = device; /* add it to our list of open devices. */ - - /* 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]; - - (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, stacksize, device); - - if (device->thread == NULL) { - close_audio_device(device); - SDL_SetError("Couldn't create audio thread"); - SDL_UnlockMutex(current_audio.detectionLock); - return 0; - } - } - SDL_UnlockMutex(current_audio.detectionLock); - - return device->id; + return retval; } -SDL_AudioDeviceID SDL_OpenAudioDevice(const char *device, int iscapture, - const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, - int allowed_changes) +int SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec) { - return open_audio_device(device, iscapture, desired, obtained, - allowed_changes, 2); -} - -SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) -{ - SDL_AudioDevice *device = get_audio_device(devid); - SDL_AudioStatus status = SDL_AUDIO_STOPPED; - if (device && SDL_AtomicGet(&device->enabled)) { - if (SDL_AtomicGet(&device->paused)) { - status = SDL_AUDIO_PAUSED; - } else { - status = SDL_AUDIO_PLAYING; - } + if (!spec) { + return SDL_InvalidParamError("spec"); } - return status; -} -int SDL_PauseAudioDevice(SDL_AudioDeviceID devid) -{ - SDL_AudioDevice *device = get_audio_device(devid); + SDL_bool is_default = SDL_FALSE; + if (devid == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) { + devid = current_audio.default_output_device_id; + is_default = SDL_TRUE; + } else if (devid == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) { + devid = current_audio.default_capture_device_id; + is_default = SDL_TRUE; + } + + if ((devid == 0) && is_default) { + return SDL_SetError("No default audio device available"); + } + + SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid); if (!device) { - return SDL_InvalidParamError("devid"); + return -1; } - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->paused, 1); - current_audio.impl.UnlockDevice(device); + + SDL_memcpy(spec, &device->spec, sizeof (SDL_AudioSpec)); + SDL_UnlockMutex(device->lock); + return 0; } -int SDL_PlayAudioDevice(SDL_AudioDeviceID devid) +// this expects the device lock to be held. !!! FIXME: no it doesn't...? +static void ClosePhysicalAudioDevice(SDL_AudioDevice *device) { - SDL_AudioDevice *device = get_audio_device(devid); - if (!device) { - return SDL_InvalidParamError("devid"); - } - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->paused, 0); - current_audio.impl.UnlockDevice(device); - return 0; -} + SDL_assert(current_audio.impl.ProvidesOwnCallbackThread || ((device->thread == NULL) == (SDL_AtomicGet(&device->thread_alive) == 0))); -int SDL_LockAudioDevice(SDL_AudioDeviceID devid) -{ - /* Obtain a lock on the mixing buffers */ - SDL_AudioDevice *device = get_audio_device(devid); - if (!device) { - return SDL_InvalidParamError("devid"); + if (SDL_AtomicGet(&device->thread_alive)) { + SDL_AtomicSet(&device->shutdown, 1); + if (device->thread != NULL) { + SDL_WaitThread(device->thread, NULL); + device->thread = NULL; + } + SDL_AtomicSet(&device->thread_alive, 0); } - current_audio.impl.LockDevice(device); - return 0; -} -void SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) -{ - /* Obtain a lock on the mixing buffers */ - SDL_AudioDevice *device = get_audio_device(devid); - if (!device) { - return; + if (device->is_opened) { + current_audio.impl.CloseDevice(device); // if ProvidesOwnCallbackThread, this must join on any existing device thread before returning! + device->is_opened = SDL_FALSE; + device->hidden = NULL; // just in case. } - current_audio.impl.UnlockDevice(device); + + if (device->work_buffer) { + SDL_aligned_free(device->work_buffer); + device->work_buffer = NULL; + } + + SDL_memcpy(&device->spec, &device->default_spec, sizeof (SDL_AudioSpec)); + device->sample_frames = 0; + device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format); + SDL_AtomicSet(&device->shutdown, 0); // ready to go again. } void SDL_CloseAudioDevice(SDL_AudioDeviceID devid) { - SDL_AudioDevice *device = get_audio_device(devid); - if (!device) { - return; + SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); + if (logdev) { // if NULL, maybe it was already lost? + SDL_AudioDevice *device = logdev->physical_device; + DestroyLogicalAudioDevice(logdev); + + if (device->logical_devices == NULL) { // no more logical devices? Close the physical device, too. + // !!! FIXME: we _need_ to release this lock, but doing so can cause a race condition if someone opens a device while we're closing it. + SDL_UnlockMutex(device->lock); // can't hold the lock or the audio thread will deadlock while we WaitThread it. + ClosePhysicalAudioDevice(device); + } else { + SDL_UnlockMutex(device->lock); // we're set, let everything go again. + } } - close_audio_device(device); } -void SDL_QuitAudio(void) + +static SDL_AudioFormat ParseAudioFormatString(const char *string) { - SDL_AudioDeviceID i; + if (string) { + #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) { return SDL_AUDIO_##x; } + CHECK_FMT_STRING(U8); + CHECK_FMT_STRING(S8); + CHECK_FMT_STRING(S16LSB); + CHECK_FMT_STRING(S16MSB); + CHECK_FMT_STRING(S16); + CHECK_FMT_STRING(S32LSB); + CHECK_FMT_STRING(S32MSB); + CHECK_FMT_STRING(S32SYS); + CHECK_FMT_STRING(S32); + CHECK_FMT_STRING(F32LSB); + CHECK_FMT_STRING(F32MSB); + CHECK_FMT_STRING(F32SYS); + CHECK_FMT_STRING(F32); + #undef CHECK_FMT_STRING + } + return 0; +} - if (!current_audio.name) { /* not initialized?! */ - return; +static void PrepareAudioFormat(SDL_bool iscapture, SDL_AudioSpec *spec) +{ + if (spec->freq == 0) { + spec->freq = iscapture ? DEFAULT_AUDIO_CAPTURE_FREQUENCY : DEFAULT_AUDIO_OUTPUT_FREQUENCY; + + const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); // !!! FIXME: should be a hint? + if (env != NULL) { + const int val = SDL_atoi(env); + if (val > 0) { + spec->freq = val; + } + } } - for (i = 0; i < SDL_arraysize(open_devices); i++) { - close_audio_device(open_devices[i]); + if (spec->channels == 0) { + spec->channels = iscapture ? DEFAULT_AUDIO_CAPTURE_CHANNELS : DEFAULT_AUDIO_OUTPUT_CHANNELS;; + const char *env = SDL_getenv("SDL_AUDIO_CHANNELS"); + if (env != NULL) { + const int val = SDL_atoi(env); + if (val > 0) { + spec->channels = val; + } + } } - free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); - free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); + if (spec->format == 0) { + const SDL_AudioFormat val = ParseAudioFormatString(SDL_getenv("SDL_AUDIO_FORMAT")); + spec->format = (val != 0) ? val : (iscapture ? DEFAULT_AUDIO_CAPTURE_FORMAT : DEFAULT_AUDIO_OUTPUT_FORMAT); + } +} - /* Free the driver data */ - current_audio.impl.Deinitialize(); +static int GetDefaultSampleFramesFromFreq(int freq) +{ + return SDL_powerof2((freq / 1000) * 46); // Pick the closest power-of-two to ~46 ms at desired frequency +} - SDL_DestroyMutex(current_audio.detectionLock); +void SDL_UpdatedAudioDeviceFormat(SDL_AudioDevice *device) +{ + device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format); + device->buffer_size = device->sample_frames * (SDL_AUDIO_BITSIZE(device->spec.format) / 8) * device->spec.channels; +} - SDL_zero(current_audio); - SDL_zeroa(open_devices); +char *SDL_GetAudioThreadName(SDL_AudioDevice *device, char *buf, size_t buflen) +{ + (void)SDL_snprintf(buf, buflen, "SDLAudio%c%d", (device->iscapture) ? 'C' : 'P', (int) device->instance_id); + return buf; +} + + +// this expects the device lock to be held. +static int OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec *inspec) +{ + SDL_assert(!device->is_opened); + SDL_assert(device->logical_devices == NULL); + + // Just pretend to open a zombie device. It can still collect logical devices on the assumption they will all migrate when the default device is officially changed. + if (SDL_AtomicGet(&device->zombie)) { + return 0; // Braaaaaaaaains. + } + + SDL_AudioSpec spec; + SDL_memcpy(&spec, inspec ? inspec : &device->default_spec, sizeof (SDL_AudioSpec)); + PrepareAudioFormat(device->iscapture, &spec); + + /* We allow the device format to change if it's better than the current settings (by various definitions of "better"). This prevents + something low quality, like an old game using S8/8000Hz audio, from ruining a music thing playing at CD quality that tries to open later. + (or some VoIP library that opens for mono output ruining your surround-sound game because it got there first). + These are just requests! The backend may change any of these values during OpenDevice method! */ + device->spec.format = (SDL_AUDIO_BITSIZE(device->default_spec.format) >= SDL_AUDIO_BITSIZE(spec.format)) ? device->default_spec.format : spec.format; + device->spec.freq = SDL_max(device->default_spec.freq, spec.freq); + device->spec.channels = SDL_max(device->default_spec.channels, spec.channels); + device->sample_frames = GetDefaultSampleFramesFromFreq(device->spec.freq); + SDL_UpdatedAudioDeviceFormat(device); // start this off sane. + + device->is_opened = SDL_TRUE; // mark this true even if impl.OpenDevice fails, so we know to clean up. + if (current_audio.impl.OpenDevice(device) < 0) { + ClosePhysicalAudioDevice(device); // clean up anything the backend left half-initialized. + return -1; + } + + SDL_UpdatedAudioDeviceFormat(device); // in case the backend changed things and forgot to call this. + + // Allocate a scratch audio buffer + device->work_buffer = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->buffer_size); + if (device->work_buffer == NULL) { + ClosePhysicalAudioDevice(device); + return SDL_OutOfMemory(); + } + + // Start the audio thread if necessary + SDL_AtomicSet(&device->thread_alive, 1); + if (!current_audio.impl.ProvidesOwnCallbackThread) { + const size_t stacksize = 0; // just take the system default, since audio streams might have callbacks. + char threadname[64]; + SDL_GetAudioThreadName(device, threadname, sizeof (threadname)); + device->thread = SDL_CreateThreadInternal(device->iscapture ? CaptureAudioThread : OutputAudioThread, threadname, stacksize, device); + + if (device->thread == NULL) { + SDL_AtomicSet(&device->thread_alive, 0); + ClosePhysicalAudioDevice(device); + return SDL_SetError("Couldn't create audio thread"); + } + } + + return 0; +} + +SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec) +{ + if (!SDL_GetCurrentAudioDriver()) { + SDL_SetError("Audio subsystem is not initialized"); + return 0; + } + + SDL_bool is_default = SDL_FALSE; + if (devid == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) { + devid = current_audio.default_output_device_id; + is_default = SDL_TRUE; + } else if (devid == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) { + devid = current_audio.default_capture_device_id; + is_default = SDL_TRUE; + } + + if ((devid == 0) && is_default) { + SDL_SetError("No default audio device available"); + return 0; + } + + // this will let you use a logical device to make a new logical device on the parent physical device. Could be useful? + SDL_AudioDevice *device = NULL; + const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE; + if (!islogical) { + device = ObtainPhysicalAudioDevice(devid); + } else { + SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); // this locks the physical device, too. + if (logdev) { + is_default = logdev->is_default; // was the original logical device meant to be a default? Make this one, too. + device = logdev->physical_device; + } + } + + SDL_AudioDeviceID retval = 0; + + if (device) { + SDL_LogicalAudioDevice *logdev = NULL; + if (!is_default && SDL_AtomicGet(&device->zombie)) { + // uhoh, this device is undead, and just waiting for a new default device to be declared so it can hand off to it. Refuse explicit opens. + SDL_SetError("Device was already lost and can't accept new opens"); + } else if ((logdev = (SDL_LogicalAudioDevice *) SDL_calloc(1, sizeof (SDL_LogicalAudioDevice))) == NULL) { + SDL_OutOfMemory(); + } else if (!device->is_opened && OpenPhysicalAudioDevice(device, spec) == -1) { // first thing using this physical device? Open at the OS level... + SDL_free(logdev); + } else { + SDL_AtomicSet(&logdev->paused, 0); + retval = logdev->instance_id = assign_audio_device_instance_id(device->iscapture, /*islogical=*/SDL_TRUE); + logdev->physical_device = device; + logdev->is_default = is_default; + logdev->next = device->logical_devices; + if (device->logical_devices) { + device->logical_devices->prev = logdev; + } + device->logical_devices = logdev; + } + SDL_UnlockMutex(device->lock); + } + + return retval; +} + +static int SetLogicalAudioDevicePauseState(SDL_AudioDeviceID devid, int value) +{ + SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); + if (!logdev) { + return -1; // ObtainLogicalAudioDevice will have set an error. + } + SDL_AtomicSet(&logdev->paused, value); + SDL_UnlockMutex(logdev->physical_device->lock); + return 0; +} + +int SDL_PauseAudioDevice(SDL_AudioDeviceID devid) +{ + return SetLogicalAudioDevicePauseState(devid, 1); +} + +int SDLCALL SDL_ResumeAudioDevice(SDL_AudioDeviceID devid) +{ + return SetLogicalAudioDevicePauseState(devid, 0); +} + +SDL_bool SDL_IsAudioDevicePaused(SDL_AudioDeviceID devid) +{ + SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); + SDL_bool retval = SDL_FALSE; + if (logdev) { + if (SDL_AtomicGet(&logdev->paused)) { + retval = SDL_TRUE; + } + SDL_UnlockMutex(logdev->physical_device->lock); + } + return retval; +} + + +int SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int num_streams) +{ + const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE; + SDL_LogicalAudioDevice *logdev; + + if (num_streams == 0) { + return 0; // nothing to do + } else if (num_streams < 0) { + return SDL_InvalidParamError("num_streams"); + } else if (streams == NULL) { + return SDL_InvalidParamError("streams"); + } else if (!islogical) { + return SDL_SetError("Audio streams are bound to device ids from SDL_OpenAudioDevice, not raw physical devices"); + } else if ((logdev = ObtainLogicalAudioDevice(devid)) == NULL) { + return -1; // ObtainLogicalAudioDevice set the error message. + } + + // make sure start of list is sane. + SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL)); + + SDL_AudioDevice *device = logdev->physical_device; + int retval = 0; + + // lock all the streams upfront, so we can verify they aren't bound elsewhere and add them all in one block, as this is intended to add everything or nothing. + for (int i = 0; i < num_streams; i++) { + SDL_AudioStream *stream = streams[i]; + if (stream == NULL) { + retval = SDL_SetError("Stream #%d is NULL", i); + } else { + SDL_LockMutex(stream->lock); + SDL_assert((stream->bound_device == NULL) == ((stream->prev_binding == NULL) || (stream->next_binding == NULL))); + if (stream->bound_device) { + retval = SDL_SetError("Stream #%d is already bound to a device", i); + } + } + + if (retval != 0) { + int j; + for (j = 0; j <= i; j++) { + SDL_UnlockMutex(streams[j]->lock); + } + break; + } + } + + if (retval == 0) { + // Now that everything is verified, chain everything together. + const SDL_bool iscapture = device->iscapture; + for (int i = 0; i < num_streams; i++) { + SDL_AudioStream *stream = streams[i]; + SDL_AudioSpec src_spec, dst_spec; + + // set the proper end of the stream to the device's format. + SDL_GetAudioStreamFormat(stream, &src_spec, &dst_spec); + if (iscapture) { + SDL_SetAudioStreamFormat(stream, &device->spec, &dst_spec); + } else { + SDL_SetAudioStreamFormat(stream, &src_spec, &device->spec); + } + + stream->bound_device = logdev; + stream->prev_binding = NULL; + stream->next_binding = logdev->bound_streams; + if (logdev->bound_streams) { + logdev->bound_streams->prev_binding = stream; + } + logdev->bound_streams = stream; + + SDL_UnlockMutex(stream->lock); + } + } + + SDL_UnlockMutex(device->lock); + + return retval; +} + +int SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream) +{ + return SDL_BindAudioStreams(devid, &stream, 1); +} + +void SDL_UnbindAudioStreams(SDL_AudioStream **streams, int num_streams) +{ + /* to prevent deadlock when holding both locks, we _must_ lock the device first, and the stream second, as that is the order the audio thread will do it. + But this means we have an unlikely, pathological case where a stream could change its binding between when we lookup its bound device and when we lock everything, + so we double-check here. */ + for (int i = 0; i < num_streams; i++) { + SDL_AudioStream *stream = streams[i]; + if (!stream) { + continue; // nothing to do, it's a NULL stream. + } + + while (SDL_TRUE) { + SDL_LockMutex(stream->lock); // lock to check this and then release it, in case the device isn't locked yet. + SDL_LogicalAudioDevice *bounddev = stream->bound_device; + SDL_UnlockMutex(stream->lock); + + // lock in correct order. + if (bounddev) { + SDL_LockMutex(bounddev->physical_device->lock); // this requires recursive mutexes, since we're likely locking the same device multiple times. + } + SDL_LockMutex(stream->lock); + + if (bounddev == stream->bound_device) { + break; // the binding didn't change in the small window where it could, so we're good. + } else { + SDL_UnlockMutex(stream->lock); // it changed bindings! Try again. + if (bounddev) { + SDL_UnlockMutex(bounddev->physical_device->lock); + } + } + } + } + + // everything is locked, start unbinding streams. + for (int i = 0; i < num_streams; i++) { + SDL_AudioStream *stream = streams[i]; + if (stream && stream->bound_device) { + if (stream->bound_device->bound_streams == stream) { + SDL_assert(stream->prev_binding == NULL); + stream->bound_device->bound_streams = stream->next_binding; + } + if (stream->prev_binding) { + stream->prev_binding->next_binding = stream->next_binding; + } + if (stream->next_binding) { + stream->next_binding->prev_binding = stream->prev_binding; + } + stream->prev_binding = stream->next_binding = NULL; + } + } + + // Finalize and unlock everything. + for (int i = 0; i < num_streams; i++) { + SDL_AudioStream *stream = streams[i]; + if (stream && stream->bound_device) { + SDL_LogicalAudioDevice *logdev = stream->bound_device; + stream->bound_device = NULL; + SDL_UnlockMutex(stream->lock); + if (logdev) { + SDL_UnlockMutex(logdev->physical_device->lock); + } + } + } +} + +void SDL_UnbindAudioStream(SDL_AudioStream *stream) +{ + SDL_UnbindAudioStreams(&stream, 1); +} + +SDL_AudioDeviceID SDL_GetAudioStreamBinding(SDL_AudioStream *stream) +{ + SDL_AudioDeviceID retval = 0; + if (stream) { + SDL_LockMutex(stream->lock); + if (stream->bound_device) { + retval = stream->bound_device->instance_id; + } + SDL_UnlockMutex(stream->lock); + } + return retval; +} + +SDL_AudioStream *SDL_CreateAndBindAudioStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec) +{ + const SDL_bool islogical = (devid & (1<<1)) ? SDL_FALSE : SDL_TRUE; + if (!islogical) { + SDL_SetError("Audio streams are bound to device ids from SDL_OpenAudioDevice, not raw physical devices"); + return NULL; + } + + SDL_AudioStream *stream = NULL; + SDL_LogicalAudioDevice *logdev = ObtainLogicalAudioDevice(devid); + if (logdev) { + SDL_AudioDevice *device = logdev->physical_device; + if (device->iscapture) { + stream = SDL_CreateAudioStream(&device->spec, spec); + } else { + stream = SDL_CreateAudioStream(spec, &device->spec); + } + + if (stream) { + if (SDL_BindAudioStream(devid, stream) == -1) { + SDL_DestroyAudioStream(stream); + stream = NULL; + } + } + SDL_UnlockMutex(device->lock); + } + return stream; } #define NUM_FORMATS 8 @@ -1506,78 +1549,168 @@ static const SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS + 1] = { const SDL_AudioFormat *SDL_ClosestAudioFormats(SDL_AudioFormat format) { - int i; - for (i = 0; i < NUM_FORMATS; i++) { + for (int i = 0; i < NUM_FORMATS; i++) { if (format_list[i][0] == format) { return &format_list[i][0]; } } - return &format_list[0][NUM_FORMATS]; /* not found; return what looks like a list with only a zero in it. */ + return &format_list[0][NUM_FORMATS]; // not found; return what looks like a list with only a zero in it. } -Uint8 SDL_GetSilenceValueForFormat(const SDL_AudioFormat format) +int SDL_GetSilenceValueForFormat(SDL_AudioFormat format) { return (format == SDL_AUDIO_U8) ? 0x80 : 0x00; } -void SDL_CalculateAudioSpec(SDL_AudioSpec *spec) +// called internally by backends when the system default device changes. +void SDL_DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device) { - spec->silence = SDL_GetSilenceValueForFormat(spec->format); - spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8; - spec->size *= spec->channels; - spec->size *= spec->samples; + if (new_default_device == NULL) { // !!! FIXME: what should we do in this case? Maybe all devices are lost, so there _isn't_ a default? + return; // uhoh. + } + + const SDL_bool iscapture = new_default_device->iscapture; + const SDL_AudioDeviceID current_devid = iscapture ? current_audio.default_capture_device_id : current_audio.default_output_device_id; + + if (new_default_device->instance_id == current_devid) { + return; // this is already the default. + } + + SDL_LockMutex(new_default_device->lock); + + SDL_AudioDevice *current_default_device = ObtainPhysicalAudioDevice(current_devid); + + /* change the official default ID over while we have locks on both devices, so if something raced to open the default during + this, it either gets the new device or is ready on the old and can be migrated. */ + if (iscapture) { + current_audio.default_capture_device_id = new_default_device->instance_id; + } else { + current_audio.default_output_device_id = new_default_device->instance_id; + } + + if (current_default_device) { + // migrate any logical devices that were opened as a default to the new physical device... + + SDL_assert(current_default_device->iscapture == iscapture); + + // See if we have to open the new physical device, and if so, find the best audiospec for it. + SDL_AudioSpec spec; + SDL_bool needs_migration = SDL_FALSE; + SDL_zero(spec); + for (SDL_LogicalAudioDevice *logdev = current_default_device->logical_devices; logdev != NULL; logdev = logdev->next) { + if (logdev->is_default) { + needs_migration = SDL_TRUE; + for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) { + const SDL_AudioSpec *streamspec = iscapture ? &stream->dst_spec : &stream->src_spec; + if (SDL_AUDIO_BITSIZE(streamspec->format) > SDL_AUDIO_BITSIZE(spec.format)) { + spec.format = streamspec->format; + } + if (streamspec->channels > spec.channels) { + spec.channels = streamspec->channels; + } + if (streamspec->freq > spec.freq) { + spec.freq = streamspec->freq; + } + } + } + } + + if (needs_migration) { + if (new_default_device->logical_devices == NULL) { // New default physical device not been opened yet? Open at the OS level... + if (OpenPhysicalAudioDevice(new_default_device, &spec) == -1) { + needs_migration = SDL_FALSE; // uhoh, just leave everything on the old default, nothing to be done. + } + } + } + + if (needs_migration) { + SDL_LogicalAudioDevice *next = NULL; + for (SDL_LogicalAudioDevice *logdev = current_default_device->logical_devices; logdev != NULL; logdev = next) { + next = logdev->next; + + if (!logdev->is_default) { + continue; // not opened as a default, leave it on the current physical device. + } + + // make sure all our streams are targeting the new device's format. + for (SDL_AudioStream *stream = logdev->bound_streams; stream != NULL; stream = stream->next_binding) { + SDL_SetAudioStreamFormat(stream, iscapture ? &new_default_device->spec : NULL, iscapture ? NULL : &new_default_device->spec); + } + + // now migrate the logical device. + if (logdev->next) { + logdev->next->prev = logdev->prev; + } + if (logdev->prev) { + logdev->prev->next = logdev->next; + } + if (current_default_device->logical_devices == logdev) { + current_default_device->logical_devices = logdev->next; + } + + logdev->physical_device = new_default_device; + logdev->prev = NULL; + logdev->next = new_default_device->logical_devices; + new_default_device->logical_devices = logdev; + } + + if (current_default_device->logical_devices == NULL) { // nothing left on the current physical device, close it. + // !!! FIXME: we _need_ to release this lock, but doing so can cause a race condition if someone opens a device while we're closing it. + SDL_UnlockMutex(current_default_device->lock); // can't hold the lock or the audio thread will deadlock while we WaitThread it. + ClosePhysicalAudioDevice(current_default_device); + SDL_LockMutex(current_default_device->lock); // we're about to unlock this again, so make sure the locks match. + } + } + + SDL_UnlockMutex(current_default_device->lock); + } + + SDL_UnlockMutex(new_default_device->lock); + + // was current device already dead and just kept around to migrate to a new default device? Now we can kill it. Aim for the brain. + if (current_default_device && SDL_AtomicGet(¤t_default_device->zombie)) { + SDL_AudioDeviceDisconnected(current_default_device); // Call again, now that we're not the default; this will remove from device list, send removal events, and destroy the SDL_AudioDevice. + } } -/* !!! FIXME: move this to SDL_audiocvt.c */ -int SDL_ConvertAudioSamples(SDL_AudioFormat src_format, Uint8 src_channels, int src_rate, const Uint8 *src_data, int src_len, - SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate, Uint8 **dst_data, int *dst_len) +int SDL_AudioDeviceFormatChangedAlreadyLocked(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames) { - int ret = -1; - SDL_AudioStream *stream = NULL; - Uint8 *dst = NULL; - int dstlen = 0; + SDL_bool kill_device = SDL_FALSE; - if (dst_data) { - *dst_data = NULL; - } + const int orig_buffer_size = device->buffer_size; + const SDL_bool iscapture = device->iscapture; - if (dst_len) { - *dst_len = 0; - } - - if (src_data == NULL) { - return SDL_InvalidParamError("src_data"); - } else if (src_len < 0) { - return SDL_InvalidParamError("src_len"); - } else if (dst_data == NULL) { - return SDL_InvalidParamError("dst_data"); - } else if (dst_len == NULL) { - return SDL_InvalidParamError("dst_len"); - } - - stream = SDL_CreateAudioStream(src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); - if (stream != NULL) { - if ((SDL_PutAudioStreamData(stream, src_data, src_len) == 0) && (SDL_FlushAudioStream(stream) == 0)) { - dstlen = SDL_GetAudioStreamAvailable(stream); - if (dstlen >= 0) { - dst = (Uint8 *)SDL_malloc(dstlen); - if (!dst) { - SDL_OutOfMemory(); - } else { - ret = (SDL_GetAudioStreamData(stream, dst, dstlen) >= 0) ? 0 : -1; + if ((device->spec.format != newspec->format) || (device->spec.channels != newspec->channels) || (device->spec.freq != newspec->freq)) { + SDL_memcpy(&device->spec, newspec, sizeof (*newspec)); + for (SDL_LogicalAudioDevice *logdev = device->logical_devices; !kill_device && (logdev != NULL); logdev = logdev->next) { + for (SDL_AudioStream *stream = logdev->bound_streams; !kill_device && (stream != NULL); stream = stream->next_binding) { + if (SDL_SetAudioStreamFormat(stream, iscapture ? &device->spec : NULL, iscapture ? NULL : &device->spec) == -1) { + kill_device = SDL_TRUE; } } } } - if (ret == -1) { - SDL_free(dst); - } else { - *dst_data = dst; - *dst_len = dstlen; + if (!kill_device) { + device->sample_frames = new_sample_frames; + SDL_UpdatedAudioDeviceFormat(device); + if (device->work_buffer && (device->buffer_size > orig_buffer_size)) { + SDL_aligned_free(device->work_buffer); + device->work_buffer = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), device->buffer_size); + if (!device->work_buffer) { + kill_device = SDL_TRUE; + } + } } - SDL_DestroyAudioStream(stream); - return ret; + return kill_device ? -1 : 0; +} + +int SDL_AudioDeviceFormatChanged(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames) +{ + SDL_LockMutex(device->lock); + const int retval = SDL_AudioDeviceFormatChangedAlreadyLocked(device, newspec, new_sample_frames); + SDL_UnlockMutex(device->lock); + return retval; } diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h index d69184a5..7b00ceac 100644 --- a/src/audio/SDL_audio_c.h +++ b/src/audio/SDL_audio_c.h @@ -22,59 +22,8 @@ #ifndef SDL_audio_c_h_ #define SDL_audio_c_h_ -#include "SDL_internal.h" +/* !!! FIXME: remove this header and have things just include SDL_sysaudio.h directly. */ -#define DEBUG_AUDIOSTREAM 0 -#define DEBUG_AUDIO_CONVERT 0 - -#if DEBUG_AUDIO_CONVERT -#define LOG_DEBUG_AUDIO_CONVERT(from, to) SDL_Log("SDL_AUDIO_CONVERT: Converting %s to %s.\n", from, to); -#else -#define LOG_DEBUG_AUDIO_CONVERT(from, to) -#endif - -/* Functions and variables exported from SDL_audio.c for SDL_sysaudio.c */ - -/* Function to get a list of audio formats, ordered most similar to `format` to least, 0-terminated. Don't free results. */ -const SDL_AudioFormat *SDL_ClosestAudioFormats(SDL_AudioFormat format); - -/* Function to calculate the size and silence for a SDL_AudioSpec */ -extern Uint8 SDL_GetSilenceValueForFormat(const SDL_AudioFormat format); -extern void SDL_CalculateAudioSpec(SDL_AudioSpec *spec); - -/* Must be called at least once before using converters (SDL_CreateAudioStream will call it). */ -extern void SDL_ChooseAudioConverters(void); - -/* These pointers get set during SDL_ChooseAudioConverters() to various SIMD implementations. */ -extern void (*SDL_Convert_S8_to_F32)(float *dst, const Sint8 *src, int num_samples); -extern void (*SDL_Convert_U8_to_F32)(float *dst, const Uint8 *src, int num_samples); -extern void (*SDL_Convert_S16_to_F32)(float *dst, const Sint16 *src, int num_samples); -extern void (*SDL_Convert_S32_to_F32)(float *dst, const Sint32 *src, int num_samples); -extern void (*SDL_Convert_F32_to_S8)(Sint8 *dst, const float *src, int num_samples); -extern void (*SDL_Convert_F32_to_U8)(Uint8 *dst, const float *src, int num_samples); -extern void (*SDL_Convert_F32_to_S16)(Sint16 *dst, const float *src, int num_samples); -extern void (*SDL_Convert_F32_to_S32)(Sint32 *dst, const float *src, int num_samples); - -/** - * 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. - */ -extern int SDL_InitAudio(const char *driver_name); - -/** - * Use this function to shut down audio if you initialized it with SDL_InitAudio(). - * - * 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(). - */ -extern void SDL_QuitAudio(void); +#include "SDL_sysaudio.h" #endif /* SDL_audio_c_h_ */ diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 299dfd10..d16c1c33 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -20,7 +20,7 @@ */ #include "SDL_internal.h" -/* Functions for audio drivers to perform runtime conversion of audio format */ +// Functions for audio drivers to perform runtime conversion of audio format #include "SDL_audio_c.h" @@ -64,7 +64,7 @@ static int GetHistoryBufferSampleFrames(const Sint32 required_resampler_frames) return (int) SDL_max(required_resampler_frames, 5000); } -/* lpadding and rpadding are expected to be buffers of (GetResamplePadding(inrate, outrate) * chans * sizeof (float)) bytes. */ +// lpadding and rpadding are expected to be buffers of (GetResamplePadding(inrate, outrate) * chans * sizeof (float)) bytes. static void ResampleAudio(const int chans, const int inrate, const int outrate, const float *lpadding, const float *rpadding, const float *inbuf, const int inframes, @@ -81,7 +81,11 @@ static void ResampleAudio(const int chans, const int inrate, const int outrate, int i, j, chan; for (i = 0; i < outframes; i++) { - const int srcindex = (int)((Sint64)i * inrate / outrate); + int srcindex = (int)((Sint64)i * inrate / outrate); + if (srcindex >= inframes) { // !!! FIXME: can we clamp this without an if statement on each iteration? + srcindex = inframes - 1; + } + /* Calculating the following way avoids subtraction or modulo of large * floats which have low result precision. * interpolation1 @@ -97,7 +101,7 @@ static void ResampleAudio(const int chans, const int inrate, const int 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. */ + // 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; @@ -106,11 +110,11 @@ static void ResampleAudio(const int chans, const int inrate, const int outrate, outsample += (float) (insample * (ResamplerFilter[filt_ind] + (interpolation1 * ResamplerFilterDifference[filt_ind]))); } - /* Do the right wing! */ + // 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. */ + // !!! 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]))); } @@ -154,25 +158,25 @@ static void ResampleAudio(const int chans, const int inrate, const int outrate, */ #ifdef SDL_SSE3_INTRINSICS -/* Convert from stereo to mono. Average left and right. */ +// Convert from stereo to mono. Average left and right. static void SDL_TARGETING("sse3") SDL_ConvertStereoToMono_SSE3(float *dst, const float *src, int num_frames) { + LOG_DEBUG_AUDIO_CONVERT("stereo", "mono (using SSE3)"); + const __m128 divby2 = _mm_set1_ps(0.5f); int i = num_frames; - LOG_DEBUG_AUDIO_CONVERT("stereo", "mono (using SSE3)"); - /* 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 */ + 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. */ + // Finish off any leftovers with scalar operations. while (i) { *dst = (src[0] + src[1]) * 0.5f; dst++; @@ -183,34 +187,33 @@ static void SDL_TARGETING("sse3") SDL_ConvertStereoToMono_SSE3(float *dst, const #endif #ifdef SDL_SSE_INTRINSICS -/* Convert from mono to stereo. Duplicate to stereo left and right. */ +// Convert from mono to stereo. Duplicate to stereo left and right. static void SDL_TARGETING("sse") SDL_ConvertMonoToStereo_SSE(float *dst, const float *src, int num_frames) { - int i = num_frames; + LOG_DEBUG_AUDIO_CONVERT("mono", "stereo (using SSE)"); - /* convert backwards, since output is growing in-place. */ + // convert backwards, since output is growing in-place. src += (num_frames-4) * 1; dst += (num_frames-4) * 2; - LOG_DEBUG_AUDIO_CONVERT("mono", "stereo (using SSE)"); - /* 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 */ + // convert backwards, since output is growing in-place. + int i = num_frames; + 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. */ + // 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. */ + 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; @@ -221,14 +224,12 @@ static void SDL_TARGETING("sse") SDL_ConvertMonoToStereo_SSE(float *dst, const f } #endif -/* Include the autogenerated channel converters... */ +// Include the autogenerated channel converters... #include "SDL_audio_channel_converters.h" static void AudioConvertByteswap(void *dst, const void *src, int num_samples, int bitsize) { - int i; - #if DEBUG_AUDIO_CONVERT SDL_Log("SDL_AUDIO_CONVERT: Converting %d-bit byte order", bitsize); #endif @@ -238,7 +239,7 @@ static void AudioConvertByteswap(void *dst, const void *src, int num_samples, in case b: { \ const Uint##b *tsrc = (const Uint##b *)src; \ Uint##b *tdst = (Uint##b *)dst; \ - for (i = 0; i < num_samples; i++) { \ + for (int i = 0; i < num_samples; i++) { \ tdst[i] = SDL_Swap##b(tsrc[i]); \ } \ break; \ @@ -258,28 +259,28 @@ static void AudioConvertByteswap(void *dst, const void *src, int num_samples, in static void AudioConvertToFloat(float *dst, const void *src, int num_samples, SDL_AudioFormat src_fmt) { - SDL_assert( (SDL_AUDIO_BITSIZE(src_fmt) <= 8) || ((SDL_AUDIO_ISBIGENDIAN(src_fmt) == 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) ); /* This only deals with native byte order. */ + SDL_assert( (SDL_AUDIO_BITSIZE(src_fmt) <= 8) || ((SDL_AUDIO_ISBIGENDIAN(src_fmt) == 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) ); // This only deals with native byte order. switch (src_fmt & ~SDL_AUDIO_MASK_ENDIAN) { case SDL_AUDIO_S8: SDL_Convert_S8_to_F32(dst, (const Sint8 *) src, num_samples); break; case SDL_AUDIO_U8: SDL_Convert_U8_to_F32(dst, (const Uint8 *) src, num_samples); break; case SDL_AUDIO_S16: SDL_Convert_S16_to_F32(dst, (const Sint16 *) src, num_samples); break; case SDL_AUDIO_S32: SDL_Convert_S32_to_F32(dst, (const Sint32 *) src, num_samples); break; - case SDL_AUDIO_F32: if (dst != src) { SDL_memcpy(dst, src, num_samples * sizeof (float)); } break; /* oh well, just pass it through. */ + case SDL_AUDIO_F32: if (dst != src) { SDL_memcpy(dst, src, num_samples * sizeof (float)); } break; // oh well, just pass it through. default: SDL_assert(!"Unexpected audio format!"); break; } } static void AudioConvertFromFloat(void *dst, const float *src, int num_samples, SDL_AudioFormat dst_fmt) { - SDL_assert( (SDL_AUDIO_BITSIZE(dst_fmt) <= 8) || ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) == 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) ); /* This only deals with native byte order. */ + SDL_assert( (SDL_AUDIO_BITSIZE(dst_fmt) <= 8) || ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) == 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) ); // This only deals with native byte order. switch (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN) { case SDL_AUDIO_S8: SDL_Convert_F32_to_S8((Sint8 *) dst, src, num_samples); break; case SDL_AUDIO_U8: SDL_Convert_F32_to_U8((Uint8 *) dst, src, num_samples); break; case SDL_AUDIO_S16: SDL_Convert_F32_to_S16((Sint16 *) dst, src, num_samples); break; case SDL_AUDIO_S32: SDL_Convert_F32_to_S32((Sint32 *) dst, src, num_samples); break; - case SDL_AUDIO_F32: if (dst != src) { SDL_memcpy(dst, src, num_samples * sizeof (float)); } break; /* oh well, just pass it through. */ + case SDL_AUDIO_F32: if (dst != src) { SDL_memcpy(dst, src, num_samples * sizeof (float)); } break; // oh well, just pass it through. default: SDL_assert(!"Unexpected audio format!"); break; } } @@ -295,13 +296,13 @@ static SDL_bool SDL_IsSupportedAudioFormat(const SDL_AudioFormat fmt) case SDL_AUDIO_S32MSB: case SDL_AUDIO_F32LSB: case SDL_AUDIO_F32MSB: - return SDL_TRUE; /* supported. */ + return SDL_TRUE; // supported. default: break; } - return SDL_FALSE; /* unsupported. */ + return SDL_FALSE; // unsupported. } static SDL_bool SDL_IsSupportedChannelCount(const int channels) @@ -320,8 +321,6 @@ static SDL_bool SDL_IsSupportedChannelCount(const int channels) static void ConvertAudio(int num_frames, const void *src, SDL_AudioFormat src_format, int src_channels, void *dst, SDL_AudioFormat dst_format, int dst_channels) { - const int dst_bitsize = (int) SDL_AUDIO_BITSIZE(dst_format); - const int src_bitsize = (int) SDL_AUDIO_BITSIZE(src_format); SDL_assert(src != NULL); SDL_assert(dst != NULL); SDL_assert(SDL_IsSupportedAudioFormat(src_format)); @@ -329,13 +328,16 @@ static void ConvertAudio(int num_frames, const void *src, SDL_AudioFormat src_fo SDL_assert(SDL_IsSupportedChannelCount(src_channels)); SDL_assert(SDL_IsSupportedChannelCount(dst_channels)); + if (!num_frames) { + return; // no data to convert, quit. + } + #if DEBUG_AUDIO_CONVERT SDL_Log("SDL_AUDIO_CONVERT: Convert format %04x->%04x, channels %u->%u", src_format, dst_format, src_channels, dst_channels); #endif - if (!num_frames) { - return; /* no data to convert, quit. */ - } + const int dst_bitsize = (int) SDL_AUDIO_BITSIZE(dst_format); + const int src_bitsize = (int) SDL_AUDIO_BITSIZE(src_format); /* Type conversion goes like this now: - byteswap to CPU native format first if necessary. @@ -351,55 +353,55 @@ static void ConvertAudio(int num_frames, const void *src, SDL_AudioFormat src_fo (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. */ + // see if we can skip float conversion entirely. if (src_channels == dst_channels) { if (src_format == dst_format) { - /* nothing to do, we're already in the right format, just copy it over if necessary. */ + // nothing to do, we're already in the right format, just copy it over if necessary. if (src != dst) { SDL_memcpy(dst, src, num_frames * src_channels * (dst_bitsize / 8)); } return; } - /* just a byteswap needed? */ + // just a byteswap needed? if ((src_format & ~SDL_AUDIO_MASK_ENDIAN) == (dst_format & ~SDL_AUDIO_MASK_ENDIAN)) { if (src_bitsize == 8) { if (src != dst) { SDL_memcpy(dst, src, num_frames * src_channels * (dst_bitsize / 8)); } - return; /* nothing to do, it's a 1-byte format. */ + return; // nothing to do, it's a 1-byte format. } AudioConvertByteswap(dst, src, num_frames * src_channels, src_bitsize); - return; /* all done. */ + return; // all done. } } - /* make sure we're in native byte order. */ + // make sure we're in native byte order. if ((SDL_AUDIO_ISBIGENDIAN(src_format) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && (src_bitsize > 8)) { AudioConvertByteswap(dst, src, num_frames * src_channels, src_bitsize); - src = dst; /* we've written to dst, future work will convert in-place. */ + src = dst; // we've written to dst, future work will convert in-place. } - /* get us to float format. */ + // get us to float format. if (!SDL_AUDIO_ISFLOAT(src_format)) { AudioConvertToFloat((float *) dst, src, num_frames * src_channels, src_format); - src = dst; /* we've written to dst, future work will convert in-place. */ + src = dst; // we've written to dst, future work will convert in-place. } - /* Channel conversion */ + // Channel conversion if (src_channels != dst_channels) { SDL_AudioChannelConverter channel_converter; SDL_AudioChannelConverter override = NULL; - /* SDL_IsSupportedChannelCount should have caught these asserts, or we added a new format and forgot to update the table. */ + // SDL_IsSupportedChannelCount 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]; SDL_assert(channel_converter != NULL); - /* swap in some SIMD versions for a few of these. */ + // swap in some SIMD versions for a few of these. if (channel_converter == SDL_ConvertStereoToMono) { #ifdef SDL_SSE3_INTRINSICS if (!override && SDL_HasSSE3()) { override = SDL_ConvertStereoToMono_SSE3; } @@ -414,88 +416,52 @@ static void ConvertAudio(int num_frames, const void *src, SDL_AudioFormat src_fo channel_converter = override; } channel_converter((float *) dst, (float *) src, num_frames); - src = dst; /* we've written to dst, future work will convert in-place. */ + src = dst; // we've written to dst, future work will convert in-place. } - /* Resampling is not done in here. SDL_AudioStream handles that. */ + // Resampling is not done in here. SDL_AudioStream handles that. - /* Move to final data type. */ + // Move to final data type. if (!SDL_AUDIO_ISFLOAT(dst_format)) { AudioConvertFromFloat(dst, (float *) src, num_frames * dst_channels, dst_format); - src = dst; /* we've written to dst, future work will convert in-place. */ + src = dst; // we've written to dst, future work will convert in-place. } - /* make sure we're in final byte order. */ + // make sure we're in final byte order. if ((SDL_AUDIO_ISBIGENDIAN(dst_format) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && (dst_bitsize > 8)) { AudioConvertByteswap(dst, src, num_frames * dst_channels, dst_bitsize); - src = dst; /* we've written to dst, future work will convert in-place. */ + src = dst; // we've written to dst, future work will convert in-place. } - SDL_assert(src == dst); /* if we got here, we _had_ to have done _something_. Otherwise, we should have memcpy'd! */ + SDL_assert(src == dst); // if we got here, we _had_ to have done _something_. Otherwise, we should have memcpy'd! } -struct SDL_AudioStream -{ - SDL_DataQueue *queue; - SDL_Mutex *lock; /* this is just a copy of `queue`'s mutex. We share a lock. */ - - Uint8 *work_buffer; /* used for scratch space during data conversion/resampling. */ - Uint8 *history_buffer; /* history for left padding and future sample rate changes. */ - Uint8 *future_buffer; /* stuff that left the queue for the right padding and will be next read's data. */ - float *left_padding; /* left padding for resampling. */ - float *right_padding; /* right padding for resampling. */ - - SDL_bool flushed; - - size_t work_buffer_allocation; - size_t history_buffer_allocation; - size_t future_buffer_allocation; - size_t resampler_padding_allocation; - - int resampler_padding_frames; - int history_buffer_frames; - int future_buffer_filled_frames; - - int max_sample_frame_size; - - int src_sample_frame_size; - SDL_AudioFormat src_format; - int src_channels; - int src_rate; - - int dst_sample_frame_size; - SDL_AudioFormat dst_format; - int dst_channels; - int dst_rate; - - int pre_resample_channels; - int packetlen; -}; - -static int GetMemsetSilenceValue(const SDL_AudioFormat fmt) -{ - return (fmt == SDL_AUDIO_U8) ? 0x80 : 0x00; -} - -/* figure out the largest thing we might need for ConvertAudio, which might grow data in-place. */ +// figure out the largest thing we might need for ConvertAudio, which might grow data in-place. static int CalculateMaxSampleFrameSize(SDL_AudioFormat src_format, int src_channels, SDL_AudioFormat dst_format, int dst_channels) { const int src_format_size = SDL_AUDIO_BITSIZE(src_format) / 8; const int dst_format_size = SDL_AUDIO_BITSIZE(dst_format) / 8; const int max_app_format_size = SDL_max(src_format_size, dst_format_size); - const int max_format_size = SDL_max(max_app_format_size, sizeof (float)); /* ConvertAudio converts to float internally. */ + const int max_format_size = SDL_max(max_app_format_size, sizeof (float)); // ConvertAudio converts to float internally. const int max_channels = SDL_max(src_channels, dst_channels); return max_format_size * max_channels; } -/* this assumes you're holding the stream's lock (or are still creating the stream). */ -static int SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_format, int src_channels, int src_rate, SDL_AudioFormat dst_format, int dst_channels, int dst_rate) +// this assumes you're holding the stream's lock (or are still creating the stream). +static int SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec) { /* 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!). This is decided in pre_resample_channels. */ + + const SDL_AudioFormat src_format = src_spec->format; + const int src_channels = src_spec->channels; + const int src_rate = src_spec->freq; + const SDL_AudioFormat dst_format = dst_spec->format; + const int dst_channels = dst_spec->channels; + const int dst_rate = dst_spec->freq; const int src_sample_frame_size = (SDL_AUDIO_BITSIZE(src_format) / 8) * src_channels; const int dst_sample_frame_size = (SDL_AUDIO_BITSIZE(dst_format) / 8) * dst_channels; const int max_sample_frame_size = CalculateMaxSampleFrameSize(src_format, src_channels, dst_format, dst_channels); @@ -510,14 +476,15 @@ static int SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_for Uint8 *future_buffer = stream->future_buffer; float *padding; - /* do all the things that can fail upfront, so we can just return an error without changing the stream if anything goes wrong. */ + // do all the things that can fail upfront, so we can just return an error without changing the stream if anything goes wrong. - /* set up for (possibly new) conversions */ + // set up for (possibly new) conversions - /* grow the padding buffers if necessary; these buffer sizes change if sample rate or source channel count is adjusted. */ - /* (we can replace these buffers in `stream` now even if we abandon this function when a later allocation fails, because it's safe for these buffers to be overallocated and their contents don't matter.) */ + /* grow the padding buffers if necessary; these buffer sizes change if sample rate or source channel count is adjusted. + (we can replace these buffers in `stream` now even if we abandon this function when a later allocation fails, because + it's safe for these buffers to be overallocated and their contents don't matter.) */ if (stream->resampler_padding_allocation < resampler_padding_allocation) { - /* left_padding and right_padding are just scratch buffers, so we don't need to preserve existing contents. */ + // left_padding and right_padding are just scratch buffers, so we don't need to preserve existing contents. padding = (float *) SDL_aligned_alloc(SDL_SIMDGetAlignment(), resampler_padding_allocation); if (!padding) { return SDL_OutOfMemory(); @@ -535,7 +502,7 @@ static int SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_for stream->resampler_padding_allocation = resampler_padding_allocation; } - /* grow the history buffer if necessary; often times this won't be, as it already buffers more than immediately necessary in case of a dramatic downsample. */ + // grow the history buffer if necessary; often times this won't be, as it already buffers more than immediately necessary in case of a dramatic downsample. if (stream->history_buffer_allocation < history_buffer_allocation) { history_buffer = (Uint8 *) SDL_aligned_alloc(SDL_SIMDGetAlignment(), history_buffer_allocation); if (!history_buffer) { @@ -543,7 +510,7 @@ static int SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_for } } - /* grow the future buffer if necessary; the buffer size changes if sample rate is adjusted. */ + // grow the future buffer if necessary; the buffer size changes if sample rate is adjusted. if (stream->future_buffer_allocation < future_buffer_allocation) { future_buffer = (Uint8 *) SDL_aligned_alloc(SDL_SIMDGetAlignment(), future_buffer_allocation); if (!future_buffer) { @@ -554,24 +521,24 @@ static int SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_for } } - /* okay, we've done all the things that can fail, now we can change stream state. */ + // okay, we've done all the things that can fail, now we can change stream state. - /* copy to new buffers and/or convert data; ConvertAudio will do a simple memcpy if format matches, and nothing at all if the buffer hasn't changed */ + // copy to new buffers and/or convert data; ConvertAudio will do a simple memcpy if format matches, and nothing at all if the buffer hasn't changed if (stream->future_buffer) { - ConvertAudio(stream->future_buffer_filled_frames, stream->future_buffer, stream->src_format, stream->src_channels, future_buffer, src_format, src_channels); + ConvertAudio(stream->future_buffer_filled_frames, stream->future_buffer, stream->src_spec.format, stream->src_spec.channels, future_buffer, src_format, src_channels); } else if (future_buffer != NULL) { - SDL_memset(future_buffer, GetMemsetSilenceValue(src_format), future_buffer_allocation); + SDL_memset(future_buffer, SDL_GetSilenceValueForFormat(src_format), future_buffer_allocation); } if (stream->history_buffer) { if (history_buffer_frames <= prev_history_buffer_frames) { - ConvertAudio(history_buffer_frames, stream->history_buffer, stream->src_format, stream->src_channels, history_buffer, src_format, src_channels); + ConvertAudio(history_buffer_frames, stream->history_buffer, stream->src_spec.format, stream->src_spec.channels, history_buffer, src_format, src_channels); } else { - ConvertAudio(prev_history_buffer_frames, stream->history_buffer, stream->src_format, stream->src_channels, history_buffer + ((history_buffer_frames - prev_history_buffer_frames) * src_sample_frame_size), src_format, src_channels); - SDL_memset(history_buffer, GetMemsetSilenceValue(src_format), (history_buffer_frames - prev_history_buffer_frames) * src_sample_frame_size); /* silence oldest history samples. */ + ConvertAudio(prev_history_buffer_frames, stream->history_buffer, stream->src_spec.format, stream->src_spec.channels, history_buffer + ((history_buffer_frames - prev_history_buffer_frames) * src_sample_frame_size), src_format, src_channels); + SDL_memset(history_buffer, SDL_GetSilenceValueForFormat(src_format), (history_buffer_frames - prev_history_buffer_frames) * src_sample_frame_size); // silence oldest history samples. } } else if (history_buffer != NULL) { - SDL_memset(history_buffer, GetMemsetSilenceValue(src_format), history_buffer_allocation); + SDL_memset(history_buffer, SDL_GetSilenceValueForFormat(src_format), history_buffer_allocation); } if (future_buffer != stream->future_buffer) { @@ -590,79 +557,80 @@ static int SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_for stream->history_buffer_frames = history_buffer_frames; stream->max_sample_frame_size = max_sample_frame_size; stream->src_sample_frame_size = src_sample_frame_size; - stream->src_format = src_format; - stream->src_channels = src_channels; - stream->src_rate = src_rate; stream->dst_sample_frame_size = dst_sample_frame_size; - stream->dst_format = dst_format; - stream->dst_channels = dst_channels; - stream->dst_rate = dst_rate; stream->pre_resample_channels = pre_resample_channels; + if (src_spec != &stream->src_spec) { + SDL_memcpy(&stream->src_spec, src_spec, sizeof (SDL_AudioSpec)); + } + + if (dst_spec != &stream->dst_spec) { + SDL_memcpy(&stream->dst_spec, dst_spec, sizeof (SDL_AudioSpec)); + } + return 0; } -SDL_AudioStream *SDL_CreateAudioStream(SDL_AudioFormat src_format, - int src_channels, - int src_rate, - SDL_AudioFormat dst_format, - int dst_channels, - int dst_rate) +SDL_AudioStream *SDL_CreateAudioStream(const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec) { - int packetlen = 4096; /* !!! FIXME: good enough for now. */ - SDL_AudioStream *retval; + // !!! FIXME: fail if audio isn't initialized - if (!SDL_IsSupportedChannelCount(src_channels)) { - SDL_InvalidParamError("src_channels"); + if (!src_spec) { + SDL_InvalidParamError("src_spec"); return NULL; - } else if (!SDL_IsSupportedChannelCount(dst_channels)) { - SDL_InvalidParamError("dst_channels"); + } else if (!dst_spec) { + SDL_InvalidParamError("dst_spec"); return NULL; - } else if (src_rate <= 0) { - SDL_InvalidParamError("src_rate"); + } else if (!SDL_IsSupportedChannelCount(src_spec->channels)) { + SDL_InvalidParamError("src_spec->channels"); return NULL; - } else if (dst_rate <= 0) { - SDL_InvalidParamError("dst_rate"); + } else if (!SDL_IsSupportedChannelCount(dst_spec->channels)) { + SDL_InvalidParamError("dst_spec->channels"); return NULL; - } else if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { + } else if (src_spec->freq <= 0) { + SDL_InvalidParamError("src_spec->freq"); + return NULL; + } else if (dst_spec->freq <= 0) { + SDL_InvalidParamError("dst_spec->freq"); + return NULL; + } else if (src_spec->freq >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { SDL_SetError("Source rate is too high"); return NULL; - } else if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { + } else if (dst_spec->freq >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { SDL_SetError("Destination rate is too high"); return NULL; - } else if (!SDL_IsSupportedAudioFormat(src_format)) { - SDL_InvalidParamError("src_format"); + } else if (!SDL_IsSupportedAudioFormat(src_spec->format)) { + SDL_InvalidParamError("src_spec->format"); return NULL; - } else if (!SDL_IsSupportedAudioFormat(dst_format)) { - SDL_InvalidParamError("dst_format"); + } else if (!SDL_IsSupportedAudioFormat(dst_spec->format)) { + SDL_InvalidParamError("dst_spec->format"); return NULL; } - retval = (SDL_AudioStream *)SDL_calloc(1, sizeof(SDL_AudioStream)); + SDL_AudioStream *retval = (SDL_AudioStream *)SDL_calloc(1, sizeof(SDL_AudioStream)); if (retval == NULL) { SDL_OutOfMemory(); return NULL; } + const int packetlen = 4096; // !!! FIXME: good enough for now. retval->queue = SDL_CreateDataQueue(packetlen, (size_t)packetlen * 2); if (!retval->queue) { SDL_DestroyAudioStream(retval); - return NULL; /* SDL_CreateDataQueue should have called SDL_SetError. */ + return NULL; // SDL_CreateDataQueue should have called SDL_SetError. } retval->lock = SDL_GetDataQueueMutex(retval->queue); SDL_assert(retval->lock != NULL); - /* Make sure we've chosen audio conversion functions (SIMD, scalar, etc.) */ - SDL_ChooseAudioConverters(); /* !!! FIXME: let's do this during SDL_Init? */ + // Make sure we've chosen audio conversion functions (SIMD, scalar, etc.) + SDL_ChooseAudioConverters(); // !!! FIXME: let's do this during SDL_Init - 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->src_sample_frame_size = (SDL_AUDIO_BITSIZE(src_spec->format) / 8) * src_spec->channels; retval->packetlen = packetlen; + SDL_memcpy(&retval->src_spec, src_spec, sizeof (SDL_AudioSpec)); - if (SetAudioStreamFormat(retval, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate) == -1) { + if (SetAudioStreamFormat(retval, src_spec, dst_spec) == -1) { SDL_DestroyAudioStream(retval); return NULL; } @@ -670,50 +638,88 @@ SDL_AudioStream *SDL_CreateAudioStream(SDL_AudioFormat src_format, return retval; } -int SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat *src_format, int *src_channels, int *src_rate, SDL_AudioFormat *dst_format, int *dst_channels, int *dst_rate) +int SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamRequestCallback callback, void *userdata) { if (!stream) { return SDL_InvalidParamError("stream"); } SDL_LockMutex(stream->lock); - #define GETAUDIOSTREAMFIELD(x) if (x) { *x = stream->x; } - GETAUDIOSTREAMFIELD(src_format); - GETAUDIOSTREAMFIELD(src_channels); - GETAUDIOSTREAMFIELD(src_rate); - GETAUDIOSTREAMFIELD(dst_format); - GETAUDIOSTREAMFIELD(dst_channels); - GETAUDIOSTREAMFIELD(dst_rate); - #undef GETAUDIOSTREAMFIELD + stream->get_callback = callback; + stream->get_callback_userdata = userdata; SDL_UnlockMutex(stream->lock); return 0; } -int SDL_SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_format, int src_channels, int src_rate, SDL_AudioFormat dst_format, int dst_channels, int dst_rate) +int SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamRequestCallback callback, void *userdata) { - int retval; - if (!stream) { return SDL_InvalidParamError("stream"); - } else if (!SDL_IsSupportedAudioFormat(src_format)) { - return SDL_InvalidParamError("src_format"); - } else if (!SDL_IsSupportedChannelCount(src_channels)) { - return SDL_InvalidParamError("src_channels"); - } else if (src_rate <= 0) { - return SDL_InvalidParamError("src_rate"); - } else if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { - return SDL_SetError("Source rate is too high"); - } else if (!SDL_IsSupportedAudioFormat(dst_format)) { - return SDL_InvalidParamError("dst_format"); - } else if (!SDL_IsSupportedChannelCount(dst_channels)) { - return SDL_InvalidParamError("dst_channels"); - } else if (dst_rate <= 0) { - return SDL_InvalidParamError("dst_rate"); - } else if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { - return SDL_SetError("Destination rate is too high"); + } + SDL_LockMutex(stream->lock); + stream->put_callback = callback; + stream->put_callback_userdata = userdata; + SDL_UnlockMutex(stream->lock); + return 0; +} + +int SDL_LockAudioStream(SDL_AudioStream *stream) +{ + return stream ? SDL_LockMutex(stream->lock) : SDL_InvalidParamError("stream"); +} + +int SDL_UnlockAudioStream(SDL_AudioStream *stream) +{ + return stream ? SDL_UnlockMutex(stream->lock) : SDL_InvalidParamError("stream"); +} + +int SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_spec, SDL_AudioSpec *dst_spec) +{ + if (!stream) { + return SDL_InvalidParamError("stream"); + } + SDL_LockMutex(stream->lock); + if (src_spec) { + SDL_memcpy(src_spec, &stream->src_spec, sizeof (SDL_AudioSpec)); + } + if (dst_spec) { + SDL_memcpy(dst_spec, &stream->dst_spec, sizeof (SDL_AudioSpec)); + } + SDL_UnlockMutex(stream->lock); + return 0; +} + +int SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec) +{ + if (!stream) { + return SDL_InvalidParamError("stream"); + } + + if (src_spec) { + if (!SDL_IsSupportedAudioFormat(src_spec->format)) { + return SDL_InvalidParamError("src_spec->format"); + } else if (!SDL_IsSupportedChannelCount(src_spec->channels)) { + return SDL_InvalidParamError("src_spec->channels"); + } else if (src_spec->freq <= 0) { + return SDL_InvalidParamError("src_spec->freq"); + } else if (src_spec->freq >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { + return SDL_SetError("Source rate is too high"); + } + } + + if (dst_spec) { + if (!SDL_IsSupportedAudioFormat(dst_spec->format)) { + return SDL_InvalidParamError("dst_spec->format"); + } else if (!SDL_IsSupportedChannelCount(dst_spec->channels)) { + return SDL_InvalidParamError("dst_spec->channels"); + } else if (dst_spec->freq <= 0) { + return SDL_InvalidParamError("dst_spec->freq"); + } else if (dst_spec->freq >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { + return SDL_SetError("Destination rate is too high"); + } } SDL_LockMutex(stream->lock); - retval = SetAudioStreamFormat(stream, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); + const int retval = SetAudioStreamFormat(stream, src_spec ? src_spec : &stream->src_spec, dst_spec ? dst_spec : &stream->dst_spec); SDL_UnlockMutex(stream->lock); return retval; @@ -721,8 +727,6 @@ int SDL_SetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioFormat src_format int SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len) { - int retval; - #if DEBUG_AUDIOSTREAM SDL_Log("AUDIOSTREAM: wants to put %d preconverted bytes", len); #endif @@ -732,19 +736,26 @@ int SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len) } else if (buf == NULL) { return SDL_InvalidParamError("buf"); } else if (len == 0) { - return 0; /* nothing to do. */ + return 0; // nothing to do. } SDL_LockMutex(stream->lock); + const int prev_available = stream->put_callback ? SDL_GetAudioStreamAvailable(stream) : 0; + if ((len % stream->src_sample_frame_size) != 0) { SDL_UnlockMutex(stream->lock); return SDL_SetError("Can't add partial sample frames"); } - /* just queue the data, we convert/resample when dequeueing. */ - retval = SDL_WriteToDataQueue(stream->queue, buf, len); + // just queue the data, we convert/resample when dequeueing. + const int retval = SDL_WriteToDataQueue(stream->queue, buf, len); stream->flushed = SDL_FALSE; + + if (stream->put_callback) { + stream->put_callback(stream, SDL_GetAudioStreamAvailable(stream) - prev_available, stream->put_callback_userdata); + } + SDL_UnlockMutex(stream->lock); return retval; @@ -768,16 +779,14 @@ int SDL_FlushAudioStream(SDL_AudioStream *stream) The returned buffer is aligned/padded for use with SIMD instructions. */ static Uint8 *EnsureStreamWorkBufferSize(SDL_AudioStream *stream, size_t newlen) { - Uint8 *ptr; - if (stream->work_buffer_allocation >= newlen) { return stream->work_buffer; } - ptr = (Uint8 *) SDL_aligned_alloc(SDL_SIMDGetAlignment(), newlen); + Uint8 *ptr = (Uint8 *) SDL_aligned_alloc(SDL_SIMDGetAlignment(), newlen); if (ptr == NULL) { SDL_OutOfMemory(); - return NULL; /* previous work buffer is still valid! */ + return NULL; // previous work buffer is still valid! } SDL_aligned_free(stream->work_buffer); @@ -788,45 +797,44 @@ static Uint8 *EnsureStreamWorkBufferSize(SDL_AudioStream *stream, size_t newlen) static int CalculateAudioStreamWorkBufSize(const SDL_AudioStream *stream, int len) { - int workbuf_frames = len / stream->dst_sample_frame_size; /* start with requested sample frames */ int workbuflen = len; - int inputlen; + int workbuf_frames = len / stream->dst_sample_frame_size; // start with requested sample frames + int inputlen = workbuf_frames * stream->max_sample_frame_size; - inputlen = workbuf_frames * stream->max_sample_frame_size; if (inputlen > workbuflen) { workbuflen = inputlen; } - if (stream->dst_rate != stream->src_rate) { - /* calculate requested sample frames needed before resampling. Use a Uint64 so the multiplication doesn't overflow. */ - const int input_frames = ((int) ((((Uint64) workbuf_frames) * stream->src_rate) / stream->dst_rate)); + if (stream->dst_spec.freq != stream->src_spec.freq) { + // calculate requested sample frames needed before resampling. Use a Uint64 so the multiplication doesn't overflow. + const int input_frames = ((int) ((((Uint64) workbuf_frames) * stream->src_spec.freq) / stream->dst_spec.freq)); inputlen = input_frames * stream->max_sample_frame_size; if (inputlen > workbuflen) { workbuflen = inputlen; } - /* Calculate space needed to move to format/channels used for resampling stage. */ + // Calculate space needed to move to format/channels used for resampling stage. inputlen = input_frames * stream->pre_resample_channels * sizeof (float); if (inputlen > workbuflen) { workbuflen = inputlen; } - /* Calculate space needed after resample (which lives in a second copy in the same buffer). */ + // Calculate space needed after resample (which lives in a second copy in the same buffer). workbuflen += workbuf_frames * stream->pre_resample_channels * sizeof (float); } return workbuflen; } -/* You must hold stream->lock and validate your parameters before calling this! */ +// You must hold stream->lock and validate your parameters before calling this! static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int len) { const int max_available = SDL_GetAudioStreamAvailable(stream); - const SDL_AudioFormat src_format = stream->src_format; - const int src_channels = stream->src_channels; - const int src_rate = stream->src_rate; + const SDL_AudioFormat src_format = stream->src_spec.format; + const int src_channels = stream->src_spec.channels; + const int src_rate = stream->src_spec.freq; const int src_sample_frame_size = stream->src_sample_frame_size; - const SDL_AudioFormat dst_format = stream->dst_format; - const int dst_channels = stream->dst_channels; - const int dst_rate = stream->dst_rate; + const SDL_AudioFormat dst_format = stream->dst_spec.format; + const int dst_channels = stream->dst_spec.channels; + const int dst_rate = stream->dst_spec.freq; const int dst_sample_frame_size = stream->dst_sample_frame_size; const int max_sample_frame_size = stream->max_sample_frame_size; const int pre_resample_channels = stream->pre_resample_channels; @@ -854,29 +862,38 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le output_frames = len / dst_sample_frame_size; if (output_frames == 0) { - return 0; /* nothing to do. */ + return 0; // nothing to do. } - /* !!! FIXME: this could be less aggressive about allocation, if we decide the necessary size at each stage and select the maximum required. */ + // !!! FIXME: this could be less aggressive about allocation, if we decide the necessary size at each stage and select the maximum required. workbuflen = CalculateAudioStreamWorkBufSize(stream, len); workbuf = EnsureStreamWorkBufferSize(stream, workbuflen); if (!workbuf) { return -1; } - /* figure out how much data we need to fulfill the request. */ - input_frames = len / dst_sample_frame_size; /* total sample frames caller wants */ + // figure out how much data we need to fulfill the request. + input_frames = len / dst_sample_frame_size; // total sample frames caller wants if (dst_rate != src_rate) { - /* calculate requested sample frames needed before resampling. Use a Uint64 so the multiplication doesn't overflow. */ - input_frames = (int) ((((Uint64) input_frames) * src_rate) / dst_rate); - if (input_frames == 0) { - return 0; /* if they are upsampling and we end up needing less than a frame of input, we reject it because it would cause artifacts on future reads to eat a full input frame. */ + // calculate requested sample frames needed before resampling. Use a Uint64 so the multiplication doesn't overflow. + const int resampled_input_frames = (int) ((((Uint64) input_frames) * src_rate) / dst_rate); + if (resampled_input_frames > 0) { + input_frames = resampled_input_frames; + } else { // uhoh, not enough input frames! + // if they are upsampling and we end up needing less than a frame of input, we reject it because it would cause artifacts on future reads to eat a full input frame. + // however, if the stream is flushed, we would just be padding any remaining input with silence anyhow, so use it up. + if (stream->flushed) { + SDL_assert(((size_t) ((input_frames * src_sample_frame_size) + future_buffer_filled_frames)) <= stream->future_buffer_allocation); + // leave input_frames alone; this will just shuffle what's available from the future buffer and pad with silence as appropriate, below. + } else { + return 0; + } } } - workbuf_frames = 0; /* no input has been moved to the workbuf yet. */ + workbuf_frames = 0; // no input has been moved to the workbuf yet. - /* move any previous right-padding to the start of the buffer to convert, as those would have been the next samples from the queue ("the future buffer"). */ + // move any previous right-padding to the start of the buffer to convert, as those would have been the next samples from the queue ("the future buffer"). if (future_buffer_filled_frames) { const int cpyframes = SDL_min(input_frames, future_buffer_filled_frames); const int cpy = cpyframes * src_sample_frame_size; @@ -884,18 +901,18 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le workbuf_frames = cpyframes; if (future_buffer_filled_frames == cpyframes) { stream->future_buffer_filled_frames = future_buffer_filled_frames = 0; - } else { /* slide any remaining bytes to the start of the padding buffer, if this was a small request. */ + } else { // slide any remaining bytes to the start of the padding buffer, if this was a small request. SDL_memmove(future_buffer, future_buffer + cpy, (future_buffer_filled_frames - cpyframes) * src_sample_frame_size); future_buffer_filled_frames -= cpyframes; stream->future_buffer_filled_frames = future_buffer_filled_frames; } } - /* we either consumed all the future buffer or we don't need to read more from the queue. If this assert fails, we will have data in the wrong order in the future buffer when we top it off. */ + // we either consumed all the future buffer or we don't need to read more from the queue. If this assert fails, we will have data in the wrong order in the future buffer when we top it off. SDL_assert((future_buffer_filled_frames == 0) || (workbuf_frames == input_frames)); - /* now read unconverted data from the queue into the work buffer to fulfill the request. */ - if (input_frames > workbuf_frames) { /* need more data? */ + // now read unconverted data from the queue into the work buffer to fulfill the request. + if (input_frames > workbuf_frames) { // need more data? const int workbufpos = workbuf_frames * src_sample_frame_size; const int request_bytes = (input_frames - workbuf_frames) * src_sample_frame_size; int read_frames; @@ -903,10 +920,10 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le br = (int) SDL_ReadFromDataQueue(stream->queue, workbuf + workbufpos, request_bytes); read_frames = br / src_sample_frame_size; workbuf_frames += read_frames; - input_frames = workbuf_frames; /* what we actually have to work with */ + input_frames = workbuf_frames; // what we actually have to work with } - /* for some resamples, we need to fill up the future buffer, too, to use as right padding. */ + // for some resamples, we need to fill up the future buffer, too, to use as right padding. if (future_buffer_filled_frames < resampler_padding_frames) { const int cpyframes = resampler_padding_frames - future_buffer_filled_frames; const int cpy = cpyframes * src_sample_frame_size; @@ -915,24 +932,24 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le brframes = br / src_sample_frame_size; future_buffer_filled_frames += brframes; stream->future_buffer_filled_frames = future_buffer_filled_frames; - if (br < cpy) { /* we couldn't fill the future buffer with enough padding! */ - if (stream->flushed) { /* that's okay, we're flushing, just silence the still-needed padding. */ - SDL_memset(future_buffer + (future_buffer_filled_frames * src_sample_frame_size), GetMemsetSilenceValue(src_format), cpy - br); - } else { /* Drastic measures: steal from the work buffer! */ + if (br < cpy) { // we couldn't fill the future buffer with enough padding! + if (stream->flushed) { // that's okay, we're flushing, just silence the still-needed padding. + SDL_memset(future_buffer + (future_buffer_filled_frames * src_sample_frame_size), SDL_GetSilenceValueForFormat(src_format), cpy - br); + } else { // Drastic measures: steal from the work buffer! const int stealcpyframes = SDL_min(workbuf_frames, cpyframes - brframes); const int stealcpy = stealcpyframes * src_sample_frame_size; SDL_memcpy(future_buffer + (future_buffer_filled_frames * src_sample_frame_size), workbuf + ((workbuf_frames - stealcpyframes) * src_sample_frame_size), stealcpy); workbuf_frames -= stealcpyframes; - input_frames = workbuf_frames; /* what we actually have to work with, now */ + input_frames = workbuf_frames; // what we actually have to work with, now future_buffer_filled_frames += stealcpyframes; SDL_assert(future_buffer_filled_frames <= resampler_padding_frames); } } } - /* Now, the work buffer has enough sample frames to fulfill the request (or all the frames available if not), and the future buffer is loaded if necessary. */ + // Now, the work buffer has enough sample frames to fulfill the request (or all the frames available if not), and the future buffer is loaded if necessary. - /* If we have resampling padding buffers, convert the current history and future buffers to float32. */ + // If we have resampling padding buffers, convert the current history and future buffers to float32. if (resampler_padding_frames > 0) { const int history_buffer_bytes = history_buffer_frames * src_sample_frame_size; const int resampler_padding_bytes = resampler_padding_frames * src_sample_frame_size; @@ -942,7 +959,7 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le ConvertAudio(resampler_padding_frames, future_buffer, src_format, src_channels, stream->right_padding, SDL_AUDIO_F32, pre_resample_channels); } - /* slide in new data to the history buffer, shuffling out the oldest, for the next run, since we've already updated left_padding with current data. */ + // slide in new data to the history buffer, shuffling out the oldest, for the next run, since we've already updated left_padding with current data. { const int history_buffer_bytes = history_buffer_frames * src_sample_frame_size; const int request_bytes = input_frames * src_sample_frame_size; @@ -950,15 +967,15 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le const int preserve_bytes = history_buffer_bytes - request_bytes; SDL_memmove(history_buffer, history_buffer + request_bytes, preserve_bytes); SDL_memcpy(history_buffer + preserve_bytes, workbuf, request_bytes); - } else { /* are we just replacing the whole thing instead? */ + } else { // are we just replacing the whole thing instead? SDL_memcpy(history_buffer, (workbuf + request_bytes) - history_buffer_bytes, history_buffer_bytes); } } - /* Not resampling? It's an easy conversion (and maybe not even that!) */ + // Not resampling? It's an easy conversion (and maybe not even that!) if (src_rate == dst_rate) { SDL_assert(resampler_padding_frames == 0); - /* see if we can do the conversion in-place (will fit in `buf` while in-progress), or if we need to do it in the workbuf and copy it over */ + // see if we can do the conversion in-place (will fit in `buf` while in-progress), or if we need to do it in the workbuf and copy it over if (max_sample_frame_size <= dst_sample_frame_size) { ConvertAudio(input_frames, workbuf, src_format, src_channels, buf, dst_format, dst_channels); } else { @@ -968,14 +985,14 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le return input_frames * dst_sample_frame_size; } - /* Resampling! get the work buffer to float32 format, etc, in-place. */ + // Resampling! get the work buffer to float32 format, etc, in-place. ConvertAudio(input_frames, workbuf, src_format, src_channels, workbuf, SDL_AUDIO_F32, pre_resample_channels); if ((dst_format == SDL_AUDIO_F32) && (dst_channels == pre_resample_channels)) { resample_outbuf = (float *) buf; } else { const int output_bytes = output_frames * pre_resample_channels * sizeof (float); - resample_outbuf = (float *) ((workbuf + stream->work_buffer_allocation) - output_bytes); /* do at the end of the buffer so we have room for final convert at front. */ + resample_outbuf = (float *) ((workbuf + stream->work_buffer_allocation) - output_bytes); // do at the end of the buffer so we have room for final convert at front. } ResampleAudio(pre_resample_channels, src_rate, dst_rate, @@ -983,8 +1000,8 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le (const float *) workbuf, input_frames, resample_outbuf, output_frames); - /* Get us to the final format! */ - /* see if we can do the conversion in-place (will fit in `buf` while in-progress), or if we need to do it in the workbuf and copy it over */ + // Get us to the final format! + // see if we can do the conversion in-place (will fit in `buf` while in-progress), or if we need to do it in the workbuf and copy it over if (max_sample_frame_size <= dst_sample_frame_size) { ConvertAudio(output_frames, resample_outbuf, SDL_AUDIO_F32, pre_resample_channels, buf, dst_format, dst_channels); } else { @@ -995,11 +1012,10 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le return (int) (output_frames * dst_sample_frame_size); } -/* get converted/resampled data from the stream */ +// get converted/resampled data from the stream int SDL_GetAudioStreamData(SDL_AudioStream *stream, void *voidbuf, int len) { Uint8 *buf = (Uint8 *) voidbuf; - int retval = 0; #if DEBUG_AUDIOSTREAM SDL_Log("AUDIOSTREAM: want to get %d converted bytes", len); @@ -1012,16 +1028,34 @@ int SDL_GetAudioStreamData(SDL_AudioStream *stream, void *voidbuf, int len) } else if (len < 0) { return SDL_InvalidParamError("len"); } else if (len == 0) { - return 0; /* nothing to do. */ + return 0; // nothing to do. } SDL_LockMutex(stream->lock); - len -= len % stream->dst_sample_frame_size; /* chop off any fractional sample frame. */ + len -= len % stream->dst_sample_frame_size; // chop off any fractional sample frame. - /* we convert in chunks, so we don't end up allocating a massive work buffer, etc. */ - while (len > 0) { /* didn't ask for a whole sample frame, nothing to do */ - const int chunk_size = 1024 * 1024; /* !!! FIXME: a megabyte might be overly-aggressive. */ + // give the callback a chance to fill in more stream data if it wants. + if (stream->get_callback) { + int approx_request = len / stream->dst_sample_frame_size; // start with sample frames desired + if (stream->src_spec.freq != stream->dst_spec.freq) { + // calculate difference in dataset size after resampling. Use a Uint64 so the multiplication doesn't overflow. + approx_request = (int) (size_t) ((((Uint64) approx_request) * stream->src_spec.freq) / stream->dst_spec.freq); + if (!stream->flushed) { // do we need to fill the future buffer to accomodate this, too? + approx_request += stream->resampler_padding_frames - stream->future_buffer_filled_frames; + } + } + + approx_request *= stream->src_sample_frame_size; // convert sample frames to bytes. + const int already_have = SDL_GetAudioStreamAvailable(stream); + approx_request -= SDL_min(approx_request, already_have); // we definitely have this much output already packed in. + stream->get_callback(stream, approx_request, stream->get_callback_userdata); + } + + // we convert in chunks, so we don't end up allocating a massive work buffer, etc. + int retval = 0; + while (len > 0) { // didn't ask for a whole sample frame, nothing to do + const int chunk_size = 1024 * 1024; // !!! FIXME: a megabyte might be overly-aggressive. const int rc = GetAudioStreamDataInternal(stream, buf, SDL_min(len, chunk_size)); if (rc == -1) { @@ -1054,41 +1088,39 @@ int SDL_GetAudioStreamData(SDL_AudioStream *stream, void *voidbuf, int len) return retval; } -/* number of converted/resampled bytes available */ +// number of converted/resampled bytes available int SDL_GetAudioStreamAvailable(SDL_AudioStream *stream) { - const int max_int = 0x7FFFFFFF; /* !!! FIXME: This will blow up on weird processors. Is there an SDL_INT_MAX? */ - size_t count; - if (!stream) { return SDL_InvalidParamError("stream"); } SDL_LockMutex(stream->lock); - /* total bytes available in source format in data queue */ - count = SDL_GetDataQueueSize(stream->queue); + // total bytes available in source format in data queue + size_t count = SDL_GetDataQueueSize(stream->queue); - /* total sample frames available in data queue */ + // total sample frames available in data queue count /= stream->src_sample_frame_size; count += stream->future_buffer_filled_frames; - /* sample frames after resampling */ - if (stream->src_rate != stream->dst_rate) { + // sample frames after resampling + if (stream->src_spec.freq != stream->dst_spec.freq) { if (!stream->flushed) { - /* have to save some samples for padding. They aren't available until more data is added or the stream is flushed. */ + // have to save some samples for padding. They aren't available until more data is added or the stream is flushed. count = (count < ((size_t) stream->resampler_padding_frames)) ? 0 : (count - stream->resampler_padding_frames); } - /* calculate difference in dataset size after resampling. Use a Uint64 so the multiplication doesn't overflow. */ - count = (size_t) ((((Uint64) count) * stream->dst_rate) / stream->src_rate); + // calculate difference in dataset size after resampling. Use a Uint64 so the multiplication doesn't overflow. + count = (size_t) ((((Uint64) count) * stream->dst_spec.freq) / stream->src_spec.freq); } - /* convert from sample frames to bytes in destination format. */ + // convert from sample frames to bytes in destination format. count *= stream->dst_sample_frame_size; SDL_UnlockMutex(stream->lock); - /* if this overflows an int, just clamp it to a maximum. */ + // if this overflows an int, just clamp it to a maximum. + const int max_int = 0x7FFFFFFF; // !!! FIXME: This will blow up on weird processors. Is there an SDL_INT_MAX? return (count >= ((size_t) max_int)) ? max_int : ((int) count); } @@ -1100,7 +1132,9 @@ int SDL_ClearAudioStream(SDL_AudioStream *stream) SDL_LockMutex(stream->lock); SDL_ClearDataQueue(stream->queue, (size_t)stream->packetlen * 2); - SDL_memset(stream->history_buffer, GetMemsetSilenceValue(stream->src_format), stream->history_buffer_frames * stream->src_channels * sizeof (float)); + if (stream->history_buffer != NULL) { + SDL_memset(stream->history_buffer, SDL_GetSilenceValueForFormat(stream->src_spec.format), stream->history_buffer_frames * stream->src_spec.channels * sizeof (float)); + } stream->future_buffer_filled_frames = 0; stream->flushed = SDL_FALSE; SDL_UnlockMutex(stream->lock); @@ -1110,7 +1144,8 @@ int SDL_ClearAudioStream(SDL_AudioStream *stream) void SDL_DestroyAudioStream(SDL_AudioStream *stream) { if (stream) { - /* do not destroy stream->lock! it's a copy of `stream->queue`'s mutex, so destroying the queue will handle it. */ + SDL_UnbindAudioStream(stream); + // do not destroy stream->lock! it's a copy of `stream->queue`'s mutex, so destroying the queue will handle it. SDL_DestroyDataQueue(stream->queue); SDL_aligned_free(stream->work_buffer); SDL_aligned_free(stream->history_buffer); @@ -1120,3 +1155,55 @@ void SDL_DestroyAudioStream(SDL_AudioStream *stream) SDL_free(stream); } } + +int SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, + const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len) +{ + if (dst_data) { + *dst_data = NULL; + } + + if (dst_len) { + *dst_len = 0; + } + + if (src_data == NULL) { + return SDL_InvalidParamError("src_data"); + } else if (src_len < 0) { + return SDL_InvalidParamError("src_len"); + } else if (dst_data == NULL) { + return SDL_InvalidParamError("dst_data"); + } else if (dst_len == NULL) { + return SDL_InvalidParamError("dst_len"); + } + + int retval = -1; + Uint8 *dst = NULL; + int dstlen = 0; + + SDL_AudioStream *stream = SDL_CreateAudioStream(src_spec, dst_spec); + if (stream != NULL) { + if ((SDL_PutAudioStreamData(stream, src_data, src_len) == 0) && (SDL_FlushAudioStream(stream) == 0)) { + dstlen = SDL_GetAudioStreamAvailable(stream); + if (dstlen >= 0) { + dst = (Uint8 *)SDL_malloc(dstlen); + if (!dst) { + SDL_OutOfMemory(); + } else { + retval = (SDL_GetAudioStreamData(stream, dst, dstlen) >= 0) ? 0 : -1; + } + } + } + } + + if (retval == -1) { + SDL_free(dst); + } else { + *dst_data = dst; + *dst_len = dstlen; + } + + SDL_DestroyAudioStream(stream); + return retval; +} + diff --git a/src/audio/SDL_audiodev.c b/src/audio/SDL_audiodev.c index b26740db..9d73fbb5 100644 --- a/src/audio/SDL_audiodev.c +++ b/src/audio/SDL_audiodev.c @@ -45,13 +45,13 @@ #define SDL_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 SDL_bool iscapture, const char *fname, int flags, SDL_bool (*test)(int fd)) { struct stat sb; if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) { const int audio_fd = open(fname, flags | O_CLOEXEC, 0); if (audio_fd >= 0) { - const int okay = test(audio_fd); + const SDL_bool okay = test(audio_fd); close(audio_fd); if (okay) { static size_t dummyhandle = 0; @@ -69,12 +69,12 @@ static void test_device(const int iscapture, const char *fname, int flags, int ( } } -static int test_stub(int fd) +static SDL_bool test_stub(int fd) { - return 1; + return SDL_TRUE; } -static void SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int)) +static void SDL_EnumUnixAudioDevices_Internal(const SDL_bool iscapture, const SDL_bool classic, SDL_bool (*test)(int)) { const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; const char *audiodev; @@ -116,7 +116,7 @@ static void SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int cla } } -void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)) +void SDL_EnumUnixAudioDevices(const SDL_bool classic, SDL_bool (*test)(int)) { SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test); SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test); diff --git a/src/audio/SDL_audiodev_c.h b/src/audio/SDL_audiodev_c.h index 370172c9..6301d07c 100644 --- a/src/audio/SDL_audiodev_c.h +++ b/src/audio/SDL_audiodev_c.h @@ -36,6 +36,6 @@ #define OPEN_FLAGS_INPUT (O_RDONLY | O_NONBLOCK) #endif -extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)); +extern void SDL_EnumUnixAudioDevices(const SDL_bool classic, SDL_bool (*test)(int)); #endif /* SDL_audiodev_c_h_ */ diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 7c6fd298..7e170330 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -18,151 +18,269 @@ 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_sysaudio_h_ #define SDL_sysaudio_h_ #include "../SDL_dataqueue.h" -#include "./SDL_audio_c.h" -/* !!! FIXME: These are wordy and unlocalized... */ +#define DEBUG_AUDIOSTREAM 0 +#define DEBUG_AUDIO_CONVERT 0 + +#if DEBUG_AUDIO_CONVERT +#define LOG_DEBUG_AUDIO_CONVERT(from, to) SDL_Log("SDL_AUDIO_CONVERT: Converting %s to %s.\n", from, to); +#else +#define LOG_DEBUG_AUDIO_CONVERT(from, to) +#endif + +// These pointers get set during SDL_ChooseAudioConverters() to various SIMD implementations. +extern void (*SDL_Convert_S8_to_F32)(float *dst, const Sint8 *src, int num_samples); +extern void (*SDL_Convert_U8_to_F32)(float *dst, const Uint8 *src, int num_samples); +extern void (*SDL_Convert_S16_to_F32)(float *dst, const Sint16 *src, int num_samples); +extern void (*SDL_Convert_S32_to_F32)(float *dst, const Sint32 *src, int num_samples); +extern void (*SDL_Convert_F32_to_S8)(Sint8 *dst, const float *src, int num_samples); +extern void (*SDL_Convert_F32_to_U8)(Uint8 *dst, const float *src, int num_samples); +extern void (*SDL_Convert_F32_to_S16)(Sint16 *dst, const float *src, int num_samples); +extern void (*SDL_Convert_F32_to_S32)(Sint32 *dst, const float *src, int num_samples); + +// !!! FIXME: These are wordy and unlocalized... #define DEFAULT_OUTPUT_DEVNAME "System audio output device" #define DEFAULT_INPUT_DEVNAME "System audio capture device" -/* The SDL audio driver */ -typedef struct SDL_AudioDevice SDL_AudioDevice; +// these are used when no better specifics are known. We default to CD audio quality. +#define DEFAULT_AUDIO_OUTPUT_FORMAT SDL_AUDIO_S16 +#define DEFAULT_AUDIO_OUTPUT_CHANNELS 2 +#define DEFAULT_AUDIO_OUTPUT_FREQUENCY 44100 -/* Audio targets should call this as devices are added to the system (such as +#define DEFAULT_AUDIO_CAPTURE_FORMAT SDL_AUDIO_S16 +#define DEFAULT_AUDIO_CAPTURE_CHANNELS 1 +#define DEFAULT_AUDIO_CAPTURE_FREQUENCY 44100 + +typedef struct SDL_AudioDevice SDL_AudioDevice; +typedef struct SDL_LogicalAudioDevice SDL_LogicalAudioDevice; + +// Used by src/SDL.c to initialize a particular audio driver. +extern int SDL_InitAudio(const char *driver_name); + +// Used by src/SDL.c to shut down previously-initialized audio. +extern void SDL_QuitAudio(void); + +// Function to get a list of audio formats, ordered most similar to `format` to least, 0-terminated. Don't free results. +const SDL_AudioFormat *SDL_ClosestAudioFormats(SDL_AudioFormat format); + +// Must be called at least once before using converters (SDL_CreateAudioStream will call it !!! FIXME but probably shouldn't). +extern void SDL_ChooseAudioConverters(void); + +/* Backends 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 SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle); +extern SDL_AudioDevice *SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, const 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 SDL_bool iscapture, void *handle); +/* Backends should call this if an opened audio device is lost. + This can happen due to i/o errors, or a device being unplugged, etc. */ +extern void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device); -/* 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, - etc. If the device is totally gone, please also call SDL_RemoveAudioDevice() - as appropriate so SDL's list of devices is accurate. */ -extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device); +// Backends should call this if the system default device changes. +extern void SDL_DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device); -/* This is the size of a packet when using SDL_QueueAudio(). We allocate - these as necessary and pool them, under the assumption that we'll - eventually end up with a handful that keep recycling, meeting whatever - the app needs. We keep packing data tightly as more arrives to avoid - wasting space, and if we get a giant block of data, we'll split them - into multiple packets behind the scenes. My expectation is that most - apps will have 2-3 of these in the pool. 8k should cover most needs, but - if this is crippling for some embedded system, we can #ifdef this. - The system preallocates enough packets for 2 callbacks' worth of data. */ -#define SDL_AUDIOBUFFERQUEUE_PACKETLEN (8 * 1024) +// Backends should call this if a device's format is changing (opened or not); SDL will update state and carry on with the new format. +extern int SDL_AudioDeviceFormatChanged(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames); + +// Same as above, but assume the device is already locked. +extern int SDL_AudioDeviceFormatChangedAlreadyLocked(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames); + +// Find the SDL_AudioDevice associated with the handle supplied to SDL_AddAudioDevice. NULL if not found. DOES NOT LOCK THE DEVICE. +extern SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle); + +// Find an SDL_AudioDevice, selected by a callback. NULL if not found. DOES NOT LOCK THE DEVICE. +extern SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(SDL_bool (*callback)(SDL_AudioDevice *device, void *userdata), void *userdata); + +// Backends should call this if they change the device format, channels, freq, or sample_frames to keep other state correct. +extern void SDL_UpdatedAudioDeviceFormat(SDL_AudioDevice *device); + +// Backends can call this to get a standardized name for a thread to power a specific audio device. +char *SDL_GetAudioThreadName(SDL_AudioDevice *device, char *buf, size_t buflen); + + +// These functions are the heart of the audio threads. Backends can call them directly if they aren't using the SDL-provided thread. +extern void SDL_OutputAudioThreadSetup(SDL_AudioDevice *device); +extern SDL_bool SDL_OutputAudioThreadIterate(SDL_AudioDevice *device); +extern void SDL_OutputAudioThreadShutdown(SDL_AudioDevice *device); +extern void SDL_CaptureAudioThreadSetup(SDL_AudioDevice *device); +extern SDL_bool SDL_CaptureAudioThreadIterate(SDL_AudioDevice *device); +extern void SDL_CaptureAudioThreadShutdown(SDL_AudioDevice *device); +extern void SDL_AudioThreadFinalize(SDL_AudioDevice *device); typedef struct SDL_AudioDriverImpl { - void (*DetectDevices)(void); - int (*OpenDevice)(SDL_AudioDevice *_this, const char *devname); - void (*ThreadInit)(SDL_AudioDevice *_this); /* Called by audio thread at start */ - void (*ThreadDeinit)(SDL_AudioDevice *_this); /* Called by audio thread at end */ - void (*WaitDevice)(SDL_AudioDevice *_this); - void (*PlayDevice)(SDL_AudioDevice *_this); - Uint8 *(*GetDeviceBuf)(SDL_AudioDevice *_this); - int (*CaptureFromDevice)(SDL_AudioDevice *_this, void *buffer, int buflen); - void (*FlushCapture)(SDL_AudioDevice *_this); - void (*CloseDevice)(SDL_AudioDevice *_this); - void (*LockDevice)(SDL_AudioDevice *_this); - void (*UnlockDevice)(SDL_AudioDevice *_this); - void (*FreeDeviceHandle)(void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */ + void (*DetectDevices)(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture); + int (*OpenDevice)(SDL_AudioDevice *device); + void (*ThreadInit)(SDL_AudioDevice *device); // Called by audio thread at start + void (*ThreadDeinit)(SDL_AudioDevice *device); // Called by audio thread at end + void (*WaitDevice)(SDL_AudioDevice *device); + void (*PlayDevice)(SDL_AudioDevice *device, const Uint8 *buffer, int buflen); // buffer and buflen are always from GetDeviceBuf, passed here for convenience. + Uint8 *(*GetDeviceBuf)(SDL_AudioDevice *device, int *buffer_size); + void (*WaitCaptureDevice)(SDL_AudioDevice *device); + int (*CaptureFromDevice)(SDL_AudioDevice *device, void *buffer, int buflen); + void (*FlushCapture)(SDL_AudioDevice *device); + void (*CloseDevice)(SDL_AudioDevice *device); + void (*FreeDeviceHandle)(SDL_AudioDevice *device); // SDL is done with this device; free the 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. */ - SDL_bool ProvidesOwnCallbackThread; + // Some flags to push duplicate code into the core and reduce #ifdefs. + SDL_bool ProvidesOwnCallbackThread; // !!! FIXME: rename this, it's not a callback thread anymore. 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 { - /* * * */ - /* The name of this audio driver */ - const char *name; - - /* * * */ - /* The description of this audio driver */ - const char *desc; - - SDL_AudioDriverImpl impl; - - /* A mutex for device detection */ - SDL_Mutex *detectionLock; - SDL_bool captureDevicesRemoved; - SDL_bool outputDevicesRemoved; - int outputDeviceCount; - int inputDeviceCount; - SDL_AudioDeviceItem *outputDevices; - SDL_AudioDeviceItem *inputDevices; + const char *name; // The name of this audio driver + const char *desc; // The description of this audio driver + SDL_AudioDriverImpl impl; // the backend's interface + SDL_RWLock *device_list_lock; // A mutex for device detection + SDL_AudioDevice *output_devices; // the list of currently-available audio output devices. + SDL_AudioDevice *capture_devices; // the list of currently-available audio capture devices. + SDL_AudioDeviceID default_output_device_id; + SDL_AudioDeviceID default_capture_device_id; + SDL_AtomicInt output_device_count; + SDL_AtomicInt capture_device_count; + SDL_AtomicInt last_device_instance_id; // increments on each device add to provide unique instance IDs + SDL_AtomicInt shutting_down; // non-zero during SDL_Quit, so we known not to accept any last-minute device hotplugs. } SDL_AudioDriver; -/* Define the SDL audio driver structure */ +struct SDL_AudioStream +{ + SDL_DataQueue *queue; + SDL_Mutex *lock; // this is just a copy of `queue`'s mutex. We share a lock. + + SDL_AudioStreamRequestCallback get_callback; + void *get_callback_userdata; + SDL_AudioStreamRequestCallback put_callback; + void *put_callback_userdata; + + Uint8 *work_buffer; // used for scratch space during data conversion/resampling. + Uint8 *history_buffer; // history for left padding and future sample rate changes. + Uint8 *future_buffer; // stuff that left the queue for the right padding and will be next read's data. + float *left_padding; // left padding for resampling. + float *right_padding; // right padding for resampling. + + SDL_bool flushed; + + size_t work_buffer_allocation; + size_t history_buffer_allocation; + size_t future_buffer_allocation; + size_t resampler_padding_allocation; + + int resampler_padding_frames; + int history_buffer_frames; + int future_buffer_filled_frames; + + SDL_AudioSpec src_spec; + SDL_AudioSpec dst_spec; + + int src_sample_frame_size; + int dst_sample_frame_size; + int max_sample_frame_size; + + int pre_resample_channels; + int packetlen; + + SDL_LogicalAudioDevice *bound_device; + SDL_AudioStream *next_binding; + SDL_AudioStream *prev_binding; +}; + +/* Logical devices are an abstraction in SDL3; you can open the same physical + device multiple times, and each will result in an object with its own set + of bound audio streams, etc, even though internally these are all processed + as a group when mixing the final output for the physical device. */ +struct SDL_LogicalAudioDevice +{ + // the unique instance ID of this device. + SDL_AudioDeviceID instance_id; + + // The physical device associated with this opened device. + SDL_AudioDevice *physical_device; + + // If whole logical device is paused (process no streams bound to this device). + SDL_AtomicInt paused; + + // double-linked list of all audio streams currently bound to this opened device. + SDL_AudioStream *bound_streams; + + // SDL_TRUE if this was opened as a default device. + SDL_bool is_default; + + // double-linked list of opened devices on the same physical device. + SDL_LogicalAudioDevice *next; + SDL_LogicalAudioDevice *prev; +}; + struct SDL_AudioDevice { - /* * * */ - /* Data common to all devices */ - SDL_AudioDeviceID id; + // A mutex for locking access to this struct + SDL_Mutex *lock; - /* The device's current audio specification */ + // human-readable name of the device. ("SoundBlaster Pro 16") + char *name; + + // the unique instance ID of this device. + SDL_AudioDeviceID instance_id; + + // a way for the backend to identify this device _when not opened_ + void *handle; + + // The device's current audio specification SDL_AudioSpec spec; + int buffer_size; - /* The callback's expected audio specification (converted vs device's spec). */ - SDL_AudioSpec callbackspec; + // The device's default audio specification + SDL_AudioSpec default_spec; - /* Stream that converts and resamples. NULL if not needed. */ - SDL_AudioStream *stream; + // Number of sample frames the devices wants per-buffer. + int sample_frames; - /* Current state flags */ - SDL_AtomicInt shutdown; /* true if we are signaling the play thread to end. */ - SDL_AtomicInt enabled; /* true if device is functioning and connected. */ - SDL_AtomicInt paused; + // Value to use for SDL_memset to silence a buffer in this device's format + int silence_value; + + // non-zero if we are signaling the audio thread to end. + SDL_AtomicInt shutdown; + + // non-zero if we want the device to be destroyed (so audio thread knows to do it on termination). + SDL_AtomicInt condemned; + + // non-zero if this was a disconnected default device and we're waiting for its replacement. + SDL_AtomicInt zombie; + + // non-zero if this has a thread running (which might be `thread` or something provided by the backend!) + SDL_AtomicInt thread_alive; + + // SDL_TRUE if this is a capture device instead of an output device SDL_bool iscapture; - /* Scratch buffer used in the bridge between SDL and the user callback. */ + // Scratch buffer used for mixing. Uint8 *work_buffer; - /* Size, in bytes, of work_buffer. */ - Uint32 work_buffer_len; - - /* A mutex for locking the mixing buffers */ - SDL_Mutex *mixer_lock; - - /* A thread to feed the audio device */ + // A thread to feed the audio device SDL_Thread *thread; - SDL_threadID threadid; - /* Queued buffers (if app not using callback). */ - SDL_DataQueue *buffer_queue; + // SDL_TRUE if this physical device is currently opened by the backend. + SDL_bool is_opened; - /* * * */ - /* Data private to this driver */ + // Data private to this driver struct SDL_PrivateAudioData *hidden; - void *handle; + // All logical devices associated with this physical device. + SDL_LogicalAudioDevice *logical_devices; + + // double-linked list of all physical devices. + struct SDL_AudioDevice *prev; + struct SDL_AudioDevice *next; }; typedef struct AudioBootStrap @@ -170,10 +288,10 @@ typedef struct AudioBootStrap const char *name; const char *desc; SDL_bool (*init)(SDL_AudioDriverImpl *impl); - SDL_bool demand_only; /* 1==request explicitly, or it won't be available. */ + SDL_bool demand_only; // if SDL_TRUE: request explicitly, or it won't be available. } AudioBootStrap; -/* Not all of these are available in a given build. Use #ifdefs, etc. */ +// 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; @@ -188,8 +306,8 @@ extern AudioBootStrap HAIKUAUDIO_bootstrap; extern AudioBootStrap COREAUDIO_bootstrap; extern AudioBootStrap DISKAUDIO_bootstrap; extern AudioBootStrap DUMMYAUDIO_bootstrap; -extern AudioBootStrap aaudio_bootstrap; -extern AudioBootStrap openslES_bootstrap; +extern AudioBootStrap AAUDIO_bootstrap; +extern AudioBootStrap openslES_bootstrap; // !!! FIXME: capitalize this to match the others extern AudioBootStrap ANDROIDAUDIO_bootstrap; extern AudioBootStrap PS2AUDIO_bootstrap; extern AudioBootStrap PSPAUDIO_bootstrap; @@ -201,4 +319,4 @@ extern AudioBootStrap QSAAUDIO_bootstrap; extern SDL_AudioDevice *get_audio_dev(SDL_AudioDeviceID id); extern int get_max_num_audio_dev(void); -#endif /* SDL_sysaudio_h_ */ +#endif // SDL_sysaudio_h_ diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c index 3f442042..27d540c4 100644 --- a/src/audio/SDL_wave.c +++ b/src/audio/SDL_wave.c @@ -1241,7 +1241,7 @@ static int LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) dst = (Sint16 *)src; - /* Work backwards, since we're expanding in-place. SDL_AudioSpec.format will + /* Work backwards, since we're expanding in-place. `format` will * inform the caller about the byte order. */ i = sample_count; @@ -1553,7 +1553,7 @@ static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t len return -2; } - chunk->size = (size_t) SDL_RWread(src, chunk->data, length); + chunk->size = SDL_RWread(src, chunk->data, length); if (chunk->size != length) { /* Expected to be handled by the caller. */ } @@ -1614,16 +1614,20 @@ static int WaveReadFormat(WaveFile *file) return SDL_OutOfMemory(); } - format->formattag = SDL_ReadLE16(fmtsrc); + if (!SDL_ReadU16LE(fmtsrc, &format->formattag) || + !SDL_ReadU16LE(fmtsrc, &format->channels) || + !SDL_ReadU32LE(fmtsrc, &format->frequency) || + !SDL_ReadU32LE(fmtsrc, &format->byterate) || + !SDL_ReadU16LE(fmtsrc, &format->blockalign)) { + return -1; + } format->encoding = format->formattag; - format->channels = SDL_ReadLE16(fmtsrc); - format->frequency = SDL_ReadLE32(fmtsrc); - format->byterate = SDL_ReadLE32(fmtsrc); - format->blockalign = SDL_ReadLE16(fmtsrc); /* This is PCM specific in the first version of the specification. */ if (fmtlen >= 16) { - format->bitspersample = SDL_ReadLE16(fmtsrc); + if (!SDL_ReadU16LE(fmtsrc, &format->bitspersample)) { + return -1; + } } else if (format->encoding == PCM_CODE) { SDL_RWclose(fmtsrc); return SDL_SetError("Missing wBitsPerSample field in WAVE fmt chunk"); @@ -1631,7 +1635,9 @@ static int WaveReadFormat(WaveFile *file) /* The earlier versions also don't have this field. */ if (fmtlen >= 18) { - format->extsize = SDL_ReadLE16(fmtsrc); + if (!SDL_ReadU16LE(fmtsrc, &format->extsize)) { + return -1; + } } if (format->formattag == EXTENSIBLE_CODE) { @@ -1647,10 +1653,11 @@ static int WaveReadFormat(WaveFile *file) return SDL_SetError("Extensible WAVE header too small"); } - format->validsamplebits = SDL_ReadLE16(fmtsrc); + if (!SDL_ReadU16LE(fmtsrc, &format->validsamplebits) || + !SDL_ReadU32LE(fmtsrc, &format->channelmask) || + SDL_RWread(fmtsrc, format->subformat, 16) != 16) { + } format->samplesperblock = format->validsamplebits; - format->channelmask = SDL_ReadLE32(fmtsrc); - SDL_RWread(fmtsrc, format->subformat, 16); format->encoding = WaveGetFormatGUIDEncoding(format); } @@ -1667,15 +1674,11 @@ static int WaveCheckFormat(WaveFile *file, size_t datalength) if (format->channels == 0) { return SDL_SetError("Invalid number of channels"); - } else if (format->channels > 255) { - /* Limit given by SDL_AudioSpec.channels. */ - return SDL_SetError("Number of channels exceeds limit of 255"); } if (format->frequency == 0) { return SDL_SetError("Invalid sample rate"); } else if (format->frequency > INT_MAX) { - /* Limit given by SDL_AudioSpec.freq. */ return SDL_SetError("Sample rate exceeds limit of %d", INT_MAX); } @@ -1806,9 +1809,9 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 * if (RIFFchunk.fourcc == RIFF) { Uint32 formtype; /* Read the form type. "WAVE" expected. */ - if (SDL_RWread(src, &formtype, sizeof(Uint32)) != sizeof(Uint32)) { + if (!SDL_ReadU32LE(src, &formtype)) { return SDL_SetError("Could not read RIFF form type"); - } else if (SDL_SwapLE32(formtype) != WAVE) { + } else if (formtype != WAVE) { return SDL_SetError("RIFF form type is not WAVE (not a Waveform file)"); } } else if (RIFFchunk.fourcc == WAVE) { @@ -1895,10 +1898,8 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 * } else { /* Let's use src directly, it's just too convenient. */ Sint64 position = SDL_RWseek(src, chunk->position, SDL_RW_SEEK_SET); - Uint32 samplelength; - if (position == chunk->position && SDL_RWread(src, &samplelength, sizeof(Uint32)) == sizeof(Uint32)) { + if (position == chunk->position && SDL_ReadU32LE(src, &file->fact.samplelength)) { file->fact.status = 1; - file->fact.samplelength = SDL_SwapLE32(samplelength); } else { file->fact.status = -1; } @@ -1941,7 +1942,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 * Uint64 position = (Uint64)chunk->position + chunk->length - 1; if (position > SDL_MAX_SINT64 || SDL_RWseek(src, (Sint64)position, SDL_RW_SEEK_SET) != (Sint64)position) { return SDL_SetError("Could not seek to WAVE chunk data"); - } else if (SDL_RWread(src, &tmp, 1) != 1) { + } else if (!SDL_ReadU8(src, &tmp)) { return SDL_SetError("RIFF size truncates chunk"); } } @@ -2025,13 +2026,12 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 * break; } - /* Setting up the SDL_AudioSpec. All unsupported formats were filtered out + /* Setting up the specs. All unsupported formats were filtered out * by checks earlier in this function. */ - SDL_zerop(spec); spec->freq = format->frequency; spec->channels = (Uint8)format->channels; - spec->samples = 4096; /* Good default buffer size */ + spec->format = 0; switch (format->encoding) { case MS_ADPCM_CODE: @@ -2061,10 +2061,10 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 * return SDL_SetError("Unexpected %u-bit PCM data format", (unsigned int)format->bitspersample); } break; + default: + return SDL_SetError("Unexpected data format"); } - spec->silence = SDL_GetSilenceValueForFormat(spec->format); - /* Report the end position back to the cleanup code. */ if (RIFFlengthknown) { chunk->position = RIFFend; @@ -2075,17 +2075,14 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 * return 0; } -SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) +int SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) { int result = -1; WaveFile file; - SDL_zero(file); - /* Make sure we are passed a valid data source */ if (src == NULL) { - /* Error may come from RWops. */ - goto done; + goto done; /* Error may come from RWops. */ } else if (spec == NULL) { SDL_InvalidParamError("spec"); goto done; @@ -2100,6 +2097,7 @@ SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *s *audio_buf = NULL; *audio_len = 0; + SDL_zero(file); file.riffhint = WaveGetRiffSizeHint(); file.trunchint = WaveGetTruncationHint(); file.facthint = WaveGetFactChunkHint(); @@ -2107,7 +2105,6 @@ SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *s result = WaveLoad(src, &file, spec, audio_buf, audio_len); if (result < 0) { SDL_free(*audio_buf); - spec = NULL; audio_buf = NULL; audio_len = 0; } @@ -2118,14 +2115,15 @@ SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *s } WaveFreeChunkData(&file.chunk); SDL_free(file.decoderdata); - done: if (freesrc && src) { SDL_RWclose(src); } - if (result == 0) { - return spec; - } else { - return NULL; - } + return result; } + +int SDL_LoadWAV(const char *path, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) +{ + return SDL_LoadWAV_RW(SDL_RWFromFile(path, "rb"), 1, spec, audio_buf, audio_len); +} + diff --git a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c index 76fe4e71..b843ba6c 100644 --- a/src/audio/aaudio/SDL_aaudio.c +++ b/src/audio/aaudio/SDL_aaudio.c @@ -30,37 +30,37 @@ #include #include +#if __ANDROID_API__ < 31 +#define AAUDIO_FORMAT_PCM_I32 4 +#endif + struct SDL_PrivateAudioData { AAudioStream *stream; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - int frame_size; - - /* Resume device if it was paused automatically */ - int resume; + Uint8 *mixbuf; // Raw mixing buffer + SDL_Semaphore *semaphore; + SDL_AtomicInt error_callback_triggered; + int resume; // Resume device if it was paused automatically }; -/* Debug */ +// Debug #if 0 #define LOGI(...) SDL_Log(__VA_ARGS__); #else #define LOGI(...) #endif +#define LIB_AAUDIO_SO "libaaudio.so" + 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 int aaudio_LoadFunctions(AAUDIO_Data *data) +static int AAUDIO_LoadFunctions(AAUDIO_Data *data) { #define SDL_PROC(ret, func, params) \ do { \ @@ -70,23 +70,95 @@ static int aaudio_LoadFunctions(AAUDIO_Data *data) } \ } 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) + +static void AAUDIO_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error) { - LOGI("SDL aaudio_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error)); + LOGI("SDL AAUDIO_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error)); + + // You MUST NOT close the audio stream from this callback, so we cannot call SDL_AudioDeviceDisconnected here. + // Just flag the device so we can kill it in WaitDevice/PlayDevice instead. + SDL_AudioDevice *device = (SDL_AudioDevice *) userData; + SDL_AtomicSet(&device->hidden->error_callback_triggered, 1); + SDL_PostSemaphore(device->hidden->semaphore); // in case we're blocking in WaitDevice. } -#define LIB_AAUDIO_SO "libaaudio.so" - -static int aaudio_OpenDevice(SDL_AudioDevice *_this, const char *devname) +// due to the way the aaudio data callback works, PlayDevice is a no-op. The callback collects audio while SDL camps in WaitDevice and +// fires a semaphore that will unblock WaitDevice and start a new iteration, so when the callback runs again, WaitDevice is ready +// to hand it more data. +static aaudio_data_callback_result_t AAUDIO_dataCallback(AAudioStream *stream, void *userData, void *audioData, int32_t numFrames) { - struct SDL_PrivateAudioData *private; - SDL_bool iscapture = _this->iscapture; + SDL_AudioDevice *device = (SDL_AudioDevice *) userData; + SDL_assert(numFrames == device->sample_frames); + if (device->iscapture) { + SDL_memcpy(device->hidden->mixbuf, audioData, device->buffer_size); + } else { + SDL_memcpy(audioData, device->hidden->mixbuf, device->buffer_size); + } + SDL_PostSemaphore(device->hidden->semaphore); + return AAUDIO_CALLBACK_RESULT_CONTINUE; +} + +static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize) +{ + return device->hidden->mixbuf; +} + +static void AAUDIO_WaitDevice(SDL_AudioDevice *device) +{ + SDL_WaitSemaphore(device->hidden->semaphore); +} + +static void AAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) +{ + // AAUDIO_dataCallback picks up our work and unblocks AAUDIO_WaitDevice. But make sure we didn't fail here. + if (SDL_AtomicGet(&device->hidden->error_callback_triggered)) { + SDL_AtomicSet(&device->hidden->error_callback_triggered, 0); + SDL_AudioDeviceDisconnected(device); + } +} + +// no need for a FlushCapture implementation, just don't read mixbuf until the next iteration. +static int AAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ + const int cpy = SDL_min(buflen, device->buffer_size); + SDL_memcpy(buffer, device->hidden->mixbuf, cpy); + return cpy; +} + +static void AAUDIO_CloseDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + LOGI(__func__); + + if (hidden) { + if (hidden->stream) { + ctx.AAudioStream_requestStop(hidden->stream); + // !!! FIXME: do we have to wait for the state to change to make sure all buffered audio has played, or will close do this (or will the system do this after the close)? + // !!! FIXME: also, will this definitely wait for a running data callback to finish, and then stop the callback from firing again? + ctx.AAudioStream_close(hidden->stream); + } + + if (hidden->semaphore) { + SDL_DestroySemaphore(hidden->semaphore); + } + + SDL_free(hidden->mixbuf); + SDL_free(hidden); + device->hidden = NULL; + } +} + +static int AAUDIO_OpenDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden; + const SDL_bool iscapture = device->iscapture; aaudio_result_t res; + + SDL_assert(device->handle != NULL); // AAUDIO_UNSPECIFIED is zero, so legit devices should all be non-zero. + LOGI(__func__); if (iscapture) { @@ -96,75 +168,111 @@ static int aaudio_OpenDevice(SDL_AudioDevice *_this, const char *devname) } } - _this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + hidden = device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (hidden == NULL) { return SDL_OutOfMemory(); } - private = _this->hidden; - ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, _this->spec.freq); - ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, _this->spec.channels); - if(devname != NULL) { - int aaudio_device_id = SDL_atoi(devname); - LOGI("Opening device id %d", aaudio_device_id); - ctx.AAudioStreamBuilder_setDeviceId(ctx.builder, aaudio_device_id); - } - { - aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT); - ctx.AAudioStreamBuilder_setDirection(ctx.builder, direction); - } - { - aaudio_format_t format = AAUDIO_FORMAT_PCM_FLOAT; - if (_this->spec.format == SDL_AUDIO_S16SYS) { - format = AAUDIO_FORMAT_PCM_I16; - } else if (_this->spec.format == SDL_AUDIO_S16SYS) { - format = AAUDIO_FORMAT_PCM_FLOAT; - } - ctx.AAudioStreamBuilder_setFormat(ctx.builder, format); + SDL_AtomicSet(&hidden->error_callback_triggered, 0); + + AAudioStreamBuilder *builder = NULL; + res = ctx.AAudio_createStreamBuilder(&builder); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudio_createStreamBuilder %d", res); + return SDL_SetError("SDL Failed AAudio_createStreamBuilder %d", res); + } else if (builder == NULL) { + LOGI("SDL Failed AAudio_createStreamBuilder - builder NULL"); + return SDL_SetError("SDL Failed AAudio_createStreamBuilder - builder NULL"); } - ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private); + // !!! FIXME: call AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); ? + + ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq); + ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels); + + const int aaudio_device_id = (int) ((size_t) device->handle); + LOGI("Opening device id %d", aaudio_device_id); + ctx.AAudioStreamBuilder_setDeviceId(builder, aaudio_device_id); + + const aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT); + ctx.AAudioStreamBuilder_setDirection(builder, direction); + aaudio_format_t format; + if ((device->spec.format == SDL_AUDIO_S32SYS) && (SDL_GetAndroidSDKVersion() >= 31)) { + format = AAUDIO_FORMAT_PCM_I32; + } else if (device->spec.format == SDL_AUDIO_F32SYS) { + format = AAUDIO_FORMAT_PCM_FLOAT; + } else { + format = AAUDIO_FORMAT_PCM_I16; // sint16 is a safe bet for everything else. + } + + ctx.AAudioStreamBuilder_setFormat(builder, format); + ctx.AAudioStreamBuilder_setErrorCallback(builder, AAUDIO_errorCallback, device); + ctx.AAudioStreamBuilder_setDataCallback(builder, AAUDIO_dataCallback, device); + ctx.AAudioStreamBuilder_setPerformanceMode(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); + device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format), + device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames); + + res = ctx.AAudioStreamBuilder_openStream(builder, &hidden->stream); - res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &private->stream); if (res != AAUDIO_OK) { LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res); + ctx.AAudioStreamBuilder_delete(builder); 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 = SDL_AUDIO_S16SYS; - } else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) { - _this->spec.format = SDL_AUDIO_F32SYS; + device->sample_frames = (int) ctx.AAudioStream_getFramesPerDataCallback(hidden->stream); + if (device->sample_frames == AAUDIO_UNSPECIFIED) { + // if this happens, figure out a reasonable sample frame count, tear down this stream and force it in a new stream. + device->sample_frames = (int) (ctx.AAudioStream_getBufferCapacityInFrames(hidden->stream) / 4); + LOGI("AAUDIO: Got a stream with unspecified sample frames per data callback! Retrying with %d frames...", device->sample_frames); + ctx.AAudioStream_close(hidden->stream); + ctx.AAudioStreamBuilder_setFramesPerDataCallback(builder, device->sample_frames); + res = ctx.AAudioStreamBuilder_openStream(builder, &hidden->stream); + if (res != AAUDIO_OK) { // oh well, we tried. + LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res); + ctx.AAudioStreamBuilder_delete(builder); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); } } - 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); + ctx.AAudioStreamBuilder_delete(builder); - SDL_CalculateAudioSpec(&_this->spec); + device->spec.freq = ctx.AAudioStream_getSampleRate(hidden->stream); + device->spec.channels = ctx.AAudioStream_getChannelCount(hidden->stream); - /* Allocate mixing buffer */ - if (!iscapture) { - private->mixlen = _this->spec.size; - private->mixbuf = (Uint8 *)SDL_malloc(private->mixlen); - if (private->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(private->mixbuf, _this->spec.silence, _this->spec.size); + format = ctx.AAudioStream_getFormat(hidden->stream); + if (format == AAUDIO_FORMAT_PCM_I16) { + device->spec.format = SDL_AUDIO_S16SYS; + } else if (format == AAUDIO_FORMAT_PCM_I32) { + device->spec.format = SDL_AUDIO_S32SYS; + } else if (format == AAUDIO_FORMAT_PCM_FLOAT) { + device->spec.format = SDL_AUDIO_F32SYS; + } else { + return SDL_SetError("Got unexpected audio format %d from AAudioStream_getFormat", (int) format); } - private->frame_size = _this->spec.channels * (SDL_AUDIO_BITSIZE(_this->spec.format) / 8); + LOGI("AAudio Actually opened %u hz %u bit chan %u %s samples %u", + device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format), + device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames); - res = ctx.AAudioStream_requestStart(private->stream); + SDL_UpdatedAudioDeviceFormat(device); + + // Allocate mixing buffer + hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(hidden->mixbuf, device->silence_value, device->buffer_size); + + hidden->semaphore = SDL_CreateSemaphore(0); + if (!hidden->semaphore) { + LOGI("SDL Failed SDL_CreateSemaphore %s iscapture:%d", SDL_GetError(), iscapture); + return -1; + } + + 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)); @@ -174,98 +282,114 @@ static int aaudio_OpenDevice(SDL_AudioDevice *_this, const char *devname) return 0; } -static void aaudio_CloseDevice(SDL_AudioDevice *_this) +static SDL_bool PauseOneDevice(SDL_AudioDevice *device, void *userdata) { - 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; - } - } - - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden); -} - -static Uint8 *aaudio_GetDeviceBuf(SDL_AudioDevice *_this) -{ - struct SDL_PrivateAudioData *private = _this->hidden; - return private->mixbuf; -} - -static void aaudio_PlayDevice(SDL_AudioDevice *_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)); - } 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(SDL_AudioDevice *_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) { + struct SDL_PrivateAudioData *hidden = (struct SDL_PrivateAudioData *)device->hidden; + if (hidden != NULL) { + if (hidden->stream) { aaudio_result_t res; - res = ctx.AAudioStreamBuilder_delete(ctx.builder); + + if (device->iscapture) { + // Pause() isn't implemented for 'capture', use Stop() + res = ctx.AAudioStream_requestStop(hidden->stream); + } else { + res = ctx.AAudioStream_requestPause(hidden->stream); + } + if (res != AAUDIO_OK) { - SDL_SetError("Failed AAudioStreamBuilder_delete %s", ctx.AAudio_convertResultToText(res)); + LOGI("SDL Failed AAudioStream_requestPause %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + + SDL_LockMutex(device->lock); + hidden->resume = SDL_TRUE; + } + } + return SDL_FALSE; // keep enumerating. +} + +// Pause (block) all non already paused audio devices by taking their mixer lock +void AAUDIO_PauseDevices(void) +{ + if (ctx.handle != NULL) { // AAUDIO driver is used? + (void) SDL_FindPhysicalAudioDeviceByCallback(PauseOneDevice, NULL); + } +} + +// Resume (unblock) all non already paused audio devices by releasing their mixer lock +static SDL_bool ResumeOneDevice(SDL_AudioDevice *device, void *userdata) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + if (hidden != NULL) { + if (hidden->resume) { + hidden->resume = SDL_FALSE; + SDL_UnlockMutex(device->lock); + } + + if (hidden->stream) { + aaudio_result_t res = ctx.AAudioStream_requestStart(hidden->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); } } + } + return SDL_FALSE; // keep enumerating. +} + +void AAUDIO_ResumeDevices(void) +{ + if (ctx.handle != NULL) { // AAUDIO driver is used? + (void) SDL_FindPhysicalAudioDeviceByCallback(ResumeOneDevice, NULL); + } +} + +// !!! FIXME: do we need this now that we use the callback? +/* + 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 +*/ +static SDL_bool DetectBrokenPlayStatePerDevice(SDL_AudioDevice *device, void *userdata) +{ + SDL_assert(device != NULL); + if (!device->iscapture && device->hidden != NULL) { + struct SDL_PrivateAudioData *hidden = device->hidden; + int64_t framePosition, timeNanoseconds; + aaudio_result_t res = ctx.AAudioStream_getTimestamp(hidden->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds); + if (res == AAUDIO_ERROR_INVALID_STATE) { + aaudio_stream_state_t currentState = ctx.AAudioStream_getState(hidden->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; // this guy. + } + } + } + + return SDL_FALSE; // enumerate more devices. +} + +SDL_bool AAUDIO_DetectBrokenPlayState(void) +{ + return (ctx.handle && SDL_FindPhysicalAudioDeviceByCallback(DetectBrokenPlayStatePerDevice, NULL) != NULL) ? SDL_TRUE : SDL_FALSE; +} + +static void AAUDIO_Deinitialize(void) +{ + Android_StopAudioHotplug(); + + LOGI(__func__); + if (ctx.handle) { SDL_UnloadObject(ctx.handle); } - ctx.handle = NULL; - ctx.builder = NULL; + SDL_zero(ctx); LOGI("End AAUDIO %s", SDL_GetError()); } -static SDL_bool aaudio_Init(SDL_AudioDriverImpl *impl) + +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, @@ -282,241 +406,34 @@ static SDL_bool aaudio_Init(SDL_AudioDriverImpl *impl) ctx.handle = SDL_LoadObject(LIB_AAUDIO_SO); if (ctx.handle == NULL) { 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 == NULL) { - 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) -{ - int i; - - /* AAUDIO driver is not used */ - if (ctx.handle == NULL) { - return; - } - - for (i = 0; i < get_max_num_audio_dev(); i++) { - SDL_AudioDevice *_this = get_audio_dev(i); - SDL_AudioDevice *audioDevice = NULL; - SDL_AudioDevice *captureDevice = NULL; - - if (_this == NULL) { - continue; - } - - if (_this->iscapture) { - captureDevice = _this; - } else { - audioDevice = _this; - } - - if (audioDevice != NULL && audioDevice->hidden != NULL) { - struct SDL_PrivateAudioData *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 (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 (captureDevice != NULL && captureDevice->hidden != NULL) { - struct SDL_PrivateAudioData *private = (struct SDL_PrivateAudioData *)audioDevice->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)); - } - } - - 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; - } - } - - } -} - -/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ -void aaudio_ResumeDevices(void) -{ - int i; - - /* AAUDIO driver is not used */ - if (ctx.handle == NULL) { - return; - } - - for (i = 0; i < get_max_num_audio_dev(); i++) { - SDL_AudioDevice *_this = get_audio_dev(i); - SDL_AudioDevice *audioDevice = NULL; - SDL_AudioDevice *captureDevice = NULL; - - if (_this == NULL) { - continue; - } - - if (_this->iscapture) { - captureDevice = _this; - } else { - audioDevice = _this; - } - - if (audioDevice != NULL && audioDevice->hidden != NULL) { - struct SDL_PrivateAudioData *private = audioDevice->hidden; - - if (private->resume) { - SDL_AtomicSet(&audioDevice->paused, 0); - private->resume = SDL_FALSE; - SDL_UnlockMutex(audioDevice->mixer_lock); - } - - 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)); - } - } - } - - if (captureDevice != NULL && captureDevice->hidden != NULL) { - struct SDL_PrivateAudioData *private = audioDevice->hidden; - - if (private->resume) { - SDL_AtomicSet(&captureDevice->paused, 0); - private->resume = SDL_FALSE; - SDL_UnlockMutex(captureDevice->mixer_lock); - } - - 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)); - } - } - } - } -} - -/* - 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) -{ - int i; - - /* AAUDIO driver is not used */ - if (ctx.handle == NULL) { return SDL_FALSE; } - for (i = 0; i < get_max_num_audio_dev(); i++) { - SDL_AudioDevice *_this = get_audio_dev(i); - SDL_AudioDevice *audioDevice = NULL; - SDL_AudioDevice *captureDevice = NULL; - - if (_this == NULL) { - continue; - } - - if (_this->iscapture) { - captureDevice = _this; - } else { - audioDevice = _this; - } - - if (audioDevice != NULL && audioDevice->hidden != NULL) { - struct SDL_PrivateAudioData *private = audioDevice->hidden; - int64_t framePosition, timeNanoseconds; - - aaudio_result_t res = ctx.AAudioStream_getTimestamp(private->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds); - if (res == AAUDIO_ERROR_INVALID_STATE) { - aaudio_stream_state_t currentState = ctx.AAudioStream_getState(private->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; - } - } - - } - - (void) captureDevice; + if (AAUDIO_LoadFunctions(&ctx) < 0) { + SDL_UnloadObject(ctx.handle); + SDL_zero(ctx); + return SDL_FALSE; } - return SDL_FALSE; + impl->ThreadInit = Android_AudioThreadInit; + impl->DetectDevices = Android_StartAudioHotplug; + impl->Deinitialize = AAUDIO_Deinitialize; + impl->OpenDevice = AAUDIO_OpenDevice; + impl->CloseDevice = AAUDIO_CloseDevice; + impl->WaitDevice = AAUDIO_WaitDevice; + impl->PlayDevice = AAUDIO_PlayDevice; + impl->GetDeviceBuf = AAUDIO_GetDeviceBuf; + impl->WaitCaptureDevice = AAUDIO_WaitDevice; + impl->CaptureFromDevice = AAUDIO_CaptureFromDevice; + + impl->HasCaptureSupport = SDL_TRUE; + + LOGI("SDL AAUDIO_Init OK"); + return SDL_TRUE; } -#endif /* SDL_AUDIO_DRIVER_AAUDIO */ +AudioBootStrap AAUDIO_bootstrap = { + "AAudio", "AAudio audio driver", AAUDIO_Init, SDL_FALSE +}; + +#endif // SDL_AUDIO_DRIVER_AAUDIO diff --git a/src/audio/aaudio/SDL_aaudio.h b/src/audio/aaudio/SDL_aaudio.h index 6b20bce9..137dd815 100644 --- a/src/audio/aaudio/SDL_aaudio.h +++ b/src/audio/aaudio/SDL_aaudio.h @@ -25,15 +25,15 @@ #ifdef SDL_AUDIO_DRIVER_AAUDIO -void aaudio_ResumeDevices(void); -void aaudio_PauseDevices(void); -SDL_bool aaudio_DetectBrokenPlayState(void); +void AAUDIO_ResumeDevices(void); +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; } +#define AAUDIO_ResumeDevices() +#define AAUDIO_PauseDevices() +#define AAUDIO_DetectBrokenPlayState() (SDL_FALSE) #endif diff --git a/src/audio/aaudio/SDL_aaudiofuncs.h b/src/audio/aaudio/SDL_aaudiofuncs.h index 3f0749ca..febbb89d 100644 --- a/src/audio/aaudio/SDL_aaudiofuncs.h +++ b/src/audio/aaudio/SDL_aaudiofuncs.h @@ -32,15 +32,15 @@ SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aa 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_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) +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_setDataCallback, (AAudioStreamBuilder * builder, AAudioStream_dataCallback callback, void *userData)) +SDL_PROC(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)) @@ -52,14 +52,14 @@ SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_requestFlush, (AAudioStream * stre 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_read, (AAudioStream * stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds)) +SDL_PROC_UNUSED(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_getBufferCapacityInFrames, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream * stream)) +SDL_PROC_UNUSED(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)) @@ -77,3 +77,6 @@ SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStrea 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 */ + +#undef SDL_PROC +#undef SDL_PROC_UNUSED diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 7699c5d8..66a3b3b0 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -20,6 +20,8 @@ */ #include "SDL_internal.h" +// !!! FIXME: Clean out the fprintf and printf calls, replace with SDL_Log + #ifdef SDL_AUDIO_DRIVER_ALSA #ifndef SDL_ALSA_NON_BLOCKING @@ -45,6 +47,7 @@ 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 int (*ALSA_snd_pcm_start)(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); @@ -115,6 +118,7 @@ static int load_alsa_syms(void) { SDL_ALSA_SYM(snd_pcm_open); SDL_ALSA_SYM(snd_pcm_close); + SDL_ALSA_SYM(snd_pcm_start); SDL_ALSA_SYM(snd_pcm_writei); SDL_ALSA_SYM(snd_pcm_readi); SDL_ALSA_SYM(snd_pcm_recover); @@ -203,48 +207,21 @@ static int LoadALSALibrary(void) static const char *get_audio_device(void *handle, const int channels) { - const char *device; + SDL_assert(handle != NULL); // SDL2 used NULL to mean "default" but that's not true in SDL3. - if (handle != NULL) { - 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 != NULL) { - 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(SDL_AudioDevice *_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! */ + if (SDL_strcmp((const char *) handle, "default") == 0) { + const char *device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ + if (device != NULL) { + return device; + } else if (channels == 6) { + return "plug:surround51"; + } else if (channels == 4) { + return "plug:surround40"; } + return "default"; } -#endif + + return (const char *)handle; } /* !!! FIXME: is there a channel swizzler in alsalib instead? */ @@ -311,15 +288,15 @@ CHANNEL_SWIZZLE(SWIZ8) #undef SWIZ8 /* - * Called right before feeding _this->hidden->mixbuf to the hardware. Swizzle + * Called right before feeding device->hidden->mixbuf to the hardware. Swizzle * channels from Windows/Mac order to the format alsalib will want. */ -static void swizzle_alsa_channels(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen) +static void swizzle_alsa_channels(SDL_AudioDevice *device, void *buffer, Uint32 bufferlen) { - switch (_this->spec.channels) { + switch (device->spec.channels) { #define CHANSWIZ(chans) \ case chans: \ - switch ((_this->spec.format & (0xFF))) { \ + switch ((device->spec.format & (0xFF))) { \ case 8: \ swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \ break; \ @@ -348,22 +325,44 @@ static void swizzle_alsa_channels(SDL_AudioDevice *_this, void *buffer, Uint32 b #ifdef SND_CHMAP_API_VERSION /* Some devices have the right channel map, no swizzling necessary */ -static void no_swizzle(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen) +static void no_swizzle(SDL_AudioDevice *device, void *buffer, Uint32 bufferlen) { } #endif /* SND_CHMAP_API_VERSION */ -static void ALSA_PlayDevice(SDL_AudioDevice *_this) +/* This function waits until it is possible to write a full sound buffer */ +static void ALSA_WaitDevice(SDL_AudioDevice *device) { - 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); + const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)device->sample_frames; + while (!SDL_AtomicGet(&device->shutdown)) { + const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(device->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_AudioDeviceDisconnected(device); + return; + } else if (rc < needed) { + const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / device->spec.freq; + SDL_Delay(SDL_max(delay, 10)); + } else { + break; /* ready to go! */ + } + } +} - _this->hidden->swizzle_func(_this, _this->hidden->mixbuf, frames_left); +static void ALSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) +{ + SDL_assert(buffer == device->hidden->mixbuf); + Uint8 *sample_buf = device->hidden->mixbuf; + const int frame_size = ((SDL_AUDIO_BITSIZE(device->spec.format)) / 8) * + device->spec.channels; + snd_pcm_uframes_t frames_left = (snd_pcm_uframes_t) (buflen / frame_size); - while (frames_left > 0 && SDL_AtomicGet(&_this->enabled)) { - int status = ALSA_snd_pcm_writei(_this->hidden->pcm_handle, + device->hidden->swizzle_func(device, sample_buf, frames_left); + + while ((frames_left > 0) && !SDL_AtomicGet(&device->shutdown)) { + int status = ALSA_snd_pcm_writei(device->hidden->pcm_handle, sample_buf, frames_left); if (status < 0) { @@ -373,21 +372,20 @@ static void ALSA_PlayDevice(SDL_AudioDevice *_this) SDL_Delay(1); continue; } - status = ALSA_snd_pcm_recover(_this->hidden->pcm_handle, status, 0); + status = ALSA_snd_pcm_recover(device->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 write failed (unrecoverable): %s", ALSA_snd_strerror(status)); - SDL_OpenedAudioDeviceDisconnected(_this); + SDL_AudioDeviceDisconnected(device); 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); + SDL_Delay((frames_left / 2 * 1000) / device->spec.freq); } sample_buf += status * frame_size; @@ -395,34 +393,30 @@ static void ALSA_PlayDevice(SDL_AudioDevice *_this) } } -static Uint8 *ALSA_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *ALSA_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + return device->hidden->mixbuf; } -static int ALSA_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int ALSA_CaptureFromDevice(SDL_AudioDevice *device, 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 frame_size = ((SDL_AUDIO_BITSIZE(device->spec.format)) / 8) * + device->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); + while ((frames_left > 0) && !SDL_AtomicGet(&device->shutdown)) { + int status = ALSA_snd_pcm_readi(device->hidden->pcm_handle, + sample_buf, frames_left); if (status == -EAGAIN) { - ALSA_snd_pcm_wait(_this->hidden->pcm_handle, wait_time); - status = 0; + break; // Can this even happen? Go back to WaitCaptureDevice, where the device lock isn't held. } else if (status < 0) { /*printf("ALSA: capture error %d\n", status);*/ - status = ALSA_snd_pcm_recover(_this->hidden->pcm_handle, status, 0); + status = ALSA_snd_pcm_recover(device->hidden->pcm_handle, status, 0); if (status < 0) { /* Hmm, not much we can do - abort */ SDL_LogError(SDL_LOG_CATEGORY_AUDIO, @@ -430,7 +424,7 @@ static int ALSA_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int bufl ALSA_snd_strerror(status)); return -1; } - continue; + break; // Go back to WaitCaptureDevice, where the device lock isn't held. } /*printf("ALSA: captured %d bytes\n", status * frame_size);*/ @@ -438,32 +432,32 @@ static int ALSA_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int bufl frames_left -= status; } - _this->hidden->swizzle_func(_this, buffer, total_frames - frames_left); + device->hidden->swizzle_func(device, buffer, total_frames - frames_left); return (total_frames - frames_left) * frame_size; } -static void ALSA_FlushCapture(SDL_AudioDevice *_this) +static void ALSA_FlushCapture(SDL_AudioDevice *device) { - ALSA_snd_pcm_reset(_this->hidden->pcm_handle); + ALSA_snd_pcm_reset(device->hidden->pcm_handle); } -static void ALSA_CloseDevice(SDL_AudioDevice *_this) +static void ALSA_CloseDevice(SDL_AudioDevice *device) { - 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); + if (device->hidden) { + if (device->hidden->pcm_handle) { + /* Wait for the submitted audio to drain + ALSA_snd_pcm_drop() can hang, so don't use that. + */ + SDL_Delay(((device->sample_frames * 1000) / device->spec.freq) * 2); + ALSA_snd_pcm_close(device->hidden->pcm_handle); + } + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); } - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden); } -static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *params) +static int ALSA_set_buffer_size(SDL_AudioDevice *device, snd_pcm_hw_params_t *params) { int status; snd_pcm_hw_params_t *hwparams; @@ -475,9 +469,9 @@ static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *par ALSA_snd_pcm_hw_params_copy(hwparams, params); /* Attempt to match the period size to the requested buffer size */ - persize = _this->spec.samples; + persize = device->sample_frames; status = ALSA_snd_pcm_hw_params_set_period_size_near( - _this->hidden->pcm_handle, hwparams, &persize, NULL); + device->hidden->pcm_handle, hwparams, &persize, NULL); if (status < 0) { return -1; } @@ -485,24 +479,24 @@ static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *par /* Need to at least double buffer */ periods = 2; status = ALSA_snd_pcm_hw_params_set_periods_min( - _this->hidden->pcm_handle, hwparams, &periods, NULL); + device->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); + device->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); + status = ALSA_snd_pcm_hw_params(device->hidden->pcm_handle, hwparams); if (status < 0) { return -1; } - _this->spec.samples = persize; + device->sample_frames = persize; /* This is useful for debugging */ if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) { @@ -518,34 +512,22 @@ static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *par return 0; } -static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int ALSA_OpenDevice(SDL_AudioDevice *device) { + const SDL_bool iscapture = device->iscapture; 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; - const SDL_AudioFormat *closefmts; - 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 == NULL) { + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); /* Open the audio device */ /* Name of device should depend on # channels in spec */ + snd_pcm_t *pcm_handle = NULL; status = ALSA_snd_pcm_open(&pcm_handle, - get_audio_device(_this->handle, _this->spec.channels), + get_audio_device(device->handle, device->spec.channels), iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); @@ -553,9 +535,10 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status)); } - _this->hidden->pcm_handle = pcm_handle; + device->hidden->pcm_handle = pcm_handle; /* Figure out what the hardware is capable of */ + snd_pcm_hw_params_t *hwparams = NULL; snd_pcm_hw_params_alloca(&hwparams); status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams); if (status < 0) { @@ -570,7 +553,9 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) } /* Try for a closest match on audio format */ - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + snd_pcm_format_t format = 0; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); + SDL_AudioFormat test_format; while ((test_format = *(closefmts++)) != 0) { switch (test_format) { case SDL_AUDIO_U8: @@ -605,21 +590,22 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) } } if (!test_format) { - return SDL_SetError("%s: Unsupported audio format", "alsa"); + return SDL_SetError("ALSA: Unsupported audio format"); } - _this->spec.format = test_format; + device->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; + device->hidden->swizzle_func = swizzle_alsa_channels; #ifdef SND_CHMAP_API_VERSION - chmap = ALSA_snd_pcm_get_chmap(pcm_handle); + snd_pcm_chmap_t *chmap = ALSA_snd_pcm_get_chmap(pcm_handle); if (chmap) { + char chmap_str[64]; 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; + device->hidden->swizzle_func = no_swizzle; } } free(chmap); /* This should NOT be SDL_free() */ @@ -628,38 +614,39 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) /* Set the number of channels */ status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams, - _this->spec.channels); - channels = _this->spec.channels; + device->spec.channels); + unsigned int channels = device->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; + device->spec.channels = channels; } /* Set the audio rate */ - rate = _this->spec.freq; + unsigned int rate = device->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; + device->spec.freq = rate; /* Set the buffer size, in samples */ - status = ALSA_set_buffer_size(_this, hwparams); + status = ALSA_set_buffer_size(device, 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_t *swparams = NULL; 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); + status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, device->sample_frames); if (status < 0) { return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status)); } @@ -673,17 +660,16 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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); + // Calculate the final parameters for this audio specification + SDL_UpdatedAudioDeviceFormat(device); - /* Allocate mixing buffer */ + // 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) { + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (device->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->hidden->mixlen); + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); } #if !SDL_ALSA_NON_BLOCKING @@ -692,6 +678,8 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) } #endif + ALSA_snd_pcm_start(pcm_handle); + /* We're ready to rock and roll. :-) */ return 0; } @@ -703,7 +691,7 @@ typedef struct ALSA_Device struct ALSA_Device *next; } ALSA_Device; -static void add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen) +static void add_device(const SDL_bool iscapture, const char *name, void *hint, ALSA_Device **pSeen) { ALSA_Device *dev = SDL_malloc(sizeof(ALSA_Device)); char *desc; @@ -765,21 +753,17 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D static ALSA_Device *hotplug_devices = NULL; -static void ALSA_HotplugIteration(void) +static void ALSA_HotplugIteration(SDL_bool *has_default_output, SDL_bool *has_default_capture) { void **hints = NULL; - ALSA_Device *dev; - ALSA_Device *unseen; - ALSA_Device *seen; - ALSA_Device *next; - ALSA_Device *prev; + ALSA_Device *unseen = NULL; + ALSA_Device *seen = NULL; if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == 0) { - int i, j; const char *match = NULL; int bestmatch = 0xFFFF; + int has_default = -1; size_t match_len = 0; - int defaultdev = -1; static const char *const prefixes[] = { "hw:", "sysdefault:", "default:", NULL }; @@ -791,92 +775,100 @@ static void ALSA_HotplugIteration(void) 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++) { + for (int i = 0; hints[i]; i++) { char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); if (name == NULL) { 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; + if (SDL_strcmp(name, "default") == 0) { + if (has_default < 0) { + has_default = i; + } + } else { + for (int 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); /* This should NOT be SDL_free() */ + free(name); /* This should NOT be SDL_free() */ + } } /* 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 == NULL) && (defaultdev != i)) { - continue; /* ...skip anything that isn't the default device. */ - } - - name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); - if (name == NULL) { - continue; - } - - /* only want physical hardware interfaces */ - if (match == NULL || (SDL_strncmp(name, match, match_len) == 0)) { - char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID"); - const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0); - const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0); - SDL_bool have_output = SDL_FALSE; - SDL_bool have_input = SDL_FALSE; - - free(ioid); /* This should NOT be SDL_free() */ - - if (!isoutput && !isinput) { - free(name); /* This should NOT be SDL_free() */ + if (match || (has_default >= 0)) { // did we find a device name prefix we like at all...? + for (int i = 0; hints[i]; i++) { + char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); + if (name == NULL) { 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; + // only want physical hardware interfaces + const SDL_bool is_default = (has_default == i) ? SDL_TRUE : SDL_FALSE; + if (is_default || (match != NULL && SDL_strncmp(name, match, match_len) == 0)) { + char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID"); + const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0); + const SDL_bool isinput = (ioid == NULL) || (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; + } + + if (is_default) { + if (has_default_output && isoutput) { + *has_default_output = SDL_TRUE; + } else if (has_default_capture && isinput) { + *has_default_capture = SDL_TRUE; + } + free(name); + continue; + } + + ALSA_Device *prev = NULL; + ALSA_Device *next; + for (ALSA_Device *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 { - unseen = next; + prev = dev; } - 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); } } - 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); /* This should NOT be SDL_free() */ } - - free(name); /* This should NOT be SDL_free() */ } ALSA_snd_device_name_free_hint(hints); @@ -884,10 +876,11 @@ static void ALSA_HotplugIteration(void) 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) { + ALSA_Device *next = NULL; + for (ALSA_Device *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_AudioDeviceDisconnected(SDL_FindPhysicalAudioDeviceByHandle(dev->name)); SDL_free(dev->name); SDL_free(dev); } @@ -909,16 +902,25 @@ static int SDLCALL ALSA_HotplugThread(void *arg) SDL_Delay(100); } - ALSA_HotplugIteration(); /* run the check. */ + ALSA_HotplugIteration(NULL, NULL); /* run the check. */ } return 0; } #endif -static void ALSA_DetectDevices(void) +static void ALSA_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - ALSA_HotplugIteration(); /* run once now before a thread continues to check. */ + // ALSA doesn't have a concept of a changeable default device, afaik, so we expose a generic default + // device here. It's the best we can do at this level. + SDL_bool has_default_output = SDL_FALSE, has_default_capture = SDL_FALSE; + ALSA_HotplugIteration(&has_default_output, &has_default_capture); // run once now before a thread continues to check. */ + if (has_default_output) { + *default_output = SDL_AddAudioDevice(/*iscapture=*/SDL_FALSE, "ALSA default output device", NULL, SDL_strdup("default")); + } + if (has_default_capture) { + *default_capture = SDL_AddAudioDevice(/*iscapture=*/SDL_TRUE, "ALSA default capture device", NULL, SDL_strdup("default")); + } #if SDL_ALSA_HOTPLUG_THREAD SDL_AtomicSet(&ALSA_hotplug_shutdown, 0); @@ -966,11 +968,11 @@ static SDL_bool ALSA_Init(SDL_AudioDriverImpl *impl) impl->PlayDevice = ALSA_PlayDevice; impl->CloseDevice = ALSA_CloseDevice; impl->Deinitialize = ALSA_Deinitialize; + impl->WaitCaptureDevice = ALSA_WaitDevice; impl->CaptureFromDevice = ALSA_CaptureFromDevice; impl->FlushCapture = ALSA_FlushCapture; impl->HasCaptureSupport = SDL_TRUE; - impl->SupportsNonPow2Samples = SDL_TRUE; return SDL_TRUE; /* this audio target is available. */ } diff --git a/src/audio/alsa/SDL_alsa_audio.h b/src/audio/alsa/SDL_alsa_audio.h index b66318d7..ef7ce1bb 100644 --- a/src/audio/alsa/SDL_alsa_audio.h +++ b/src/audio/alsa/SDL_alsa_audio.h @@ -34,7 +34,6 @@ struct SDL_PrivateAudioData /* Raw mixing buffer */ Uint8 *mixbuf; - int mixlen; /* swizzle function */ void (*swizzle_func)(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen); diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c index 5f666a27..761ec5be 100644 --- a/src/audio/android/SDL_androidaudio.c +++ b/src/audio/android/SDL_androidaudio.c @@ -22,7 +22,7 @@ #ifdef SDL_AUDIO_DRIVER_ANDROID -/* Output audio to Android */ +// Output audio to Android (legacy interface) #include "../SDL_sysaudio.h" #include "../SDL_audio_c.h" @@ -34,185 +34,158 @@ struct SDL_PrivateAudioData { - /* Resume device if it was paused automatically */ - int resume; + int resume; // Resume device if it was paused automatically }; static SDL_AudioDevice *audioDevice = NULL; static SDL_AudioDevice *captureDevice = NULL; - -static int ANDROIDAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int ANDROIDAUDIO_OpenDevice(SDL_AudioDevice *device) { - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; - SDL_bool iscapture = _this->iscapture; + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { + return SDL_OutOfMemory(); + } + + const SDL_bool iscapture = device->iscapture; if (iscapture) { if (captureDevice) { return SDL_SetError("An audio capture device is already opened"); } - } - - if (!iscapture) { + captureDevice = device; + } else { if (audioDevice) { return SDL_SetError("An audio playback device is already opened"); } + audioDevice = device; } - if (iscapture) { - captureDevice = _this; - } else { - audioDevice = _this; - } - - _this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden)); - if (_this->hidden == NULL) { - return SDL_OutOfMemory(); - } - - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { if ((test_format == SDL_AUDIO_U8) || (test_format == SDL_AUDIO_S16) || (test_format == SDL_AUDIO_F32)) { - _this->spec.format = test_format; + device->spec.format = test_format; break; } } if (!test_format) { - /* Didn't find a compatible format :( */ - return SDL_SetError("%s: Unsupported audio format", "android"); + return SDL_SetError("android: Unsupported audio format"); } - { - int audio_device_id = 0; - if (devname != NULL) { - audio_device_id = SDL_atoi(devname); - } - if (Android_JNI_OpenAudioDevice(iscapture, audio_device_id, &_this->spec) < 0) { - return -1; - } + if (Android_JNI_OpenAudioDevice(device) < 0) { + return -1; } - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); return 0; } -static void ANDROIDAUDIO_PlayDevice(SDL_AudioDevice *_this) +// !!! FIXME: this needs a WaitDevice implementation. + +static void ANDROIDAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { Android_JNI_WriteAudioBuffer(); } -static Uint8 *ANDROIDAUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *ANDROIDAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { return Android_JNI_GetAudioBuffer(); } -static int ANDROIDAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int ANDROIDAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { return Android_JNI_CaptureAudioBuffer(buffer, buflen); } -static void ANDROIDAUDIO_FlushCapture(SDL_AudioDevice *_this) +static void ANDROIDAUDIO_FlushCapture(SDL_AudioDevice *device) { Android_JNI_FlushCapturedAudio(); } -static void ANDROIDAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void ANDROIDAUDIO_CloseDevice(SDL_AudioDevice *device) { /* 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 */ - Android_JNI_CloseAudioDevice(_this->iscapture); - if (_this->iscapture) { - SDL_assert(captureDevice == _this); - captureDevice = NULL; - } else { - SDL_assert(audioDevice == _this); - audioDevice = NULL; + if (device->hidden) { + Android_JNI_CloseAudioDevice(device->iscapture); + if (device->iscapture) { + SDL_assert(captureDevice == device); + captureDevice = NULL; + } else { + SDL_assert(audioDevice == device); + audioDevice = NULL; + } + SDL_free(device->hidden); + device->hidden = NULL; + } +} + +// Pause (block) all non already paused audio devices by taking their mixer lock +void ANDROIDAUDIO_PauseDevices(void) +{ + // TODO: Handle multiple devices? + struct SDL_PrivateAudioData *hidden; + if (audioDevice != NULL && audioDevice->hidden != NULL) { + hidden = (struct SDL_PrivateAudioData *)audioDevice->hidden; + SDL_LockMutex(audioDevice->lock); + hidden->resume = SDL_TRUE; + } + + if (captureDevice != NULL && captureDevice->hidden != NULL) { + hidden = (struct SDL_PrivateAudioData *)captureDevice->hidden; + SDL_LockMutex(captureDevice->lock); + hidden->resume = SDL_TRUE; + } +} + +// Resume (unblock) all non already paused audio devices by releasing their mixer lock +void ANDROIDAUDIO_ResumeDevices(void) +{ + // TODO: Handle multiple devices? + struct SDL_PrivateAudioData *hidden; + if (audioDevice != NULL && audioDevice->hidden != NULL) { + hidden = (struct SDL_PrivateAudioData *)audioDevice->hidden; + if (hidden->resume) { + hidden->resume = SDL_FALSE; + SDL_UnlockMutex(audioDevice->lock); + } + } + + if (captureDevice != NULL && captureDevice->hidden != NULL) { + hidden = (struct SDL_PrivateAudioData *)captureDevice->hidden; + if (hidden->resume) { + hidden->resume = SDL_FALSE; + SDL_UnlockMutex(captureDevice->lock); + } } - SDL_free(_this->hidden); } static SDL_bool ANDROIDAUDIO_Init(SDL_AudioDriverImpl *impl) { - /* Set the function pointers */ - impl->DetectDevices = Android_DetectDevices; + // !!! FIXME: if on Android API < 24, DetectDevices and Deinitialize should be NULL and OnlyHasDefaultOutputDevice and OnlyHasDefaultCaptureDevice should be SDL_TRUE, since audio device enum and hotplug appears to require Android 7.0+. + impl->ThreadInit = Android_AudioThreadInit; + impl->DetectDevices = Android_StartAudioHotplug; + impl->Deinitialize = Android_StopAudioHotplug; 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 = SDL_FALSE; - impl->OnlyHasDefaultCaptureDevice = SDL_FALSE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap ANDROIDAUDIO_bootstrap = { "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 (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; - } - } -} - -/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ -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 (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); - } - } -} - -#endif /* SDL_AUDIO_DRIVER_ANDROID */ +#endif // SDL_AUDIO_DRIVER_ANDROID diff --git a/src/audio/coreaudio/SDL_coreaudio.h b/src/audio/coreaudio/SDL_coreaudio.h index 989ed61d..4b7f81bf 100644 --- a/src/audio/coreaudio/SDL_coreaudio.h +++ b/src/audio/coreaudio/SDL_coreaudio.h @@ -53,15 +53,12 @@ struct SDL_PrivateAudioData AudioQueueRef audioQueue; int numAudioBuffers; AudioQueueBufferRef *audioBuffer; - void *buffer; - UInt32 bufferOffset; - UInt32 bufferSize; + AudioQueueBufferRef current_buffer; AudioStreamBasicDescription strdesc; SDL_Semaphore *ready_semaphore; char *thread_error; #ifdef MACOSX_COREAUDIO AudioDeviceID deviceID; - SDL_AtomicInt device_change_flag; #else SDL_bool interrupted; CFTypeRef interruption_listener; diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 08af17c4..b96db86b 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -22,28 +22,24 @@ #ifdef SDL_AUDIO_DRIVER_COREAUDIO -/* !!! FIXME: clean out some of the macro salsa in here. */ - #include "../SDL_audio_c.h" #include "../SDL_sysaudio.h" #include "SDL_coreaudio.h" #include "../../thread/SDL_systhread.h" -#define DEBUG_COREAUDIO 0 +#define DEBUG_COREAUDIO 1 #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; \ - } + #define CHECK_RESULT(msg) \ + if (result != noErr) { \ + SDL_Log("COREAUDIO: Got error %d from '%s'!\n", (int)result, msg); \ + return SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \ + } #else -#define CHECK_RESULT(msg) \ - if (result != noErr) { \ - SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \ - return 0; \ - } + #define CHECK_RESULT(msg) \ + if (result != noErr) { \ + return SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \ + } #endif #ifdef MACOSX_COREAUDIO @@ -53,78 +49,83 @@ static const AudioObjectPropertyAddress devlist_address = { kAudioObjectPropertyElementMain }; -typedef void (*addDevFn)(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data); +static const AudioObjectPropertyAddress default_output_device_address = { + kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain +}; -typedef struct AudioDeviceList +static const AudioObjectPropertyAddress default_input_device_address = { + kAudioHardwarePropertyDefaultInputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain +}; + +static const AudioObjectPropertyAddress alive_address = { + kAudioDevicePropertyDeviceIsAlive, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain +}; + + +static OSStatus DeviceAliveNotification(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) { - AudioDeviceID devid; - SDL_bool alive; - struct AudioDeviceList *next; -} AudioDeviceList; + SDL_AudioDevice *device = (SDL_AudioDevice *)data; + SDL_assert(((AudioObjectID)(size_t)device->handle) == devid); -static AudioDeviceList *output_devs = NULL; -static AudioDeviceList *capture_devs = NULL; + UInt32 alive = 1; + UInt32 size = sizeof(alive); + const OSStatus error = AudioObjectGetPropertyData(devid, addrs, 0, NULL, &size, &alive); -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; + SDL_bool dead = SDL_FALSE; + if (error == kAudioHardwareBadDeviceError) { + dead = SDL_TRUE; /* device was unplugged. */ + } else if ((error == kAudioHardwareNoError) && (!alive)) { + dead = SDL_TRUE; /* device died in some other way. */ } - return SDL_TRUE; + if (dead) { + #if DEBUG_COREAUDIO + SDL_Log("COREAUDIO: device '%s' is lost!", device->name); + #endif + SDL_AudioDeviceDisconnected(device); + } + + return noErr; } -static void addToDevList(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data) +static void COREAUDIO_FreeDeviceHandle(SDL_AudioDevice *device) { - if (add_to_internal_dev_list(iscapture, devId)) { - SDL_AddAudioDevice(iscapture, name, spec, (void *)((size_t)devId)); - } + const AudioDeviceID devid = (AudioDeviceID)(size_t)device->handle; + AudioObjectRemovePropertyListener(devid, &alive_address, DeviceAliveNotification, device); } -static void build_device_list(int iscapture, addDevFn addfn, void *addfndata) +// This only _adds_ new devices. Removal is handled by devices triggering kAudioDevicePropertyDeviceIsAlive property changes. +static void RefreshPhysicalDevices(void) { - OSStatus result = noErr; UInt32 size = 0; AudioDeviceID *devs = NULL; - UInt32 i = 0; - UInt32 max = 0; + SDL_bool isstack; - result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, - &devlist_address, 0, NULL, &size); - if (result != kAudioHardwareNoError) { + if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &devlist_address, 0, NULL, &size) != kAudioHardwareNoError) { + return; + } else if ((devs = (AudioDeviceID *) SDL_small_alloc(Uint8, size, &isstack)) == NULL) { + return; + } else if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &devlist_address, 0, NULL, &size, devs) != kAudioHardwareNoError) { + SDL_small_free(devs, isstack); return; } - devs = (AudioDeviceID *)alloca(size); - if (devs == NULL) { - return; + const UInt32 total_devices = (UInt32) (size / sizeof(AudioDeviceID)); + for (UInt32 i = 0; i < total_devices; i++) { + SDL_AudioDevice *device = SDL_FindPhysicalAudioDeviceByHandle((void *)((size_t)devs[i])); + if (device) { + devs[i] = 0; // The system and SDL both agree it's already here, don't check it again. + } } - 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; + // any non-zero items remaining in `devs` are new devices to be added. + for (int iscapture = 0; iscapture < 2; iscapture++) { const AudioObjectPropertyAddress addr = { kAudioDevicePropertyStreamConfiguration, iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, @@ -141,200 +142,192 @@ static void build_device_list(int iscapture, addDevFn addfn, void *addfndata) 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; + for (UInt32 i = 0; i < total_devices; i++) { + const AudioDeviceID dev = devs[i]; + if (!dev) { + continue; // already added. } - } - SDL_free(buflist); + AudioBufferList *buflist = NULL; + double sampleRate = 0; - 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 = SDL_strlen(ptr); - /* Some devices have whitespace at the end...trim it. */ - while ((len > 0) && (ptr[len - 1] == ' ')) { - len--; + if (AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size) != noErr) { + continue; + } else if ((buflist = (AudioBufferList *)SDL_malloc(size)) == NULL) { + continue; } - usable = (len > 0); - } - if (usable) { - ptr[len] = '\0'; + OSStatus result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, &size, buflist); -#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_AudioSpec spec; + SDL_zero(spec); + if (result == noErr) { + for (Uint32 j = 0; j < buflist->mNumberBuffers; j++) { + spec.channels += buflist->mBuffers[j].mNumberChannels; + } } - 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 + SDL_free(buflist); -static int open_playback_devices; -static int open_capture_devices; -static int num_open_devices; -static SDL_AudioDevice **open_devices; + if (spec.channels == 0) { + continue; + } -#ifndef MACOSX_COREAUDIO + size = sizeof(sampleRate); + if (AudioObjectGetPropertyData(dev, &freqaddr, 0, NULL, &size, &sampleRate) == noErr) { + spec.freq = (int)sampleRate; + } -static BOOL session_active = NO; + CFStringRef cfstr = NULL; + size = sizeof(CFStringRef); + if (AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr) != kAudioHardwareNoError) { + continue; + } -static void pause_audio_devices(void) -{ - int i; + CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8); + char *name = (char *)SDL_malloc(len + 1); + SDL_bool usable = ((name != NULL) && (CFStringGetCString(cfstr, name, len + 1, kCFStringEncodingUTF8))) ? SDL_TRUE : SDL_FALSE; - if (!open_devices) { - return; - } + CFRelease(cfstr); - 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); + if (usable) { + // Some devices have whitespace at the end...trim it. + len = (CFIndex) SDL_strlen(name); + while ((len > 0) && (name[len - 1] == ' ')) { + len--; + } + usable = (len > 0); + } + + if (usable) { + name[len] = '\0'; + + #if DEBUG_COREAUDIO + SDL_Log("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n", + ((iscapture) ? "capture" : "output"), + (int)i, name, (int)dev); + #endif + + devs[i] = 0; // don't bother checking this one on the next iscapture iteration of the loop + + SDL_AudioDevice *device = SDL_AddAudioDevice(iscapture ? SDL_TRUE : SDL_FALSE, name, &spec, (void *)((size_t)dev)); + if (device) { + AudioObjectAddPropertyListener(dev, &alive_address, DeviceAliveNotification, device); + } + } + SDL_free(name); // SDL_AddAudioDevice() would have copied the string. } } + + SDL_small_free(devs, isstack); } -static void resume_audio_devices(void) +// this is called when the system's list of available audio devices changes. +static OSStatus DeviceListChangedNotification(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) { - int i; + RefreshPhysicalDevices(); + return noErr; +} - if (!open_devices) { - return; +static OSStatus DefaultAudioDeviceChangedNotification(AudioObjectID inObjectID, const AudioObjectPropertyAddress *addr) +{ + AudioDeviceID devid; + Uint32 size = sizeof(devid); + if (AudioObjectGetPropertyData(inObjectID, addr, 0, NULL, &size, &devid) == noErr) { + SDL_DefaultAudioDeviceChanged(SDL_FindPhysicalAudioDeviceByHandle((void *)((size_t)devid))); } + return noErr; +} - 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 OSStatus DefaultOutputDeviceChangedNotification(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData) +{ + #if DEBUG_COREAUDIO + SDL_Log("COREAUDIO: default output device changed!"); + #endif + SDL_assert(inNumberAddresses == 1); + return DefaultAudioDeviceChangedNotification(inObjectID, inAddresses); +} + +static OSStatus DefaultInputDeviceChangedNotification(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData) +{ + #if DEBUG_COREAUDIO + SDL_Log("COREAUDIO: default input device changed!"); + #endif + SDL_assert(inNumberAddresses == 1); + return DefaultAudioDeviceChangedNotification(inObjectID, inAddresses); +} + +static void COREAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) +{ + RefreshPhysicalDevices(); + + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, DeviceListChangedNotification, NULL); + + /* Get the Device ID */ + UInt32 size; + AudioDeviceID devid; + + size = sizeof(AudioDeviceID); + if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &default_output_device_address, 0, NULL, &size, &devid) == noErr) { + SDL_AudioDevice *device = SDL_FindPhysicalAudioDeviceByHandle((void *)((size_t)devid)); + if (device) { + *default_output = device; } } + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_output_device_address, DefaultOutputDeviceChangedNotification, NULL); + + size = sizeof(AudioDeviceID); + if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &default_input_device_address, 0, NULL, &size, &devid) == noErr) { + SDL_AudioDevice *device = SDL_FindPhysicalAudioDeviceByHandle((void *)((size_t)devid)); + if (device) { + *default_capture = device; + } + } + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_input_device_address, DefaultInputDeviceChangedNotification, NULL); } -static void interruption_begin(SDL_AudioDevice *_this) +#else // iOS-specific section follows. + +static SDL_bool session_active = SDL_FALSE; + +static SDL_bool PauseOneAudioDevice(SDL_AudioDevice *device, void *userdata) { - if (_this != NULL && _this->hidden->audioQueue != NULL) { - _this->hidden->interrupted = SDL_TRUE; - AudioQueuePause(_this->hidden->audioQueue); + if (device->hidden && device->hidden->audioQueue && !device->hidden->interrupted) { + AudioQueuePause(device->hidden->audioQueue); + } + return SDL_FALSE; // keep enumerating devices until we've paused them all. +} + +static void PauseAudioDevices(void) +{ + (void) SDL_FindPhysicalAudioDeviceByCallback(PauseOneAudioDevice, NULL); +} + +static SDL_bool ResumeOneAudioDevice(SDL_AudioDevice *device, void *userdata) +{ + if (device->hidden && device->hidden->audioQueue && !device->hidden->interrupted) { + AudioQueueStart(device->hidden->audioQueue, NULL); + } + return SDL_FALSE; // keep enumerating devices until we've resumed them all. +} + +static void ResumeAudioDevices(void) +{ + (void) SDL_FindPhysicalAudioDeviceByCallback(ResumeOneAudioDevice, NULL); +} + +static void InterruptionBegin(SDL_AudioDevice *device) +{ + if (device != NULL && device->hidden->audioQueue != NULL) { + device->hidden->interrupted = SDL_TRUE; + AudioQueuePause(device->hidden->audioQueue); } } -static void interruption_end(SDL_AudioDevice *_this) +static void InterruptionEnd(SDL_AudioDevice *device) { - if (_this != NULL && _this->hidden != NULL && _this->hidden->audioQueue != NULL && _this->hidden->interrupted && AudioQueueStart(_this->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) { - _this->hidden->interrupted = SDL_FALSE; + if (device != NULL && device->hidden != NULL && device->hidden->audioQueue != NULL && device->hidden->interrupted && AudioQueueStart(device->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) { + device->hidden->interrupted = SDL_FALSE; } } @@ -351,9 +344,9 @@ static void interruption_end(SDL_AudioDevice *_this) @synchronized(self) { NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey]; if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) { - interruption_begin(self.device); + InterruptionBegin(self.device); } else { - interruption_end(self.device); + InterruptionEnd(self.device); } } } @@ -361,13 +354,32 @@ static void interruption_end(SDL_AudioDevice *_this) - (void)applicationBecameActive:(NSNotification *)note { @synchronized(self) { - interruption_end(self.device); + InterruptionEnd(self.device); } } @end -static BOOL update_audio_session(SDL_AudioDevice *_this, SDL_bool open, SDL_bool allow_playandrecord) +typedef struct +{ + int output; + int capture; +} CountOpenAudioDevicesData; + +static SDL_bool CountOpenAudioDevices(SDL_AudioDevice *device, void *userdata) +{ + CountOpenAudioDevicesData *data = (CountOpenAudioDevicesData *) userdata; + if (device->hidden != NULL) { // assume it's open if hidden != NULL + if (device->iscapture) { + data->capture++; + } else { + data->output++; + } + } + return SDL_FALSE; // keep enumerating until all devices have been checked. +} + +static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_bool allow_playandrecord) { @autoreleasepool { AVAudioSession *session = [AVAudioSession sharedInstance]; @@ -379,6 +391,10 @@ static BOOL update_audio_session(SDL_AudioDevice *_this, SDL_bool open, SDL_bool NSError *err = nil; const char *hint; + CountOpenAudioDevicesData data; + SDL_zero(data); + (void) SDL_FindPhysicalAudioDeviceByCallback(CountOpenAudioDevices, &data); + hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY); if (hint) { if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) { @@ -396,17 +412,17 @@ static BOOL update_audio_session(SDL_AudioDevice *_this, SDL_bool open, SDL_bool category = AVAudioSessionCategoryPlayAndRecord; } } - } else if (open_playback_devices && open_capture_devices) { + } else if (data.output && data.capture) { category = AVAudioSessionCategoryPlayAndRecord; - } else if (open_capture_devices) { + } else if (data.capture) { category = AVAudioSessionCategoryRecord; } -#if !TARGET_OS_TV + #if !TARGET_OS_TV if (category == AVAudioSessionCategoryPlayAndRecord) { options |= AVAudioSessionCategoryOptionDefaultToSpeaker; } -#endif + #endif if (category == AVAudioSessionCategoryRecord || category == AVAudioSessionCategoryPlayAndRecord) { /* AVAudioSessionCategoryOptionAllowBluetooth isn't available in the SDK for @@ -426,53 +442,53 @@ static BOOL update_audio_session(SDL_AudioDevice *_this, SDL_bool open, SDL_bool 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(); + PauseAudioDevices(); [session setActive:NO error:nil]; - session_active = NO; + session_active = SDL_FALSE; 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; + return SDL_FALSE; } } } else { if (![session.category isEqualToString:category]) { /* Stop the current session so we don't interrupt other application audio */ - pause_audio_devices(); + PauseAudioDevices(); [session setActive:NO error:nil]; - session_active = NO; + session_active = SDL_FALSE; if (![session setCategory:category error:&err]) { NSString *desc = err.description; SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String); - return NO; + return SDL_FALSE; } } } - if ((open_playback_devices || open_capture_devices) && !session_active) { + if ((data.output || data.capture) && !session_active) { if (![session setActive:YES error:&err]) { if ([err code] == AVAudioSessionErrorCodeResourceNotAvailable && category == AVAudioSessionCategoryPlayAndRecord) { - return update_audio_session(_this, open, SDL_FALSE); + return UpdateAudioSession(device, open, SDL_FALSE); } NSString *desc = err.description; SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String); - return NO; + return SDL_FALSE; } - session_active = YES; - resume_audio_devices(); - } else if (!open_playback_devices && !open_capture_devices && session_active) { - pause_audio_devices(); + session_active = SDL_TRUE; + ResumeAudioDevices(); + } else if (!data.output && !data.capture && session_active) { + PauseAudioDevices(); [session setActive:NO error:nil]; - session_active = NO; + session_active = SDL_FALSE; } if (open) { SDLInterruptionListener *listener = [SDLInterruptionListener new]; - listener.device = _this; + listener.device = device; [center addObserver:listener selector:@selector(audioSessionInterruption:) @@ -493,10 +509,10 @@ static BOOL update_audio_session(SDL_AudioDevice *_this, SDL_bool open, SDL_bool name:UIApplicationWillEnterForegroundNotification object:nil]; - _this->hidden->interruption_listener = CFBridgingRetain(listener); + device->hidden->interruption_listener = CFBridgingRetain(listener); } else { SDLInterruptionListener *listener = nil; - listener = (SDLInterruptionListener *)CFBridgingRelease(_this->hidden->interruption_listener); + listener = (SDLInterruptionListener *)CFBridgingRelease(device->hidden->interruption_listener); [center removeObserver:listener]; @synchronized(listener) { listener.device = NULL; @@ -504,247 +520,125 @@ static BOOL update_audio_session(SDL_AudioDevice *_this, SDL_bool open, SDL_bool } } - return YES; + return SDL_TRUE; } #endif -/* The AudioQueue callback */ -static void outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) + +static void COREAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { - 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); - } else if (_this->stream) { - UInt32 remaining = inBuffer->mAudioDataBytesCapacity; - Uint8 *ptr = (Uint8 *)inBuffer->mAudioData; - - while (remaining > 0) { - if (SDL_GetAudioStreamAvailable(_this->stream) == 0) { - /* Generate the data */ - (*_this->callbackspec.callback)(_this->callbackspec.userdata, - _this->hidden->buffer, _this->hidden->bufferSize); - _this->hidden->bufferOffset = 0; - SDL_PutAudioStreamData(_this->stream, _this->hidden->buffer, _this->hidden->bufferSize); - } - if (SDL_GetAudioStreamAvailable(_this->stream) > 0) { - int got; - UInt32 len = SDL_GetAudioStreamAvailable(_this->stream); - if (len > remaining) { - len = remaining; - } - got = SDL_GetAudioStreamData(_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); + AudioQueueBufferRef current_buffer = device->hidden->current_buffer; + SDL_assert(current_buffer != NULL); // should have been called from OutputBufferReadyCallback + SDL_assert(buffer == (Uint8 *) current_buffer->mAudioData); + current_buffer->mAudioDataByteSize = current_buffer->mAudioDataBytesCapacity; + device->hidden->current_buffer = NULL; + AudioQueueEnqueueBuffer(device->hidden->audioQueue, current_buffer, 0, NULL); } -static void inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, +static Uint8 *COREAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) +{ + AudioQueueBufferRef current_buffer = device->hidden->current_buffer; + SDL_assert(current_buffer != NULL); // should have been called from OutputBufferReadyCallback + SDL_assert(current_buffer->mAudioData != NULL); + *buffer_size = (int) current_buffer->mAudioDataBytesCapacity; + return (Uint8 *) current_buffer->mAudioData; +} + +static void OutputBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) +{ + SDL_AudioDevice *device = (SDL_AudioDevice *)inUserData; + SDL_assert(inBuffer != NULL); // ...right? + SDL_assert(device->hidden->current_buffer == NULL); // shouldn't have anything pending + device->hidden->current_buffer = inBuffer; + const SDL_bool okay = SDL_OutputAudioThreadIterate(device); + SDL_assert((device->hidden->current_buffer == NULL) || !okay); // PlayDevice should have enqueued and cleaned it out, unless we failed or shutdown. + + // buffer is unexpectedly here? We're probably dying, but try to requeue this buffer with silence. + if (device->hidden->current_buffer) { + AudioQueueBufferRef current_buffer = device->hidden->current_buffer; + device->hidden->current_buffer = NULL; + SDL_memset(current_buffer->mAudioData, device->silence_value, (size_t) current_buffer->mAudioDataBytesCapacity); + AudioQueueEnqueueBuffer(device->hidden->audioQueue, current_buffer, 0, NULL); + } +} + +static int COREAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ + AudioQueueBufferRef current_buffer = device->hidden->current_buffer; + SDL_assert(current_buffer != NULL); // should have been called from InputBufferReadyCallback + SDL_assert(current_buffer->mAudioData != NULL); + SDL_assert(buflen >= (int) current_buffer->mAudioDataByteSize); // `cpy` makes sure this won't overflow a buffer, but we _will_ drop samples if this assertion fails! + const int cpy = SDL_min(buflen, (int) current_buffer->mAudioDataByteSize); + SDL_memcpy(buffer, current_buffer->mAudioData, cpy); + device->hidden->current_buffer = NULL; + AudioQueueEnqueueBuffer(device->hidden->audioQueue, current_buffer, 0, NULL); // requeue for capturing more data later. + return cpy; +} + +static void COREAUDIO_FlushCapture(SDL_AudioDevice *device) +{ + AudioQueueBufferRef current_buffer = device->hidden->current_buffer; + if (current_buffer != NULL) { // also gets called at shutdown, when no buffer is available. + // just requeue the current buffer without reading from it, so it can be refilled with new data later. + device->hidden->current_buffer = NULL; + AudioQueueEnqueueBuffer(device->hidden->audioQueue, current_buffer, 0, NULL); + } +} + +static void InputBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, const AudioStreamPacketDescription *inPacketDescs) { - SDL_AudioDevice *_this = (SDL_AudioDevice *)inUserData; + SDL_AudioDevice *device = (SDL_AudioDevice *)inUserData; + SDL_assert(inAQ == device->hidden->audioQueue); + SDL_assert(inBuffer != NULL); // ...right? + SDL_assert(device->hidden->current_buffer == NULL); // shouldn't have anything pending + device->hidden->current_buffer = inBuffer; + SDL_CaptureAudioThreadIterate(device); + SDL_assert(device->hidden->current_buffer == NULL); // CaptureFromDevice/FlushCapture should have enqueued and cleaned it out. +} - if (SDL_AtomicGet(&_this->shutdown)) { - return; /* don't do anything. */ +static void COREAUDIO_CloseDevice(SDL_AudioDevice *device) +{ + if (!device->hidden) { + return; } - /* 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; - } - } + // dispose of the audio queue before waiting on the thread, or it might stall for a long time! + if (device->hidden->audioQueue) { + AudioQueueFlush(device->hidden->audioQueue); + AudioQueueStop(device->hidden->audioQueue, 0); + AudioQueueDispose(device->hidden->audioQueue, 0); } - AudioQueueEnqueueBuffer(_this->hidden->audioQueue, inBuffer, 0, NULL); + if (device->hidden->thread) { + SDL_assert(SDL_AtomicGet(&device->shutdown) != 0); // should have been set by SDL_audio.c + SDL_WaitThread(device->hidden->thread, NULL); + } + + #ifndef MACOSX_COREAUDIO + UpdateAudioSession(device, SDL_FALSE, SDL_TRUE); + #endif + + if (device->hidden->ready_semaphore) { + SDL_DestroySemaphore(device->hidden->ready_semaphore); + } + + // AudioQueueDispose() frees the actual buffer objects. + SDL_free(device->hidden->audioBuffer); + SDL_free(device->hidden->thread_error); + SDL_free(device->hidden); } #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) +static int PrepareDevice(SDL_AudioDevice *device) { - SDL_AudioDevice *_this = (SDL_AudioDevice *)data; - SDL_bool dead = SDL_FALSE; - UInt32 isAlive = 1; - UInt32 size = sizeof(isAlive); - OSStatus error; + void *handle = device->handle; + SDL_assert(handle != NULL); // this meant "system default" in SDL2, but doesn't anymore - 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(SDL_AudioDevice *_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(SDL_AudioDevice *_this) -{ - void *handle = _this->handle; - SDL_bool iscapture = _this->iscapture; - AudioDeviceID devid = (AudioDeviceID)((size_t)handle); + const AudioDeviceID devid = (AudioDeviceID)((size_t)handle); OSStatus result = noErr; UInt32 size = 0; - UInt32 alive = 0; - pid_t pid = 0; AudioObjectPropertyAddress addr = { 0, @@ -752,104 +646,80 @@ static int prepare_device(SDL_AudioDevice *_this) 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; - + UInt32 alive = 0; size = sizeof(alive); + addr.mSelector = kAudioDevicePropertyDeviceIsAlive; + addr.mScope = device->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; 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; + return SDL_SetError("CoreAudio: requested device exists, but isn't alive."); } - addr.mSelector = kAudioDevicePropertyHogMode; + // some devices don't support this property, so errors are fine here. + pid_t pid = 0; size = sizeof(pid); + addr.mSelector = kAudioDevicePropertyHogMode; 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; + return SDL_SetError("CoreAudio: requested device is being hogged."); } - _this->hidden->deviceID = devid; - return 1; + device->hidden->deviceID = devid; + + return 0; } -static int assign_device_to_audioqueue(SDL_AudioDevice *_this) +static int AssignDeviceToAudioQueue(SDL_AudioDevice *device) { const AudioObjectPropertyAddress prop = { kAudioDevicePropertyDeviceUID, - _this->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + device->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMain }; OSStatus result; CFStringRef devuid; UInt32 devuidsize = sizeof(devuid); - result = AudioObjectGetPropertyData(_this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid); + result = AudioObjectGetPropertyData(device->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid); CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)"); - result = AudioQueueSetProperty(_this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize); + result = AudioQueueSetProperty(device->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize); CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"); - return 1; + // !!! FIXME: do we need to CFRelease(devuid)? + + return 0; } #endif -static int prepare_audioqueue(SDL_AudioDevice *_this) +static int PrepareAudioQueue(SDL_AudioDevice *device) { - const AudioStreamBasicDescription *strdesc = &_this->hidden->strdesc; - const int iscapture = _this->iscapture; + const AudioStreamBasicDescription *strdesc = &device->hidden->strdesc; + const SDL_bool iscapture = device->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); + result = AudioQueueNewInput(strdesc, InputBufferReadyCallback, device, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &device->hidden->audioQueue); CHECK_RESULT("AudioQueueNewInput"); } else { - result = AudioQueueNewOutput(strdesc, outputCallback, _this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &_this->hidden->audioQueue); + result = AudioQueueNewOutput(strdesc, OutputBufferReadyCallback, device, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &device->hidden->audioQueue); CHECK_RESULT("AudioQueueNewOutput"); } -#ifdef MACOSX_COREAUDIO - if (!assign_device_to_audioqueue(_this)) { - return 0; + #ifdef MACOSX_COREAUDIO + if (AssignDeviceToAudioQueue(device) < 0) { + return -1; } + #endif - /* 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); + SDL_UpdatedAudioDeviceFormat(device); // make sure this is correct. /* Set the channel layout for the audio queue */ + AudioChannelLayout layout; SDL_zero(layout); - switch (_this->spec.channels) { + switch (device->spec.channels) { case 1: layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; break; @@ -877,198 +747,129 @@ static int prepare_audioqueue(SDL_AudioDevice *_this) break; } if (layout.mChannelLayoutTag != 0) { - result = AudioQueueSetProperty(_this->hidden->audioQueue, kAudioQueueProperty_ChannelLayout, &layout, sizeof(layout)); + result = AudioQueueSetProperty(device->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; -#ifdef __IOS__ + // Make sure we can feed the device a minimum amount of time + double MINIMUM_AUDIO_BUFFER_TIME_MS = 15.0; + #ifdef __IOS__ if (SDL_floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { - /* Older iOS hardware, use 40 ms as a minimum time */ + // Older iOS hardware, use 40 ms as a minimum time MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0; } -#endif + #endif + + int numAudioBuffers = 2; + const double msecs = (device->sample_frames / ((double)device->spec.freq)) * 1000.0; 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; + device->hidden->numAudioBuffers = numAudioBuffers; + device->hidden->audioBuffer = SDL_calloc(numAudioBuffers, sizeof(AudioQueueBufferRef)); + if (device->hidden->audioBuffer == NULL) { + return SDL_OutOfMemory(); } -#if DEBUG_COREAUDIO - printf("COREAUDIO: numAudioBuffers == %d\n", numAudioBuffers); -#endif + #if DEBUG_COREAUDIO + SDL_Log("COREAUDIO: numAudioBuffers == %d\n", numAudioBuffers); + #endif - for (i = 0; i < numAudioBuffers; i++) { - result = AudioQueueAllocateBuffer(_this->hidden->audioQueue, _this->spec.size, &_this->hidden->audioBuffer[i]); + for (int i = 0; i < numAudioBuffers; i++) { + result = AudioQueueAllocateBuffer(device->hidden->audioQueue, device->buffer_size, &device->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; + SDL_memset(device->hidden->audioBuffer[i]->mAudioData, device->silence_value, device->hidden->audioBuffer[i]->mAudioDataBytesCapacity); + device->hidden->audioBuffer[i]->mAudioDataByteSize = device->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); + result = AudioQueueEnqueueBuffer(device->hidden->audioQueue, device->hidden->audioBuffer[i], 0, NULL); CHECK_RESULT("AudioQueueEnqueueBuffer"); } - result = AudioQueueStart(_this->hidden->audioQueue, NULL); + result = AudioQueueStart(device->hidden->audioQueue, NULL); CHECK_RESULT("AudioQueueStart"); - /* We're running! */ - return 1; + return 0; // We're running! } -static int audioqueue_thread(void *arg) +static int AudioQueueThreadEntry(void *arg) { - SDL_AudioDevice *_this = (SDL_AudioDevice *)arg; - int rc; + SDL_AudioDevice *device = (SDL_AudioDevice *)arg; -#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); + if (device->iscapture) { + SDL_CaptureAudioThreadSetup(device); + } else { + SDL_OutputAudioThreadSetup(device); } -#endif - rc = prepare_audioqueue(_this); - if (!rc) { - _this->hidden->thread_error = SDL_strdup(SDL_GetError()); - SDL_PostSemaphore(_this->hidden->ready_semaphore); + if (PrepareAudioQueue(device) < 0) { + device->hidden->thread_error = SDL_strdup(SDL_GetError()); + SDL_PostSemaphore(device->hidden->ready_semaphore); return 0; } - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + // init was successful, alert parent thread and start running... + SDL_PostSemaphore(device->hidden->ready_semaphore); - /* init was successful, alert parent thread and start running... */ - SDL_PostSemaphore(_this->hidden->ready_semaphore); - - while (!SDL_AtomicGet(&_this->shutdown)) { + // This would be WaitDevice/WaitCaptureDevice in the normal SDL audio thread, but we get *BufferReadyCallback calls here to know when to iterate. + while (!SDL_AtomicGet(&device->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; + if (device->iscapture) { + SDL_CaptureAudioThreadShutdown(device); + } else { + // Drain off any pending playback. + const CFTimeInterval secs = (((CFTimeInterval)device->sample_frames) / ((CFTimeInterval)device->spec.freq)) * 2.0; CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0); + SDL_OutputAudioThreadShutdown(device); } -#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(SDL_AudioDevice *_this, const char *devname) +static int COREAUDIO_OpenDevice(SDL_AudioDevice *device) { - AudioStreamBasicDescription *strdesc; - const SDL_AudioFormat *closefmts; - 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) { + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->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)) { + #ifndef MACOSX_COREAUDIO + if (!UpdateAudioSession(device, 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; + [session setPreferredSampleRate:device->spec.freq error:nil]; + device->spec.freq = (int)session.sampleRate; + #if TARGET_OS_TV + if (device->iscapture) { + [session setPreferredInputNumberOfChannels:device->spec.channels error:nil]; + device->spec.channels = session.preferredInputNumberOfChannels; } else { - [session setPreferredOutputNumberOfChannels:_this->spec.channels error:nil]; - _this->spec.channels = session.preferredOutputNumberOfChannels; + [session setPreferredOutputNumberOfChannels:device->spec.channels error:nil]; + device->spec.channels = session.preferredOutputNumberOfChannels; } -#else + #else /* Calling setPreferredOutputNumberOfChannels seems to break audio output on iOS */ -#endif /* TARGET_OS_TV */ + #endif /* TARGET_OS_TV */ } -#endif + #endif /* Setup a AudioStreamBasicDescription with the requested format */ - SDL_zerop(strdesc); + AudioStreamBasicDescription *strdesc = &device->hidden->strdesc; strdesc->mFormatID = kAudioFormatLinearPCM; strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked; - strdesc->mChannelsPerFrame = _this->spec.channels; - strdesc->mSampleRate = _this->spec.freq; + strdesc->mChannelsPerFrame = device->spec.channels; + strdesc->mSampleRate = device->spec.freq; strdesc->mFramesPerPacket = 1; - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); + SDL_AudioFormat test_format; while ((test_format = *(closefmts++)) != 0) { /* CoreAudio handles most of SDL's formats natively. */ switch (test_format) { @@ -1091,7 +892,7 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) if (!test_format) { /* shouldn't happen, but just in case... */ return SDL_SetError("%s: Unsupported audio format", "coreaudio"); } - _this->spec.format = test_format; + device->spec.format = test_format; strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(test_format); if (SDL_AUDIO_ISBIGENDIAN(test_format)) { strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; @@ -1107,175 +908,43 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket; #ifdef MACOSX_COREAUDIO - if (!prepare_device(_this)) { + if (PrepareDevice(device) < 0) { 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) { + device->hidden->ready_semaphore = SDL_CreateSemaphore(0); + if (!device->hidden->ready_semaphore) { return -1; /* oh well. */ } - _this->hidden->thread = SDL_CreateThreadInternal(audioqueue_thread, "AudioQueue thread", 512 * 1024, _this); - if (!_this->hidden->thread) { + char threadname[64]; + SDL_GetAudioThreadName(device, threadname, sizeof(threadname)); + device->hidden->thread = SDL_CreateThreadInternal(AudioQueueThreadEntry, threadname, 0, device); + if (!device->hidden->thread) { return -1; } - SDL_WaitSemaphore(_this->hidden->ready_semaphore); - SDL_DestroySemaphore(_this->hidden->ready_semaphore); - _this->hidden->ready_semaphore = NULL; + SDL_WaitSemaphore(device->hidden->ready_semaphore); + SDL_DestroySemaphore(device->hidden->ready_semaphore); + device->hidden->ready_semaphore = NULL; - if ((_this->hidden->thread != NULL) && (_this->hidden->thread_error != NULL)) { - return SDL_SetError("%s", _this->hidden->thread_error); + if ((device->hidden->thread != NULL) && (device->hidden->thread_error != NULL)) { + SDL_WaitThread(device->hidden->thread, NULL); + device->hidden->thread = NULL; + return SDL_SetError("%s", device->hidden->thread_error); } - return (_this->hidden->thread != NULL) ? 0 : -1; + return (device->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 = SDL_strlen(devname); - /* Some devices have whitespace at the end...trim it. */ - while ((len > 0) && (devname[len - 1] == ' ')) { - len--; - usable = (int)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); + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, DeviceListChangedNotification, NULL); + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_output_device_address, DefaultOutputDeviceChangedNotification, NULL); + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_input_device_address, DefaultInputDeviceChangedNotification, NULL); #endif } @@ -1283,13 +952,16 @@ static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl) { /* Set the function pointers */ impl->OpenDevice = COREAUDIO_OpenDevice; + impl->PlayDevice = COREAUDIO_PlayDevice; + impl->GetDeviceBuf = COREAUDIO_GetDeviceBuf; + impl->CaptureFromDevice = COREAUDIO_CaptureFromDevice; + impl->FlushCapture = COREAUDIO_FlushCapture; 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); + impl->FreeDeviceHandle = COREAUDIO_FreeDeviceHandle; #else impl->OnlyHasDefaultOutputDevice = SDL_TRUE; impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; @@ -1297,7 +969,6 @@ static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl) impl->ProvidesOwnCallbackThread = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - impl->SupportsNonPow2Samples = SDL_TRUE; return SDL_TRUE; /* this audio target is available. */ } diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c index 33ad1964..f1ab2970 100644 --- a/src/audio/directsound/SDL_directsound.c +++ b/src/audio/directsound/SDL_directsound.c @@ -22,34 +22,34 @@ #ifdef SDL_AUDIO_DRIVER_DSOUND -/* Allow access to a raw mixing buffer */ - #include "../SDL_audio_c.h" #include "SDL_directsound.h" #include #ifdef HAVE_MMDEVICEAPI_H #include "../../core/windows/SDL_immdevice.h" -#endif /* HAVE_MMDEVICEAPI_H */ +#endif #ifndef WAVE_FORMAT_IEEE_FLOAT #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #endif -/* For Vista+, we can enumerate DSound devices with IMMDevice */ +// For Vista+, we can enumerate DSound devices with IMMDevice #ifdef HAVE_MMDEVICEAPI_H static SDL_bool SupportsIMMDevice = SDL_FALSE; -#endif /* HAVE_MMDEVICEAPI_H */ +#endif -/* DirectX function pointers for audio */ +// 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); +typedef HRESULT(WINAPI *fnGetDeviceID)(LPCGUID, LPGUID); static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL; static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL; static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL; static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL; +static fnGetDeviceID pGetDeviceID = NULL; 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 } }; @@ -60,6 +60,7 @@ static void DSOUND_Unload(void) pDirectSoundEnumerateW = NULL; pDirectSoundCaptureCreate8 = NULL; pDirectSoundCaptureEnumerateW = NULL; + pGetDeviceID = NULL; if (DSoundDLL != NULL) { SDL_UnloadObject(DSoundDLL); @@ -77,18 +78,19 @@ static int DSOUND_Load(void) if (DSoundDLL == NULL) { SDL_SetError("DirectSound: failed to load DSOUND.DLL"); } else { -/* Now make sure we have DirectX 8 or better... */ +// 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. */ + loaded = 1; // will reset if necessary. DSOUNDLOAD(DirectSoundCreate8); DSOUNDLOAD(DirectSoundEnumerateW); DSOUNDLOAD(DirectSoundCaptureCreate8); DSOUNDLOAD(DirectSoundCaptureEnumerateW); + DSOUNDLOAD(GetDeviceID); #undef DSOUNDLOAD if (!loaded) { @@ -149,56 +151,81 @@ static int SetDSerror(const char *function, int code) return SDL_SetError("%s: %s (0x%x)", function, error, code); } -static void DSOUND_FreeDeviceHandle(void *handle) -{ - SDL_free(handle); -} - -static int DSOUND_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +static void DSOUND_FreeDeviceHandle(SDL_AudioDevice *device) { #ifdef HAVE_MMDEVICEAPI_H if (SupportsIMMDevice) { - return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture); + SDL_IMMDevice_FreeDeviceHandle(device); + } else +#endif + { + SDL_free(device->handle); } -#endif /* HAVE_MMDEVICEAPI_H */ - return SDL_Unsupported(); } -static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) +// FindAllDevs is presumably only used on WinXP; Vista and later can use IMMDevice for better results. +typedef struct FindAllDevsData { - const int iscapture = (int)((size_t)data); - if (guid != NULL) { /* skip default device */ + SDL_bool iscapture; + SDL_AudioDevice **default_device; + LPCGUID default_device_guid; +} FindAllDevsData; + +static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID userdata) +{ + FindAllDevsData *data = (FindAllDevsData *) userdata; + 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)); + if (cpyguid) { + 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. */ + /* 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_AudioDevice *device = SDL_AddAudioDevice(data->iscapture, str, NULL, cpyguid); + if (device && data->default_device && data->default_device_guid) { + if (SDL_memcmp(cpyguid, data->default_device_guid, sizeof (GUID)) == 0) { + *data->default_device = device; + } + } + } + SDL_free(str); // SDL_AddAudioDevice() makes a copy of this string. } } - return TRUE; /* keep enumerating. */ + return TRUE; // keep enumerating. } -static void DSOUND_DetectDevices(void) +static void DSOUND_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { #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 + SDL_IMMDevice_EnumerateEndpoints(default_output, default_capture); + } else +#endif + { + // Without IMMDevice, you can enumerate devices and figure out the default devices, + // but you won't get device hotplug or default device change notifications. But this is + // only for WinXP; Windows Vista and later should be using IMMDevice. + FindAllDevsData data; + GUID guid; + + data.iscapture = SDL_TRUE; + data.default_device = default_capture; + data.default_device_guid = (pGetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) ? &guid : NULL; + pDirectSoundCaptureEnumerateW(FindAllDevs, &data); + + data.iscapture = SDL_FALSE; + data.default_device = default_output; + data.default_device_guid = (pGetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) ? &guid : NULL; + pDirectSoundEnumerateW(FindAllDevs, &data); } -#endif /* HAVE_MMDEVICEAPI_H*/ + } -static void DSOUND_WaitDevice(SDL_AudioDevice *_this) +static void DSOUND_WaitDevice(SDL_AudioDevice *device) { DWORD status = 0; DWORD cursor = 0; @@ -208,11 +235,11 @@ static void DSOUND_WaitDevice(SDL_AudioDevice *_this) /* Semi-busy wait, since we have no way of getting play notification on a primary mixing buffer located in hardware (DirectX 5.0) */ - result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf, + result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf, &junk, &cursor); if (result != DS_OK) { if (result == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(_this->hidden->mixbuf); + IDirectSoundBuffer_Restore(device->hidden->mixbuf); } #ifdef DEBUG_SOUND SetDSerror("DirectSound GetCurrentPosition", result); @@ -220,21 +247,24 @@ static void DSOUND_WaitDevice(SDL_AudioDevice *_this) return; } - while ((cursor / _this->spec.size) == _this->hidden->lastchunk) { - /* FIXME: find out how much time is left and sleep that long */ + while ((cursor / device->buffer_size) == device->hidden->lastchunk) { + if (SDL_AtomicGet(&device->shutdown)) { + return; + } + SDL_Delay(1); - /* Try to restore a lost sound buffer */ - IDirectSoundBuffer_GetStatus(_this->hidden->mixbuf, &status); + // Try to restore a lost sound buffer + IDirectSoundBuffer_GetStatus(device->hidden->mixbuf, &status); if (status & DSBSTATUS_BUFFERLOST) { - IDirectSoundBuffer_Restore(_this->hidden->mixbuf); - IDirectSoundBuffer_GetStatus(_this->hidden->mixbuf, &status); + IDirectSoundBuffer_Restore(device->hidden->mixbuf); + IDirectSoundBuffer_GetStatus(device->hidden->mixbuf, &status); if (status & DSBSTATUS_BUFFERLOST) { break; } } if (!(status & DSBSTATUS_PLAYING)) { - result = IDirectSoundBuffer_Play(_this->hidden->mixbuf, 0, 0, + result = IDirectSoundBuffer_Play(device->hidden->mixbuf, 0, 0, DSBPLAY_LOOPING); if (result == DS_OK) { continue; @@ -245,8 +275,8 @@ static void DSOUND_WaitDevice(SDL_AudioDevice *_this) return; } - /* Find out where we are playing */ - result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf, + // Find out where we are playing + result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf, &junk, &cursor); if (result != DS_OK) { SetDSerror("DirectSound GetCurrentPosition", result); @@ -255,102 +285,100 @@ static void DSOUND_WaitDevice(SDL_AudioDevice *_this) } } -static void DSOUND_PlayDevice(SDL_AudioDevice *_this) +static void DSOUND_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - /* Unlock the buffer, allowing it to play */ - if (_this->hidden->locked_buf) { - IDirectSoundBuffer_Unlock(_this->hidden->mixbuf, - _this->hidden->locked_buf, - _this->spec.size, NULL, 0); - } + // Unlock the buffer, allowing it to play + SDL_assert(buflen == device->buffer_size); + IDirectSoundBuffer_Unlock(device->hidden->mixbuf, (LPVOID) buffer, buflen, NULL, 0); } -static Uint8 *DSOUND_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *DSOUND_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { DWORD cursor = 0; DWORD junk = 0; HRESULT result = DS_OK; - DWORD rawlen = 0; - /* Figure out which blocks to fill next */ - _this->hidden->locked_buf = NULL; - result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf, + SDL_assert(*buffer_size == device->buffer_size); + + // Figure out which blocks to fill next + device->hidden->locked_buf = NULL; + result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf, &junk, &cursor); if (result == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(_this->hidden->mixbuf); - result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf, + IDirectSoundBuffer_Restore(device->hidden->mixbuf); + result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf, &junk, &cursor); } if (result != DS_OK) { SetDSerror("DirectSound GetCurrentPosition", result); return NULL; } - cursor /= _this->spec.size; + cursor /= device->buffer_size; #ifdef DEBUG_SOUND - /* Detect audio dropouts */ + // Detect audio dropouts { DWORD spot = cursor; - if (spot < _this->hidden->lastchunk) { - spot += _this->hidden->num_buffers; + if (spot < device->hidden->lastchunk) { + spot += device->hidden->num_buffers; } - if (spot > _this->hidden->lastchunk + 1) { + if (spot > device->hidden->lastchunk + 1) { fprintf(stderr, "Audio dropout, missed %d fragments\n", - (spot - (_this->hidden->lastchunk + 1))); + (spot - (device->hidden->lastchunk + 1))); } } #endif - _this->hidden->lastchunk = cursor; - cursor = (cursor + 1) % _this->hidden->num_buffers; - cursor *= _this->spec.size; + device->hidden->lastchunk = cursor; + cursor = (cursor + 1) % device->hidden->num_buffers; + cursor *= device->buffer_size; - /* Lock the audio buffer */ - result = IDirectSoundBuffer_Lock(_this->hidden->mixbuf, cursor, - _this->spec.size, - (LPVOID *)&_this->hidden->locked_buf, + // Lock the audio buffer + DWORD rawlen = 0; + result = IDirectSoundBuffer_Lock(device->hidden->mixbuf, cursor, + device->buffer_size, + (LPVOID *)&device->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, + IDirectSoundBuffer_Restore(device->hidden->mixbuf); + result = IDirectSoundBuffer_Lock(device->hidden->mixbuf, cursor, + device->buffer_size, + (LPVOID *)&device->hidden->locked_buf, &rawlen, NULL, &junk, 0); } if (result != DS_OK) { SetDSerror("DirectSound Lock", result); return NULL; } - return _this->hidden->locked_buf; + return device->hidden->locked_buf; } -static int DSOUND_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static void DSOUND_WaitCaptureDevice(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; - DWORD junk, cursor, ptr1len, ptr2len; + struct SDL_PrivateAudioData *h = device->hidden; + while (!SDL_AtomicGet(&device->shutdown)) { + DWORD junk, cursor; + if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) { + SDL_AudioDeviceDisconnected(device); + return; + } else if ((cursor / device->buffer_size) != h->lastchunk) { + return; + } + SDL_Delay(1); + } +} + +static int DSOUND_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ + struct SDL_PrivateAudioData *h = device->hidden; + DWORD ptr1len, ptr2len; VOID *ptr1, *ptr2; - SDL_assert((Uint32)buflen == _this->spec.size); + SDL_assert(buflen == device->buffer_size); - while (SDL_TRUE) { - if (SDL_AtomicGet(&_this->shutdown)) { /* in case the buffer froze... */ - SDL_memset(buffer, _this->spec.silence, buflen); - return buflen; - } - - if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) { - return -1; - } - if ((cursor / _this->spec.size) == h->lastchunk) { - SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */ - } else { - break; - } - } - - if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * _this->spec.size, _this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) { + if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * buflen, buflen, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) { return -1; } - SDL_assert(ptr1len == _this->spec.size); + SDL_assert(ptr1len == buflen); SDL_assert(ptr2 == NULL); SDL_assert(ptr2len == 0); @@ -362,51 +390,54 @@ static int DSOUND_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int bu h->lastchunk = (h->lastchunk + 1) % h->num_buffers; - return ptr1len; + return (int) ptr1len; } -static void DSOUND_FlushCapture(SDL_AudioDevice *_this) +static void DSOUND_FlushCapture(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; + struct SDL_PrivateAudioData *h = device->hidden; DWORD junk, cursor; if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) { - h->lastchunk = cursor / _this->spec.size; + h->lastchunk = cursor / device->buffer_size; } } -static void DSOUND_CloseDevice(SDL_AudioDevice *_this) +static void DSOUND_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->mixbuf != NULL) { - IDirectSoundBuffer_Stop(_this->hidden->mixbuf); - IDirectSoundBuffer_Release(_this->hidden->mixbuf); + if (device->hidden) { + if (device->hidden->mixbuf != NULL) { + IDirectSoundBuffer_Stop(device->hidden->mixbuf); + IDirectSoundBuffer_Release(device->hidden->mixbuf); + } + if (device->hidden->sound != NULL) { + IDirectSound_Release(device->hidden->sound); + } + if (device->hidden->capturebuf != NULL) { + IDirectSoundCaptureBuffer_Stop(device->hidden->capturebuf); + IDirectSoundCaptureBuffer_Release(device->hidden->capturebuf); + } + if (device->hidden->capture != NULL) { + IDirectSoundCapture_Release(device->hidden->capture); + } + SDL_free(device->hidden); + device->hidden = NULL; } - if (_this->hidden->sound != NULL) { - IDirectSound_Release(_this->hidden->sound); - } - if (_this->hidden->capturebuf != NULL) { - IDirectSoundCaptureBuffer_Stop(_this->hidden->capturebuf); - IDirectSoundCaptureBuffer_Release(_this->hidden->capturebuf); - } - if (_this->hidden->capture != NULL) { - IDirectSoundCapture_Release(_this->hidden->capture); - } - SDL_free(_this->hidden); } /* This function tries to create a secondary audio buffer, and returns the number of audio chunks available in the created buffer. This is for playback devices, not capture. */ -static int CreateSecondary(SDL_AudioDevice *_this, const DWORD bufsize, WAVEFORMATEX *wfmt) +static int CreateSecondary(SDL_AudioDevice *device, const DWORD bufsize, WAVEFORMATEX *wfmt) { - LPDIRECTSOUND sndObj = _this->hidden->sound; - LPDIRECTSOUNDBUFFER *sndbuf = &_this->hidden->mixbuf; + LPDIRECTSOUND sndObj = device->hidden->sound; + LPDIRECTSOUNDBUFFER *sndbuf = &device->hidden->mixbuf; HRESULT result = DS_OK; DSBUFFERDESC format; LPVOID pvAudioPtr1, pvAudioPtr2; DWORD dwAudioBytes1, dwAudioBytes2; - /* Try to create the secondary buffer */ + // Try to create the secondary buffer SDL_zero(format); format.dwSize = sizeof(format); format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; @@ -419,30 +450,29 @@ static int CreateSecondary(SDL_AudioDevice *_this, const DWORD bufsize, WAVEFORM } IDirectSoundBuffer_SetFormat(*sndbuf, wfmt); - /* Silence the initial audio buffer */ + // Silence the initial audio buffer result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, (LPVOID *)&pvAudioPtr1, &dwAudioBytes1, (LPVOID *)&pvAudioPtr2, &dwAudioBytes2, DSBLOCK_ENTIREBUFFER); if (result == DS_OK) { - SDL_memset(pvAudioPtr1, _this->spec.silence, dwAudioBytes1); + SDL_memset(pvAudioPtr1, device->silence_value, dwAudioBytes1); IDirectSoundBuffer_Unlock(*sndbuf, (LPVOID)pvAudioPtr1, dwAudioBytes1, (LPVOID)pvAudioPtr2, dwAudioBytes2); } - /* We're ready to go */ - return 0; + return 0; // We're ready to go } /* This function tries to create a capture buffer, and returns the number of audio chunks available in the created buffer. This is for capture devices, not playback. */ -static int CreateCaptureBuffer(SDL_AudioDevice *_this, const DWORD bufsize, WAVEFORMATEX *wfmt) +static int CreateCaptureBuffer(SDL_AudioDevice *device, const DWORD bufsize, WAVEFORMATEX *wfmt) { - LPDIRECTSOUNDCAPTURE capture = _this->hidden->capture; - LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &_this->hidden->capturebuf; + LPDIRECTSOUNDCAPTURE capture = device->hidden->capture; + LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &device->hidden->capturebuf; DSCBUFFERDESC format; HRESULT result; @@ -464,7 +494,7 @@ static int CreateCaptureBuffer(SDL_AudioDevice *_this, const DWORD bufsize, WAVE } #if 0 - /* presumably this starts at zero, but just in case... */ + // presumably this starts at zero, but just in case... result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor); if (result != DS_OK) { IDirectSoundCaptureBuffer_Stop(*capturebuf); @@ -472,42 +502,45 @@ static int CreateCaptureBuffer(SDL_AudioDevice *_this, const DWORD bufsize, WAVE return SetDSerror("DirectSound GetCurrentPosition", result); } - _this->hidden->lastchunk = cursor / _this->spec.size; + device->hidden->lastchunk = cursor / device->buffer_size; #endif return 0; } -static int DSOUND_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int DSOUND_OpenDevice(SDL_AudioDevice *device) { - const DWORD numchunks = 8; - HRESULT result; - SDL_bool tried_format = SDL_FALSE; - SDL_bool iscapture = _this->iscapture; - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; - 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) { + // Initialize all variables that we clean on shutdown + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); - /* Open the audio device */ - if (iscapture) { - result = pDirectSoundCaptureCreate8(guid, &_this->hidden->capture, NULL); + // Open the audio device + LPGUID guid; +#ifdef HAVE_MMDEVICEAPI_H + if (SupportsIMMDevice) { + guid = SDL_IMMDevice_GetDirectSoundGUID(device); + } else +#endif + { + guid = (LPGUID) device->handle; + } + + SDL_assert(guid != NULL); + + HRESULT result; + if (device->iscapture) { + result = pDirectSoundCaptureCreate8(guid, &device->hidden->capture, NULL); if (result != DS_OK) { return SetDSerror("DirectSoundCaptureCreate8", result); } } else { - result = pDirectSoundCreate8(guid, &_this->hidden->sound, NULL); + result = pDirectSoundCreate8(guid, &device->hidden->sound, NULL); if (result != DS_OK) { return SetDSerror("DirectSoundCreate8", result); } - result = IDirectSound_SetCooperativeLevel(_this->hidden->sound, + result = IDirectSound_SetCooperativeLevel(device->hidden->sound, GetDesktopWindow(), DSSCL_NORMAL); if (result != DS_OK) { @@ -515,7 +548,10 @@ static int DSOUND_OpenDevice(SDL_AudioDevice *_this, const char *devname) } } - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + const DWORD numchunks = 8; + SDL_bool tried_format = SDL_FALSE; + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { switch (test_format) { case SDL_AUDIO_U8: @@ -524,69 +560,68 @@ static int DSOUND_OpenDevice(SDL_AudioDevice *_this, const char *devname) case SDL_AUDIO_F32: tried_format = SDL_TRUE; - _this->spec.format = test_format; + device->spec.format = test_format; - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); + // Update the fragment size as size in bytes + SDL_UpdatedAudioDeviceFormat(device); - bufsize = numchunks * _this->spec.size; + const DWORD bufsize = numchunks * device->buffer_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)); } else { - int rc; WAVEFORMATEXTENSIBLE wfmt; SDL_zero(wfmt); - if (_this->spec.channels > 2) { + if (device->spec.channels > 2) { wfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfmt.Format.cbSize = sizeof(wfmt) - sizeof(WAVEFORMATEX); - if (SDL_AUDIO_ISFLOAT(_this->spec.format)) { + if (SDL_AUDIO_ISFLOAT(device->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); + wfmt.Samples.wValidBitsPerSample = SDL_AUDIO_BITSIZE(device->spec.format); - switch (_this->spec.channels) { - case 3: /* 3.0 (or 2.1) */ + switch (device->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 */ + 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) */ + 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 */ + 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 */ + 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 */ + 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)) { + } else if (SDL_AUDIO_ISFLOAT(device->spec.format)) { wfmt.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; } else { wfmt.Format.wFormatTag = WAVE_FORMAT_PCM; } - wfmt.Format.wBitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format); - wfmt.Format.nChannels = _this->spec.channels; - wfmt.Format.nSamplesPerSec = _this->spec.freq; + wfmt.Format.wBitsPerSample = SDL_AUDIO_BITSIZE(device->spec.format); + wfmt.Format.nChannels = device->spec.channels; + wfmt.Format.nSamplesPerSec = device->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, (WAVEFORMATEX *)&wfmt) : CreateSecondary(_this, bufsize, (WAVEFORMATEX *)&wfmt); + const int rc = device->iscapture ? CreateCaptureBuffer(device, bufsize, (WAVEFORMATEX *)&wfmt) : CreateSecondary(device, bufsize, (WAVEFORMATEX *)&wfmt); if (rc == 0) { - _this->hidden->num_buffers = numchunks; + device->hidden->num_buffers = numchunks; break; } } @@ -599,14 +634,14 @@ static int DSOUND_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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("%s: Unsupported audio format", "directsound"); } - /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */ + // Playback buffers will auto-start playing in DSOUND_WaitDevice() - return 0; /* good to go. */ + return 0; // good to go. } static void DSOUND_Deinitialize(void) @@ -616,7 +651,7 @@ static void DSOUND_Deinitialize(void) SDL_IMMDevice_Quit(); SupportsIMMDevice = SDL_FALSE; } -#endif /* HAVE_MMDEVICEAPI_H */ +#endif DSOUND_Unload(); } @@ -628,29 +663,27 @@ static SDL_bool DSOUND_Init(SDL_AudioDriverImpl *impl) #ifdef HAVE_MMDEVICEAPI_H SupportsIMMDevice = !(SDL_IMMDevice_Init() < 0); -#endif /* HAVE_MMDEVICEAPI_H */ +#endif - /* Set the function pointers */ impl->DetectDevices = DSOUND_DetectDevices; impl->OpenDevice = DSOUND_OpenDevice; impl->PlayDevice = DSOUND_PlayDevice; impl->WaitDevice = DSOUND_WaitDevice; impl->GetDeviceBuf = DSOUND_GetDeviceBuf; + impl->WaitCaptureDevice = DSOUND_WaitCaptureDevice; impl->CaptureFromDevice = DSOUND_CaptureFromDevice; impl->FlushCapture = DSOUND_FlushCapture; 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 SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap DSOUND_bootstrap = { "directsound", "DirectSound", DSOUND_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_DSOUND */ +#endif // SDL_AUDIO_DRIVER_DSOUND diff --git a/src/audio/directsound/SDL_directsound.h b/src/audio/directsound/SDL_directsound.h index d66c920a..18b67dac 100644 --- a/src/audio/directsound/SDL_directsound.h +++ b/src/audio/directsound/SDL_directsound.h @@ -27,9 +27,10 @@ #include "../SDL_sysaudio.h" -/* The DirectSound objects */ +// The DirectSound objects struct SDL_PrivateAudioData { + // !!! FIXME: make this a union with capture/playback sections? LPDIRECTSOUND sound; LPDIRECTSOUNDBUFFER mixbuf; LPDIRECTSOUNDCAPTURE capture; @@ -39,4 +40,4 @@ struct SDL_PrivateAudioData Uint8 *locked_buf; }; -#endif /* SDL_directsound_h_ */ +#endif // SDL_directsound_h_ diff --git a/src/audio/disk/SDL_diskaudio.c b/src/audio/disk/SDL_diskaudio.c index d351ed90..e7830ccc 100644 --- a/src/audio/disk/SDL_diskaudio.c +++ b/src/audio/disk/SDL_diskaudio.c @@ -22,171 +22,151 @@ #ifdef SDL_AUDIO_DRIVER_DISK -/* Output raw audio data to a file. */ - -#ifdef HAVE_STDIO_H -#include -#endif +// Output raw audio data to a file. #include "../SDL_audio_c.h" #include "SDL_diskaudio.h" -/* !!! FIXME: these should be SDL hints, not environment variables. */ -/* environment variables and defaults. */ +// !!! 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" -/* This function waits until it is possible to write a full sound buffer */ -static void DISKAUDIO_WaitDevice(SDL_AudioDevice *_this) +static void DISKAUDIO_WaitDevice(SDL_AudioDevice *device) { - SDL_Delay(_this->hidden->io_delay); + SDL_Delay(device->hidden->io_delay); } -static void DISKAUDIO_PlayDevice(SDL_AudioDevice *_this) +static void DISKAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { - const Sint64 written = SDL_RWwrite(_this->hidden->io, - _this->hidden->mixbuf, - _this->spec.size); - - /* If we couldn't write, assume fatal error for now */ - if (written != _this->spec.size) { - SDL_OpenedAudioDeviceDisconnected(_this); + const int written = (int)SDL_RWwrite(device->hidden->io, buffer, (size_t)buffer_size); + if (written != buffer_size) { // If we couldn't write, assume fatal error for now + SDL_AudioDeviceDisconnected(device); } #ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", (int) written); + SDL_Log("DISKAUDIO: Wrote %d bytes of audio data", (int) written); #endif } -static Uint8 *DISKAUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *DISKAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + return device->hidden->mixbuf; } -static int DISKAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int DISKAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { - struct SDL_PrivateAudioData *h = _this->hidden; + struct SDL_PrivateAudioData *h = device->hidden; const int origbuflen = buflen; - SDL_Delay(h->io_delay); - if (h->io) { - const int br = (int) SDL_RWread(h->io, buffer, (Sint64) buflen); + const int br = (int)SDL_RWread(h->io, buffer, (size_t)buflen); buflen -= br; buffer = ((Uint8 *)buffer) + br; - if (buflen > 0) { /* EOF (or error, but whatever). */ + 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); + // if we ran out of file, just write silence. + SDL_memset(buffer, device->silence_value, buflen); return origbuflen; } -static void DISKAUDIO_FlushCapture(SDL_AudioDevice *_this) +static void DISKAUDIO_FlushCapture(SDL_AudioDevice *device) { - /* no op...we don't advance the file pointer or anything. */ + // no op...we don't advance the file pointer or anything. } -static void DISKAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void DISKAUDIO_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->io != NULL) { - SDL_RWclose(_this->hidden->io); - } - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden); -} - -static const char *get_filename(const SDL_bool iscapture, const char *devname) -{ - if (devname == NULL) { - devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE); - if (devname == NULL) { - devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE; + if (device->hidden) { + if (device->hidden->io != NULL) { + SDL_RWclose(device->hidden->io); } + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); + device->hidden = NULL; + } +} + +static const char *get_filename(const SDL_bool iscapture) +{ + const char *devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE); + if (devname == NULL) { + devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE; } return devname; } -static int DISKAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int DISKAUDIO_OpenDevice(SDL_AudioDevice *device) { - 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); + SDL_bool iscapture = device->iscapture; + const char *fname = get_filename(iscapture); const char *envr = SDL_getenv(DISKENVR_IODELAY); - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); if (envr != NULL) { - _this->hidden->io_delay = SDL_atoi(envr); + device->hidden->io_delay = SDL_atoi(envr); } else { - _this->hidden->io_delay = ((_this->spec.samples * 1000) / _this->spec.freq); + device->hidden->io_delay = ((device->sample_frames * 1000) / device->spec.freq); } - /* Open the audio device */ - _this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); - if (_this->hidden->io == NULL) { + // Open the "audio device" + device->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); + if (device->hidden->io == NULL) { return -1; } - /* Allocate mixing buffer */ + // Allocate mixing buffer if (!iscapture) { - _this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->spec.size); - if (_this->hidden->mixbuf == NULL) { + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (device->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size); + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); } - SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, - "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); + SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, "You are using the SDL disk i/o audio driver!"); + SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, " %s file [%s].\n", iscapture ? "Reading from" : "Writing to", fname); - /* We're ready to rock and roll. :-) */ - return 0; + return 0; // We're ready to rock and roll. :-) } -static void DISKAUDIO_DetectDevices(void) +static void DISKAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1); - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2); + *default_output = SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1); + *default_capture = SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2); } static SDL_bool DISKAUDIO_Init(SDL_AudioDriverImpl *impl) { - /* Set the function pointers */ impl->OpenDevice = DISKAUDIO_OpenDevice; impl->WaitDevice = DISKAUDIO_WaitDevice; + impl->WaitCaptureDevice = DISKAUDIO_WaitDevice; impl->PlayDevice = DISKAUDIO_PlayDevice; impl->GetDeviceBuf = DISKAUDIO_GetDeviceBuf; impl->CaptureFromDevice = DISKAUDIO_CaptureFromDevice; impl->FlushCapture = DISKAUDIO_FlushCapture; - impl->CloseDevice = DISKAUDIO_CloseDevice; impl->DetectDevices = DISKAUDIO_DetectDevices; impl->AllowsArbitraryDeviceNames = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - impl->SupportsNonPow2Samples = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap DISKAUDIO_bootstrap = { "disk", "direct-to-disk audio", DISKAUDIO_Init, SDL_TRUE }; -#endif /* SDL_AUDIO_DRIVER_DISK */ +#endif // SDL_AUDIO_DRIVER_DISK diff --git a/src/audio/dsp/SDL_dspaudio.c b/src/audio/dsp/SDL_dspaudio.c index 88c053e8..004acef9 100644 --- a/src/audio/dsp/SDL_dspaudio.c +++ b/src/audio/dsp/SDL_dspaudio.c @@ -20,9 +20,9 @@ */ #include "SDL_internal.h" -#ifdef SDL_AUDIO_DRIVER_OSS +// !!! FIXME: clean out perror and fprintf calls in here. -/* Allow access to a raw mixing buffer */ +#ifdef SDL_AUDIO_DRIVER_OSS #include /* For perror() */ #include /* For strerror() */ @@ -38,82 +38,69 @@ #include "../SDL_audio_c.h" #include "../SDL_audiodev_c.h" +#include "../../SDL_utils_c.h" #include "SDL_dspaudio.h" -static void DSP_DetectDevices(void) +static void DSP_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - SDL_EnumUnixAudioDevices(0, NULL); + SDL_EnumUnixAudioDevices(SDL_FALSE, NULL); } -static void DSP_CloseDevice(SDL_AudioDevice *_this) +static void DSP_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->audio_fd >= 0) { - close(_this->hidden->audio_fd); - } - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden); -} - -static int DSP_OpenDevice(SDL_AudioDevice *_this, const char *devname) -{ - SDL_bool iscapture = _this->iscapture; - const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); - int format = 0; - int value; - int frag_spec; - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; - - /* 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) { - devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { - return SDL_SetError("No such audio device"); + if (device->hidden) { + if (device->hidden->audio_fd >= 0) { + close(device->hidden->audio_fd); } + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); + } +} + +static int DSP_OpenDevice(SDL_AudioDevice *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 (device->spec.channels > 8) { + device->spec.channels = 8; + } else if (device->spec.channels > 4) { + device->spec.channels = 4; + } else if (device->spec.channels > 2) { + device->spec.channels = 2; } - /* 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) { - _this->spec.channels = 8; - } else if (_this->spec.channels > 4) { - _this->spec.channels = 4; - } 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) { + // Initialize all variables that we clean on shutdown + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); - /* Open the audio device */ - _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)); + // Open the audio device; we hardcode the device path in `device->name` for lack of better info, so use that. + const int flags = ((device->iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); + device->hidden->audio_fd = open(device->name, flags | O_CLOEXEC, 0); + if (device->hidden->audio_fd < 0) { + return SDL_SetError("Couldn't open %s: %s", device->name, strerror(errno)); } - /* Make the file descriptor use blocking i/o with fcntl() */ + // Make the file descriptor use blocking i/o with fcntl() { - long ctlflags; - ctlflags = fcntl(_this->hidden->audio_fd, F_GETFL); - ctlflags &= ~O_NONBLOCK; - if (fcntl(_this->hidden->audio_fd, F_SETFL, ctlflags) < 0) { + const long ctlflags = fcntl(device->hidden->audio_fd, F_GETFL) & ~O_NONBLOCK; + if (fcntl(device->hidden->audio_fd, F_SETFL, ctlflags) < 0) { return SDL_SetError("Couldn't set audio blocking mode"); } } - /* Get a list of supported hardware formats */ - if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { + // Get a list of supported hardware formats + int value; + if (ioctl(device->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { perror("SNDCTL_DSP_GETFMTS"); return SDL_SetError("Couldn't get audio format list"); } /* Try for a closest match on audio format */ - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + int format = 0; + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); @@ -134,17 +121,7 @@ static int DSP_OpenDevice(SDL_AudioDevice *_this, const char *devname) format = AFMT_S16_BE; } break; -#if 0 -/* - * These formats are not used by any real life systems so they are not - * needed here. - */ - case SDL_AUDIO_S8: - if (value & AFMT_S8) { - format = AFMT_S8; - } - break; -#endif + default: continue; } @@ -153,40 +130,43 @@ static int DSP_OpenDevice(SDL_AudioDevice *_this, const char *devname) if (format == 0) { return SDL_SetError("Couldn't find any hardware audio formats"); } - _this->spec.format = test_format; + device->spec.format = test_format; - /* Set the audio format */ + // Set the audio format value = format; - if ((ioctl(_this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || + if ((ioctl(device->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) { perror("SNDCTL_DSP_SETFMT"); return SDL_SetError("Couldn't set audio format"); } - /* Set the number of channels of output */ - value = _this->spec.channels; - if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { + // Set the number of channels of output + value = device->spec.channels; + if (ioctl(device->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { perror("SNDCTL_DSP_CHANNELS"); return SDL_SetError("Cannot set the number of channels"); } - _this->spec.channels = value; + device->spec.channels = value; - /* Set the DSP frequency */ - value = _this->spec.freq; - if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { + // Set the DSP frequency + value = device->spec.freq; + if (ioctl(device->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { perror("SNDCTL_DSP_SPEED"); return SDL_SetError("Couldn't set audio frequency"); } - _this->spec.freq = value; + device->spec.freq = value; /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); - /* Determine the power of two of the fragment size */ - 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"); + /* Determine the power of two of the fragment size + Since apps don't control this in SDL3, and this driver only accepts 8, 16 + bit formats and 1, 2, 4, 8 channels, this should always be a power of 2 already. */ + SDL_assert(SDL_powerof2(device->buffer_size) == device->buffer_size); + + int frag_spec = 0; + while ((0x01U << frag_spec) < device->buffer_size) { + frag_spec++; } frag_spec |= 0x00020000; /* two fragments, for low latency */ @@ -195,13 +175,13 @@ static int DSP_OpenDevice(SDL_AudioDevice *_this, const char *devname) fprintf(stderr, "Requesting %d fragments of size %d\n", (frag_spec >> 16), 1 << (frag_spec & 0xFFFF)); #endif - if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) { + if (ioctl(device->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) { perror("SNDCTL_DSP_SETFRAGMENT"); } #ifdef DEBUG_AUDIO { audio_buf_info info; - ioctl(_this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info); + ioctl(device->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info); fprintf(stderr, "fragments = %d\n", info.fragments); fprintf(stderr, "fragstotal = %d\n", info.fragstotal); fprintf(stderr, "fragsize = %d\n", info.fragsize); @@ -210,44 +190,67 @@ static int DSP_OpenDevice(SDL_AudioDevice *_this, const char *devname) #endif /* 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) { + if (!device->iscapture) { + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (device->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size); + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); } - /* We're ready to rock and roll. :-) */ - return 0; + return 0; // We're ready to rock and roll. :-) } -static void DSP_PlayDevice(SDL_AudioDevice *_this) +static void DSP_WaitDevice(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; - if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) { + const unsigned long ioctlreq = device->iscapture ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE; + struct SDL_PrivateAudioData *h = device->hidden; + + while (!SDL_AtomicGet(&device->shutdown)) { + audio_buf_info info; + const int rc = ioctl(h->audio_fd, ioctlreq, &info); + if (rc < 0) { + if (errno == EAGAIN) { + continue; + } + // Hmm, not much we can do - abort + fprintf(stderr, "dsp WaitDevice ioctl failed (unrecoverable): %s\n", strerror(errno)); + SDL_AudioDeviceDisconnected(device); + return; + } else if (info.bytes < device->buffer_size) { + SDL_Delay(10); + } else { + break; // ready to go! + } + } +} + +static void DSP_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) +{ + struct SDL_PrivateAudioData *h = device->hidden; + if (write(h->audio_fd, buffer, buflen) == -1) { perror("Audio write"); - SDL_OpenedAudioDeviceDisconnected(_this); + SDL_AudioDeviceDisconnected(device); + return; } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen); #endif } -static Uint8 *DSP_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *DSP_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + return device->hidden->mixbuf; } -static int DSP_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int DSP_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { - return (int)read(_this->hidden->audio_fd, buffer, buflen); + return (int)read(device->hidden->audio_fd, buffer, buflen); } -static void DSP_FlushCapture(SDL_AudioDevice *_this) +static void DSP_FlushCapture(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; + struct SDL_PrivateAudioData *h = device->hidden; audio_buf_info info; if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) { while (info.bytes > 0) { @@ -263,17 +266,17 @@ static void DSP_FlushCapture(SDL_AudioDevice *_this) } static SDL_bool InitTimeDevicesExist = SDL_FALSE; -static int look_for_devices_test(int fd) +static SDL_bool 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; + return SDL_FALSE; } static SDL_bool DSP_Init(SDL_AudioDriverImpl *impl) { InitTimeDevicesExist = SDL_FALSE; - SDL_EnumUnixAudioDevices(0, look_for_devices_test); + SDL_EnumUnixAudioDevices(SDL_FALSE, look_for_devices_test); if (!InitTimeDevicesExist) { SDL_SetError("dsp: No such audio device"); return SDL_FALSE; /* maybe try a different backend. */ @@ -282,9 +285,11 @@ static SDL_bool DSP_Init(SDL_AudioDriverImpl *impl) /* Set the function pointers */ impl->DetectDevices = DSP_DetectDevices; impl->OpenDevice = DSP_OpenDevice; + impl->WaitDevice = DSP_WaitDevice; impl->PlayDevice = DSP_PlayDevice; impl->GetDeviceBuf = DSP_GetDeviceBuf; impl->CloseDevice = DSP_CloseDevice; + impl->WaitCaptureDevice = DSP_WaitDevice; impl->CaptureFromDevice = DSP_CaptureFromDevice; impl->FlushCapture = DSP_FlushCapture; @@ -295,7 +300,7 @@ static SDL_bool DSP_Init(SDL_AudioDriverImpl *impl) } AudioBootStrap DSP_bootstrap = { - "dsp", "OSS /dev/dsp standard audio", DSP_Init, SDL_FALSE + "dsp", "Open Sound System (/dev/dsp)", DSP_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_OSS */ diff --git a/src/audio/dsp/SDL_dspaudio.h b/src/audio/dsp/SDL_dspaudio.h index e5bf29ed..abe0c347 100644 --- a/src/audio/dsp/SDL_dspaudio.h +++ b/src/audio/dsp/SDL_dspaudio.h @@ -32,8 +32,6 @@ struct SDL_PrivateAudioData /* Raw mixing buffer */ Uint8 *mixbuf; - int mixlen; }; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ #endif /* SDL_dspaudio_h_ */ diff --git a/src/audio/dummy/SDL_dummyaudio.c b/src/audio/dummy/SDL_dummyaudio.c index 1f12a1a2..bd3002da 100644 --- a/src/audio/dummy/SDL_dummyaudio.c +++ b/src/audio/dummy/SDL_dummyaudio.c @@ -20,39 +20,75 @@ */ #include "SDL_internal.h" -/* Output audio to nowhere... */ +// Output audio to nowhere... #include "../SDL_audio_c.h" #include "SDL_dummyaudio.h" -static int DUMMYAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) -{ - _this->hidden = (void *)0x1; /* just something non-NULL */ +// !!! FIXME: this should be an SDL hint, not an environment variable. +#define DUMMYENVR_IODELAY "SDL_DUMMYAUDIODELAY" - return 0; /* always succeeds. */ +static void DUMMYAUDIO_WaitDevice(SDL_AudioDevice *device) +{ + SDL_Delay(device->hidden->io_delay); } -static int DUMMYAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int DUMMYAUDIO_OpenDevice(SDL_AudioDevice *device) { - /* Delay to make this sort of simulate real audio input. */ - SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq); + const char *envr = SDL_getenv(DUMMYENVR_IODELAY); - /* always return a full buffer of silence. */ - SDL_memset(buffer, _this->spec.silence, buflen); + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (!device->hidden) { + return SDL_OutOfMemory(); + } + + if (!device->iscapture) { + device->hidden->mixbuf = (Uint8 *) SDL_malloc(device->buffer_size); + if (!device->hidden->mixbuf) { + return SDL_OutOfMemory(); + } + } + + device->hidden->io_delay = (Uint32) (envr ? SDL_atoi(envr) : ((device->sample_frames * 1000) / device->spec.freq)); + + return 0; // we're good; don't change reported device format. +} + +static void DUMMYAUDIO_CloseDevice(SDL_AudioDevice *device) +{ + if (device->hidden) { + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); + device->hidden = NULL; + } +} + +static Uint8 *DUMMYAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) +{ + return device->hidden->mixbuf; +} + +static int DUMMYAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ + // always return a full buffer of silence. + SDL_memset(buffer, device->silence_value, buflen); return buflen; } static SDL_bool DUMMYAUDIO_Init(SDL_AudioDriverImpl *impl) { - /* Set the function pointers */ impl->OpenDevice = DUMMYAUDIO_OpenDevice; + impl->CloseDevice = DUMMYAUDIO_CloseDevice; + impl->WaitDevice = DUMMYAUDIO_WaitDevice; + impl->GetDeviceBuf = DUMMYAUDIO_GetDeviceBuf; + impl->WaitCaptureDevice = DUMMYAUDIO_WaitDevice; impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice; impl->OnlyHasDefaultOutputDevice = SDL_TRUE; impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap DUMMYAUDIO_bootstrap = { diff --git a/src/audio/dummy/SDL_dummyaudio.h b/src/audio/dummy/SDL_dummyaudio.h index a4bddb44..d629e0d8 100644 --- a/src/audio/dummy/SDL_dummyaudio.h +++ b/src/audio/dummy/SDL_dummyaudio.h @@ -27,11 +27,8 @@ struct SDL_PrivateAudioData { - /* The file descriptor for the audio device */ - Uint8 *mixbuf; - Uint32 mixlen; - Uint32 write_delay; - Uint32 initial_calls; + Uint8 *mixbuf; // The file descriptor for the audio device + Uint32 io_delay; // miliseconds to sleep in WaitDevice. }; -#endif /* SDL_dummyaudio_h_ */ +#endif // SDL_dummyaudio_h_ diff --git a/src/audio/emscripten/SDL_emscriptenaudio.c b/src/audio/emscripten/SDL_emscriptenaudio.c index cdb4308f..142d9e56 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/src/audio/emscripten/SDL_emscriptenaudio.c @@ -27,15 +27,18 @@ #include -/* !!! 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! */ +// just turn off clang-format for this whole file, this INDENT_OFF stuff on +// each EM_ASM section is ugly. +/* *INDENT-OFF* */ /* clang-format off */ -static void FeedAudioDevice(SDL_AudioDevice *_this, const void *buf, const int buflen) +static Uint8 *EMSCRIPTENAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - const int framelen = (SDL_AUDIO_BITSIZE(_this->spec.format) / 8) * _this->spec.channels; - /* *INDENT-OFF* */ /* clang-format off */ + return device->hidden->mixbuf; +} + +static void EMSCRIPTENAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) +{ + const int framelen = (SDL_AUDIO_BITSIZE(device->spec.format) / 8) * device->spec.channels; MAIN_THREAD_EM_ASM({ var SDL3 = Module['SDL3']; var numChannels = SDL3.audio.currentOutputBuffer['numberOfChannels']; @@ -46,65 +49,25 @@ static void FeedAudioDevice(SDL_AudioDevice *_this, const void *buf, const int b } for (var j = 0; j < $1; ++j) { - channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; /* !!! FIXME: why are these shifts here? */ + channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; // !!! FIXME: why are these shifts here? } } - }, buf, buflen / framelen); -/* *INDENT-ON* */ /* clang-format on */ + }, buffer, buffer_size / framelen); } -static void HandleAudioProcess(SDL_AudioDevice *_this) +static void HandleAudioProcess(SDL_AudioDevice *device) // this fires when the main thread is idle. { - SDL_AudioCallback callback = _this->callbackspec.callback; - const int stream_len = _this->callbackspec.size; - - /* Only do something if audio is enabled */ - if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) { - if (_this->stream) { - SDL_ClearAudioStream(_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. */ - SDL_assert(_this->spec.size == stream_len); - callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); - } else { /* streaming/converting */ - int got; - while (SDL_GetAudioStreamAvailable(_this->stream) < ((int)_this->spec.size)) { - callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); - if (SDL_PutAudioStreamData(_this->stream, _this->work_buffer, stream_len) == -1) { - SDL_ClearAudioStream(_this->stream); - SDL_AtomicSet(&_this->enabled, 0); - break; - } - } - - got = SDL_GetAudioStreamData(_this->stream, _this->work_buffer, _this->spec.size); - SDL_assert((got < 0) || (got == _this->spec.size)); - if (got != _this->spec.size) { - SDL_memset(_this->work_buffer, _this->spec.silence, _this->spec.size); - } - } - - FeedAudioDevice(_this, _this->work_buffer, _this->spec.size); + SDL_OutputAudioThreadIterate(device); } -static void HandleCaptureProcess(SDL_AudioDevice *_this) + +static void EMSCRIPTENAUDIO_FlushCapture(SDL_AudioDevice *device) { - SDL_AudioCallback callback = _this->callbackspec.callback; - const int stream_len = _this->callbackspec.size; + // Do nothing, the new data will just be dropped. +} - /* Only do something if audio is enabled */ - if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) { - SDL_ClearAudioStream(_this->stream); - return; - } - - /* *INDENT-OFF* */ /* clang-format off */ +static int EMSCRIPTENAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ MAIN_THREAD_EM_ASM({ var SDL3 = Module['SDL3']; var numChannels = SDL3.capture.currentCaptureBuffer.numberOfChannels; @@ -114,7 +77,7 @@ static void HandleCaptureProcess(SDL_AudioDevice *_this) throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } - if (numChannels == 1) { /* fastpath this a little for the common (mono) case. */ + if (numChannels == 1) { // fastpath this a little for the common (mono) case. for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } @@ -124,33 +87,22 @@ static void HandleCaptureProcess(SDL_AudioDevice *_this) } } } - }, _this->work_buffer, (_this->spec.size / sizeof(float)) / _this->spec.channels); -/* *INDENT-ON* */ /* clang-format on */ + }, buffer, (buflen / sizeof(float)) / device->spec.channels); - /* okay, we've got an interleaved float32 array in C now. */ - - if (_this->stream == NULL) { /* no conversion necessary. */ - SDL_assert(_this->spec.size == stream_len); - callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); - } else { /* streaming/converting */ - if (SDL_PutAudioStreamData(_this->stream, _this->work_buffer, _this->spec.size) == -1) { - SDL_AtomicSet(&_this->enabled, 0); - } - - while (SDL_GetAudioStreamAvailable(_this->stream) >= stream_len) { - const int got = SDL_GetAudioStreamData(_this->stream, _this->work_buffer, stream_len); - SDL_assert((got < 0) || (got == stream_len)); - 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. */ - } - } + return buflen; } -static void EMSCRIPTENAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void HandleCaptureProcess(SDL_AudioDevice *device) // this fires when the main thread is idle. { - /* *INDENT-OFF* */ /* clang-format off */ + SDL_CaptureAudioThreadIterate(device); +} + +static void EMSCRIPTENAUDIO_CloseDevice(SDL_AudioDevice *device) +{ + if (!device->hidden) { + return; + } + MAIN_THREAD_EM_ASM({ var SDL3 = Module['SDL3']; if ($0) { @@ -188,29 +140,23 @@ static void EMSCRIPTENAUDIO_CloseDevice(SDL_AudioDevice *_this) SDL3.audioContext.close(); SDL3.audioContext = undefined; } - }, _this->iscapture); -/* *INDENT-ON* */ /* clang-format on */ + }, device->iscapture); -#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */ - SDL_free(_this->hidden); -#endif + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); + device->hidden = NULL; + + SDL_AudioThreadFinalize(device); } - EM_JS_DEPS(sdlaudio, "$autoResumeAudioContext,$dynCall"); -static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *device) { - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; - SDL_bool iscapture = _this->iscapture; - int result; + // based on parts of library_sdl.js - /* based on parts of library_sdl.js */ - - /* *INDENT-OFF* */ /* clang-format off */ - /* create context */ - result = MAIN_THREAD_EM_ASM_INT({ + // create context + const int result = MAIN_THREAD_EM_ASM_INT({ if (typeof(Module['SDL3']) === 'undefined') { Module['SDL3'] = {}; } @@ -232,57 +178,41 @@ static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devnam } } return SDL3.audioContext === undefined ? -1 : 0; - }, iscapture); -/* *INDENT-ON* */ /* clang-format on */ + }, device->iscapture); if (result < 0) { return SDL_SetError("Web Audio API is not available!"); } - closefmts = SDL_ClosestAudioFormats(_this->spec.format); - while ((test_format = *(closefmts++)) != 0) { - switch (test_format) { - case SDL_AUDIO_F32: /* web audio only supports floats */ - break; - default: - continue; - } - break; - } + device->spec.format = SDL_AUDIO_F32; // web audio only supports floats - if (!test_format) { - /* Didn't find a compatible 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 SDL3 namespace? --ryan. */ - _this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + // Initialize all variables that we clean on shutdown + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); -#endif - _this->hidden = (struct SDL_PrivateAudioData *)0x1; - /* limit to native freq */ - _this->spec.freq = EM_ASM_INT({ - var SDL3 = Module['SDL3']; - return SDL3.audioContext.sampleRate; - }); + // limit to native freq + device->spec.freq = EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; }); - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); - /* *INDENT-OFF* */ /* clang-format off */ - if (iscapture) { + if (!device->iscapture) { + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (device->hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); + } + + if (device->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 to access the raw PCM samples and push them to the SDL app's callback. From there, we "process" the audio data into silence - and forget about it. */ + and forget about it. - /* This should, strictly speaking, use MediaRecorder for capture, but + This should, strictly speaking, use MediaRecorder for capture, but this API is cleaner to use and better supported, and fires a callback whenever there's enough data to fire down into the app. The downside is that we are spending CPU time silencing a buffer @@ -317,7 +247,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devnam //console.log('SDL audio capture: we DO NOT have a microphone! (' + error.name + ')...leaving silence callback running.'); }; - /* we write silence to the audio callback until the microphone is available (user approves use, etc). */ + // we write silence to the audio callback until the microphone is available (user approves use, etc). SDL3.capture.silenceBuffer = SDL3.audioContext.createBuffer($0, $1, SDL3.audioContext.sampleRate); SDL3.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { @@ -332,9 +262,9 @@ static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devnam } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } - }, _this->spec.channels, _this->spec.samples, HandleCaptureProcess, _this); + }, device->spec.channels, device->sample_frames, HandleCaptureProcess, device); } else { - /* setup a ScriptProcessorNode */ + // setup a ScriptProcessorNode MAIN_THREAD_EM_ASM({ var SDL3 = Module['SDL3']; SDL3.audio.scriptProcessorNode = SDL3.audioContext['createScriptProcessor']($1, 0, $0); @@ -344,33 +274,29 @@ static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devnam dynCall('vi', $2, [$3]); }; SDL3.audio.scriptProcessorNode['connect'](SDL3.audioContext['destination']); - }, _this->spec.channels, _this->spec.samples, HandleAudioProcess, _this); + }, device->spec.channels, device->sample_frames, HandleAudioProcess, device); } -/* *INDENT-ON* */ /* clang-format on */ return 0; } -static void EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice *device) -{ -} - 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->GetDeviceBuf = EMSCRIPTENAUDIO_GetDeviceBuf; + impl->PlayDevice = EMSCRIPTENAUDIO_PlayDevice; + impl->FlushCapture = EMSCRIPTENAUDIO_FlushCapture; + impl->CaptureFromDevice = EMSCRIPTENAUDIO_CaptureFromDevice; impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - /* no threads here */ - impl->LockDevice = impl->UnlockDevice = EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock; + // technically, this is just runs in idle time in the main thread, but it's close enough to a "thread" for our purposes. impl->ProvidesOwnCallbackThread = SDL_TRUE; - /* *INDENT-OFF* */ /* clang-format off */ - /* check availability */ + // check availability available = MAIN_THREAD_EM_ASM_INT({ if (typeof(AudioContext) !== 'undefined') { return true; @@ -378,14 +304,12 @@ static SDL_bool EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl *impl) return true; } return false; - }); -/* *INDENT-ON* */ /* clang-format on */ + }) ? SDL_TRUE : SDL_FALSE; if (!available) { SDL_SetError("No audio context available"); } - /* *INDENT-OFF* */ /* clang-format off */ capture_available = available && MAIN_THREAD_EM_ASM_INT({ if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; @@ -393,8 +317,7 @@ static SDL_bool EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl *impl) return true; } return false; - }); -/* *INDENT-ON* */ /* clang-format on */ + }) ? SDL_TRUE : SDL_FALSE; impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE; impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE; @@ -406,4 +329,6 @@ AudioBootStrap EMSCRIPTENAUDIO_bootstrap = { "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */ +/* *INDENT-ON* */ /* clang-format on */ + +#endif // SDL_AUDIO_DRIVER_EMSCRIPTEN diff --git a/src/audio/emscripten/SDL_emscriptenaudio.h b/src/audio/emscripten/SDL_emscriptenaudio.h index db9c737f..cc2f49b2 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.h +++ b/src/audio/emscripten/SDL_emscriptenaudio.h @@ -27,7 +27,7 @@ struct SDL_PrivateAudioData { - int unused; + Uint8 *mixbuf; }; #endif /* SDL_emscriptenaudio_h_ */ diff --git a/src/audio/haiku/SDL_haikuaudio.cc b/src/audio/haiku/SDL_haikuaudio.cc index c9915839..c34142f3 100644 --- a/src/audio/haiku/SDL_haikuaudio.cc +++ b/src/audio/haiku/SDL_haikuaudio.cc @@ -22,7 +22,7 @@ #ifdef SDL_AUDIO_DRIVER_HAIKU -/* Allow access to the audio stream on Haiku */ +// Allow access to the audio stream on Haiku #include #include @@ -38,58 +38,45 @@ extern "C" } - -/* !!! 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, - const media_raw_audio_format & format) +static Uint8 *HAIKUAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - 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_ClearAudioStream(audio->stream); - } - SDL_memset(stream, audio->spec.silence, len); - } else { - SDL_assert(audio->spec.size == len); - - if (audio->stream == NULL) { /* 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_GetAudioStreamAvailable(audio->stream) < ilen) { - callback(audio->callbackspec.userdata, audio->work_buffer, stream_len); - if (SDL_PutAudioStreamData(audio->stream, audio->work_buffer, stream_len) == -1) { - SDL_ClearAudioStream(audio->stream); - SDL_AtomicSet(&audio->enabled, 0); - break; - } - } - - const int got = SDL_GetAudioStreamData(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); + SDL_assert(device->hidden->current_buffer != NULL); + SDL_assert(device->hidden->current_buffer_len > 0); + *buffer_size = device->hidden->current_buffer_len; + return device->hidden->current_buffer; } -static void HAIKUAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void HAIKUAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { - if (_this->hidden->audio_obj) { - _this->hidden->audio_obj->Stop(); - delete _this->hidden->audio_obj; + // We already wrote our output right into the BSoundPlayer's callback's stream. Just clean up our stuff. + SDL_assert(device->hidden->current_buffer != NULL); + SDL_assert(device->hidden->current_buffer_len > 0); + device->hidden->current_buffer = NULL; + device->hidden->current_buffer_len = 0; +} + +// The Haiku callback for handling the audio buffer +static void FillSound(void *data, void *stream, size_t len, const media_raw_audio_format & format) +{ + SDL_AudioDevice *device = (SDL_AudioDevice *)data; + SDL_assert(device->hidden->current_buffer == NULL); + SDL_assert(device->hidden->current_buffer_len == 0); + device->hidden->current_buffer = (Uint8 *) stream; + device->hidden->current_buffer_len = (int) len; + SDL_OutputAudioThreadIterate(device); +} + +static void HAIKUAUDIO_CloseDevice(SDL_AudioDevice *device) +{ + if (device->hidden) { + if (device->hidden->audio_obj) { + device->hidden->audio_obj->Stop(); + delete device->hidden->audio_obj; + } + delete device->hidden; + device->hidden = NULL; + SDL_AudioThreadFinalize(device); } - delete _this->hidden; } @@ -115,26 +102,24 @@ static inline void UnmaskSignals(sigset_t * omask) } -static int HAIKUAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int HAIKUAUDIO_OpenDevice(SDL_AudioDevice *device) { - media_raw_audio_format format; - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; - - /* Initialize all variables that we clean on shutdown */ - _this->hidden = new SDL_PrivateAudioData; - if (_this->hidden == NULL) { + // Initialize all variables that we clean on shutdown + device->hidden = new SDL_PrivateAudioData; + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); + SDL_zerop(device->hidden); - /* Parse the audio format and fill the Be raw audio format */ + // Parse the audio format and fill the Be raw audio format + media_raw_audio_format format; SDL_zero(format); format.byte_order = B_MEDIA_LITTLE_ENDIAN; - format.frame_rate = (float) _this->spec.freq; - format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */ + format.frame_rate = (float) device->spec.freq; + format.channel_count = device->spec.channels; // !!! FIXME: support > 2? - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { switch (test_format) { case SDL_AUDIO_S8: @@ -178,31 +163,30 @@ static int HAIKUAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) break; } - if (!test_format) { /* shouldn't happen, but just in case... */ - return SDL_SetError("%s: Unsupported audio format", "haiku"); + if (!test_format) { // shouldn't happen, but just in case... + return SDL_SetError("HAIKU: Unsupported audio format"); } - _this->spec.format = test_format; + device->spec.format = test_format; - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); + // Calculate the final parameters for this audio specification + SDL_UpdatedAudioDeviceFormat(device); - format.buffer_size = _this->spec.size; + format.buffer_size = device->buffer_size; - /* Subscribe to the audio stream (creates a new thread) */ + // Subscribe to the audio stream (creates a new thread) sigset_t omask; MaskSignals(&omask); - _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio", - FillSound, NULL, _this); + device->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio", + FillSound, NULL, device); UnmaskSignals(&omask); - if (_this->hidden->audio_obj->Start() == B_NO_ERROR) { - _this->hidden->audio_obj->SetHasData(true); + if (device->hidden->audio_obj->Start() == B_NO_ERROR) { + device->hidden->audio_obj->SetHasData(true); } else { - return SDL_SetError("Unable to start Be audio"); + return SDL_SetError("Unable to start Haiku audio"); } - /* We're running! */ - return 0; + return 0; // We're running! } static void HAIKUAUDIO_Deinitialize(void) @@ -210,29 +194,29 @@ static void HAIKUAUDIO_Deinitialize(void) SDL_QuitBeApp(); } -static SDL_bool 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 SDL_FALSE; } - /* Set the function pointers */ + // Set the function pointers impl->OpenDevice = HAIKUAUDIO_OpenDevice; + impl->GetDeviceBuf = HAIKUAUDIO_GetDeviceBuf; + impl->PlayDevice = HAIKUAUDIO_PlayDevice; impl->CloseDevice = HAIKUAUDIO_CloseDevice; impl->Deinitialize = HAIKUAUDIO_Deinitialize; impl->ProvidesOwnCallbackThread = SDL_TRUE; impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } -extern "C" -{ - extern AudioBootStrap HAIKUAUDIO_bootstrap; -} + +extern "C" { extern AudioBootStrap HAIKUAUDIO_bootstrap; } + AudioBootStrap HAIKUAUDIO_bootstrap = { "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_HAIKU */ +#endif // SDL_AUDIO_DRIVER_HAIKU diff --git a/src/audio/haiku/SDL_haikuaudio.h b/src/audio/haiku/SDL_haikuaudio.h index c8ecd654..c78c6061 100644 --- a/src/audio/haiku/SDL_haikuaudio.h +++ b/src/audio/haiku/SDL_haikuaudio.h @@ -28,6 +28,8 @@ struct SDL_PrivateAudioData { BSoundPlayer *audio_obj; + Uint8 *current_buffer; + int current_buffer_len; }; #endif /* SDL_haikuaudio_h_ */ diff --git a/src/audio/jack/SDL_jackaudio.c b/src/audio/jack/SDL_jackaudio.c index 60deac3a..3e3ed208 100644 --- a/src/audio/jack/SDL_jackaudio.c +++ b/src/audio/jack/SDL_jackaudio.c @@ -135,9 +135,7 @@ static int load_jack_syms(void) static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. */ { - SDL_AudioDevice *_this = (SDL_AudioDevice *)arg; - SDL_OpenedAudioDeviceDisconnected(_this); - SDL_PostSemaphore(_this->hidden->iosem); /* unblock the SDL thread. */ + SDL_AudioDeviceDisconnected((SDL_AudioDevice *)arg); } // !!! FIXME: implement and register these! @@ -146,124 +144,117 @@ static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. * static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *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; - int channelsi; + SDL_assert(nframes == ((SDL_AudioDevice *)arg)->sample_frames); + SDL_OutputAudioThreadIterate((SDL_AudioDevice *)arg); + return 0; +} - if (!SDL_AtomicGet(&_this->enabled)) { - /* silence the buffer to avoid repeats and corruption. */ - SDL_memset(_this->hidden->iobuffer, '\0', _this->spec.size); - } +static void JACK_PlayDevice(SDL_AudioDevice *device, const Uint8 *ui8buffer, int buflen) +{ + const float *buffer = (float *) ui8buffer; + jack_port_t **ports = device->hidden->sdlports; + const int total_channels = device->spec.channels; + const int total_frames = device->sample_frames; + const jack_nframes_t nframes = (jack_nframes_t) device->sample_frames; - for (channelsi = 0; channelsi < total_channels; channelsi++) { + for (int channelsi = 0; channelsi < total_channels; channelsi++) { float *dst = (float *)JACK_jack_port_get_buffer(ports[channelsi], nframes); if (dst) { - const float *src = _this->hidden->iobuffer + channelsi; - int framesi; - for (framesi = 0; framesi < total_frames; framesi++) { + const float *src = buffer + channelsi; + for (int framesi = 0; framesi < total_frames; framesi++) { *(dst++) = *src; src += total_channels; } } } - - SDL_PostSemaphore(_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(SDL_AudioDevice *_this) +static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - if (SDL_AtomicGet(&_this->enabled)) { - if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) { - SDL_OpenedAudioDeviceDisconnected(_this); - } - } -} - -static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *_this) -{ - return (Uint8 *)_this->hidden->iobuffer; + return (Uint8 *)device->hidden->iobuffer; } static int jackProcessCaptureCallback(jack_nframes_t nframes, void *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); - if (src) { - float *dst = _this->hidden->iobuffer + channelsi; - int framesi; - for (framesi = 0; framesi < total_frames; framesi++) { - *dst = *(src++); - dst += total_channels; - } - } - } - } - - SDL_PostSemaphore(_this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */ + SDL_assert(nframes == ((SDL_AudioDevice *)arg)->sample_frames); + SDL_CaptureAudioThreadIterate((SDL_AudioDevice *)arg); return 0; } -static int JACK_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int JACK_CaptureFromDevice(SDL_AudioDevice *device, void *vbuffer, int buflen) { - SDL_assert(buflen == _this->spec.size); /* we always fill a full buffer. */ + float *buffer = (float *) vbuffer; + jack_port_t **ports = device->hidden->sdlports; + const int total_channels = device->spec.channels; + const int total_frames = device->sample_frames; + const jack_nframes_t nframes = (jack_nframes_t) device->sample_frames; - /* Wait for JACK to fill the iobuffer */ - if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) { - return -1; + for (int channelsi = 0; channelsi < total_channels; channelsi++) { + const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes); + if (src) { + float *dst = buffer + channelsi; + for (int framesi = 0; framesi < total_frames; framesi++) { + *dst = *(src++); + dst += total_channels; + } + } } - SDL_memcpy(buffer, _this->hidden->iobuffer, buflen); return buflen; } -static void JACK_FlushCapture(SDL_AudioDevice *_this) +static void JACK_FlushCapture(SDL_AudioDevice *device) { - SDL_WaitSemaphore(_this->hidden->iosem); + // do nothing, the data will just be replaced next callback. } -static void JACK_CloseDevice(SDL_AudioDevice *_this) +static void JACK_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->client) { - JACK_jack_deactivate(_this->hidden->client); + if (device->hidden) { + if (device->hidden->client) { + JACK_jack_deactivate(device->hidden->client); - if (_this->hidden->sdlports) { - const int channels = _this->spec.channels; - int i; - for (i = 0; i < channels; i++) { - JACK_jack_port_unregister(_this->hidden->client, _this->hidden->sdlports[i]); + if (device->hidden->sdlports) { + const int channels = device->spec.channels; + int i; + for (i = 0; i < channels; i++) { + JACK_jack_port_unregister(device->hidden->client, device->hidden->sdlports[i]); + } + SDL_free(device->hidden->sdlports); } - SDL_free(_this->hidden->sdlports); + + JACK_jack_client_close(device->hidden->client); } - JACK_jack_client_close(_this->hidden->client); - } + SDL_free(device->hidden->iobuffer); + SDL_free(device->hidden); + device->hidden = NULL; - if (_this->hidden->iosem) { - SDL_DestroySemaphore(_this->hidden->iosem); + SDL_AudioThreadFinalize(device); } - - SDL_free(_this->hidden->iobuffer); - SDL_free(_this->hidden); } -static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) +// !!! FIXME: unify this (PulseAudio has a getAppName, Pipewire has a thing, etc +static const char *GetJackAppName(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; + } + return "SDL Application"; +} + +static int JACK_OpenDevice(SDL_AudioDevice *device) { /* 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; + SDL_bool iscapture = device->iscapture; const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput; const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput; const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback; @@ -277,14 +268,13 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) int i; /* Initialize all variables that we clean on shutdown */ - _this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - /* !!! FIXME: we _still_ need an API to specify an app name */ - client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL); - _this->hidden->client = client; + client = JACK_jack_client_open(GetJackAppName(), JackNoStartServer, &status, NULL); + device->hidden->client = client; if (client == NULL) { return SDL_SetError("Can't open JACK client"); } @@ -317,28 +307,24 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) /* !!! 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. */ - _this->spec.format = SDL_AUDIO_F32SYS; - _this->spec.freq = JACK_jack_get_sample_rate(client); - _this->spec.channels = channels; - _this->spec.samples = JACK_jack_get_buffer_size(client); + device->spec.format = SDL_AUDIO_F32SYS; + device->spec.freq = JACK_jack_get_sample_rate(client); + device->spec.channels = channels; + device->sample_frames = JACK_jack_get_buffer_size(client); - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); - _this->hidden->iosem = SDL_CreateSemaphore(0); - if (!_this->hidden->iosem) { - SDL_free(audio_ports); - return -1; /* error was set by SDL_CreateSemaphore */ - } - - _this->hidden->iobuffer = (float *)SDL_calloc(1, _this->spec.size); - if (!_this->hidden->iobuffer) { - SDL_free(audio_ports); - return SDL_OutOfMemory(); + if (!device->iscapture) { + device->hidden->iobuffer = (float *)SDL_calloc(1, device->buffer_size); + if (!device->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) { + device->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *)); + if (device->hidden->sdlports == NULL) { SDL_free(audio_ports); return SDL_OutOfMemory(); } @@ -346,19 +332,19 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) for (i = 0; i < channels; i++) { char portname[32]; (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) { + device->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0); + if (device->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) { + if (JACK_jack_set_process_callback(client, callback, device) != 0) { SDL_free(audio_ports); return SDL_SetError("JACK: Couldn't set process callback"); } - JACK_jack_on_shutdown(client, jackShutdownCallback, _this); + JACK_jack_on_shutdown(client, jackShutdownCallback, device); if (JACK_jack_activate(client) != 0) { SDL_free(audio_ports); @@ -367,7 +353,7 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) /* once activated, we can connect all the ports. */ for (i = 0; i < channels; i++) { - const char *sdlport = JACK_jack_port_name(_this->hidden->sdlports[i]); + const char *sdlport = JACK_jack_port_name(device->hidden->sdlports[i]); 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) { @@ -406,8 +392,8 @@ static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl) /* Set the function pointers */ impl->OpenDevice = JACK_OpenDevice; - impl->WaitDevice = JACK_WaitDevice; impl->GetDeviceBuf = JACK_GetDeviceBuf; + impl->PlayDevice = JACK_PlayDevice; impl->CloseDevice = JACK_CloseDevice; impl->Deinitialize = JACK_Deinitialize; impl->CaptureFromDevice = JACK_CaptureFromDevice; @@ -415,6 +401,7 @@ static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl) impl->OnlyHasDefaultOutputDevice = SDL_TRUE; impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; + impl->ProvidesOwnCallbackThread = SDL_TRUE; return SDL_TRUE; /* this audio target is available. */ } diff --git a/src/audio/jack/SDL_jackaudio.h b/src/audio/jack/SDL_jackaudio.h index 91f5680d..a8cf81d4 100644 --- a/src/audio/jack/SDL_jackaudio.h +++ b/src/audio/jack/SDL_jackaudio.h @@ -28,9 +28,8 @@ struct SDL_PrivateAudioData { jack_client_t *client; - SDL_Semaphore *iosem; - float *iobuffer; jack_port_t **sdlports; + float *iobuffer; }; #endif /* SDL_jackaudio_h_ */ diff --git a/src/audio/n3ds/SDL_n3dsaudio.c b/src/audio/n3ds/SDL_n3dsaudio.c index 1d0bff66..f17ac560 100644 --- a/src/audio/n3ds/SDL_n3dsaudio.c +++ b/src/audio/n3ds/SDL_n3dsaudio.c @@ -22,7 +22,7 @@ #ifdef SDL_AUDIO_DRIVER_N3DS -/* N3DS Audio driver */ +// N3DS Audio driver #include "../SDL_sysaudio.h" #include "SDL_n3dsaudio.h" @@ -32,27 +32,14 @@ static dspHookCookie dsp_hook; static SDL_AudioDevice *audio_device; -static void FreePrivateData(SDL_AudioDevice *_this); -static int FindAudioFormat(SDL_AudioDevice *_this); - -static SDL_INLINE void contextLock(SDL_AudioDevice *_this) +static SDL_INLINE void contextLock(SDL_AudioDevice *device) { - LightLock_Lock(&_this->hidden->lock); + LightLock_Lock(&device->hidden->lock); } -static SDL_INLINE void contextUnlock(SDL_AudioDevice *_this) +static SDL_INLINE void contextUnlock(SDL_AudioDevice *device) { - LightLock_Unlock(&_this->hidden->lock); -} - -static void N3DSAUD_LockAudio(SDL_AudioDevice *_this) -{ - contextLock(_this); -} - -static void N3DSAUD_UnlockAudio(SDL_AudioDevice *_this) -{ - contextUnlock(_this); + LightLock_Unlock(&device->hidden->lock); } static void N3DSAUD_DspHook(DSP_HookType hook) @@ -60,46 +47,46 @@ 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); + SDL_AudioDeviceDisconnected(audio_device); CondVar_Broadcast(&audio_device->hidden->cv); contextUnlock(audio_device); } } -static void AudioFrameFinished(void *device) +static void AudioFrameFinished(void *vdevice) { bool shouldBroadcast = false; unsigned i; - SDL_AudioDevice *_this = (SDL_AudioDevice *)device; + SDL_AudioDevice *device = (SDL_AudioDevice *)vdevice; - contextLock(_this); + contextLock(device); for (i = 0; i < NUM_BUFFERS; i++) { - if (_this->hidden->waveBuf[i].status == NDSP_WBUF_DONE) { - _this->hidden->waveBuf[i].status = NDSP_WBUF_FREE; + if (device->hidden->waveBuf[i].status == NDSP_WBUF_DONE) { + device->hidden->waveBuf[i].status = NDSP_WBUF_FREE; shouldBroadcast = SDL_TRUE; } } if (shouldBroadcast) { - CondVar_Broadcast(&_this->hidden->cv); + CondVar_Broadcast(&device->hidden->cv); } - contextUnlock(_this); + contextUnlock(device); } -static int N3DSAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int N3DSAUDIO_OpenDevice(SDL_AudioDevice *device) { Result ndsp_init_res; Uint8 *data_vaddr; float mix[12]; - _this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - /* Initialise the DSP service */ + // 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)) { @@ -110,173 +97,180 @@ static int N3DSAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) return -1; } - /* Initialise internal state */ - LightLock_Init(&_this->hidden->lock); - CondVar_Init(&_this->hidden->cv); + // Initialise internal state + LightLock_Init(&device->hidden->lock); + CondVar_Init(&device->hidden->cv); - if (_this->spec.channels > 2) { - _this->spec.channels = 2; + if (device->spec.channels > 2) { + device->spec.channels = 2; } - /* Should not happen but better be safe. */ - if (FindAudioFormat(_this) < 0) { + Uint32 format = 0; + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); + while ((test_format = *(closefmts++)) != 0) { + if (test_format == SDL_AUDIO_S8) { // Signed 8-bit audio supported + format = (device->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM8 : NDSP_FORMAT_MONO_PCM8; + break; + } else if (test_format == SDL_AUDIO_S16) { // Signed 16-bit audio supported + format = (device->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM16 : NDSP_FORMAT_MONO_PCM16; + break; + } + } + + if (!test_format) { // shouldn't happen, but just in case... return SDL_SetError("No supported audio format found."); } - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); + device->spec.format = test_format; - /* Allocate mixing buffer */ - if (_this->spec.size >= SDL_MAX_UINT32 / 2) { + // Update the fragment size as size in bytes + SDL_UpdatedAudioDeviceFormat(device); + + // Allocate mixing buffer + if (device->buffer_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 == NULL) { + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (device->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size); + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); - data_vaddr = (Uint8 *)linearAlloc(_this->hidden->mixlen * NUM_BUFFERS); + data_vaddr = (Uint8 *)linearAlloc(device->buffer_size * NUM_BUFFERS); if (data_vaddr == NULL) { return SDL_OutOfMemory(); } - SDL_memset(data_vaddr, 0, _this->hidden->mixlen * NUM_BUFFERS); - DSP_FlushDataCache(data_vaddr, _this->hidden->mixlen * NUM_BUFFERS); + SDL_memset(data_vaddr, 0, device->buffer_size * NUM_BUFFERS); + DSP_FlushDataCache(data_vaddr, device->buffer_size * NUM_BUFFERS); - _this->hidden->nextbuf = 0; - _this->hidden->channels = _this->spec.channels; - _this->hidden->samplerate = _this->spec.freq; + device->hidden->nextbuf = 0; ndspChnReset(0); ndspChnSetInterp(0, NDSP_INTERP_LINEAR); - ndspChnSetRate(0, _this->spec.freq); - ndspChnSetFormat(0, _this->hidden->format); + ndspChnSetRate(0, device->spec.freq); + ndspChnSetFormat(0, format); - SDL_memset(mix, 0, sizeof(mix)); - mix[0] = 1.0; - mix[1] = 1.0; + SDL_zeroa(mix); + mix[0] = mix[1] = 1.0f; ndspChnSetMix(0, mix); - SDL_memset(_this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS); + SDL_memset(device->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS); + const int sample_frame_size = device->spec.channels * (SDL_AUDIO_BITSIZE(device->spec.format) / 8); 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; + device->hidden->waveBuf[i].data_vaddr = data_vaddr; + device->hidden->waveBuf[i].nsamples = device->buffer_size / sample_frame_size; + data_vaddr += device->buffer_size; } - /* Setup callback */ - audio_device = _this; - ndspSetCallback(AudioFrameFinished, _this); + // Setup callback + audio_device = device; + ndspSetCallback(AudioFrameFinished, device); dspHook(&dsp_hook, N3DSAUD_DspHook); return 0; } -static int N3DSAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static void N3DSAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - /* Delay to make this sort of simulate real audio input. */ - SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq); + contextLock(device); - /* always return a full buffer of silence. */ - SDL_memset(buffer, _this->spec.silence, buflen); - return buflen; -} + const size_t nextbuf = device->hidden->nextbuf; -static void N3DSAUDIO_PlayDevice(SDL_AudioDevice *_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); + if (device->hidden->isCancelled || + device->hidden->waveBuf[nextbuf].status != NDSP_WBUF_FREE) { + contextUnlock(device); return; } - _this->hidden->nextbuf = (nextbuf + 1) % NUM_BUFFERS; + device->hidden->nextbuf = (nextbuf + 1) % NUM_BUFFERS; - contextUnlock(_this); + contextUnlock(device); - SDL_memcpy((void *)_this->hidden->waveBuf[nextbuf].data_vaddr, - _this->hidden->mixbuf, sampleLen); - DSP_FlushDataCache(_this->hidden->waveBuf[nextbuf].data_vaddr, sampleLen); + SDL_memcpy((void *)device->hidden->waveBuf[nextbuf].data_vaddr, buffer, buflen); + DSP_FlushDataCache(device->hidden->waveBuf[nextbuf].data_vaddr, buflen); - ndspChnWaveBufAdd(0, &_this->hidden->waveBuf[nextbuf]); + ndspChnWaveBufAdd(0, &device->hidden->waveBuf[nextbuf]); } -static void N3DSAUDIO_WaitDevice(SDL_AudioDevice *_this) +static void N3DSAUDIO_WaitDevice(SDL_AudioDevice *device) { - contextLock(_this); - while (!_this->hidden->isCancelled && - _this->hidden->waveBuf[_this->hidden->nextbuf].status != NDSP_WBUF_FREE) { - CondVar_Wait(&_this->hidden->cv, &_this->hidden->lock); + contextLock(device); + while (!device->hidden->isCancelled && !SDL_AtomicGet(&device->shutdown) && + device->hidden->waveBuf[device->hidden->nextbuf].status != NDSP_WBUF_FREE) { + CondVar_Wait(&device->hidden->cv, &device->hidden->lock); } - contextUnlock(_this); + contextUnlock(device); } -static Uint8 *N3DSAUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *N3DSAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + return device->hidden->mixbuf; } -static void N3DSAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void N3DSAUDIO_CloseDevice(SDL_AudioDevice *device) { - contextLock(_this); + if (!device->hidden) { + return; + } + + contextLock(device); dspUnhook(&dsp_hook); ndspSetCallback(NULL, NULL); - if (!_this->hidden->isCancelled) { + if (!device->hidden->isCancelled) { ndspChnReset(0); - SDL_memset(_this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS); - CondVar_Broadcast(&_this->hidden->cv); + SDL_memset(device->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS); + CondVar_Broadcast(&device->hidden->cv); } - contextUnlock(_this); + contextUnlock(device); ndspExit(); - FreePrivateData(_this); + if (device->hidden->waveBuf[0].data_vaddr) { + linearFree((void *)device->hidden->waveBuf[0].data_vaddr); + } + + if (device->hidden->mixbuf) { + SDL_free(device->hidden->mixbuf); + device->hidden->mixbuf = NULL; + } + + SDL_free(device->hidden); + device->hidden = NULL; } -static void N3DSAUDIO_ThreadInit(SDL_AudioDevice *_this) +static void N3DSAUDIO_ThreadInit(SDL_AudioDevice *device) { s32 current_priority; svcGetThreadPriority(¤t_priority, CUR_THREAD_HANDLE); current_priority--; - /* 0x18 is reserved for video, 0x30 is the default for main thread */ + // 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->LockDevice = N3DSAUD_LockAudio; - impl->UnlockDevice = N3DSAUD_UnlockAudio; impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - /* Should be possible, but micInit would fail */ + // Should be possible, but micInit would fail impl->HasCaptureSupport = SDL_FALSE; - impl->CaptureFromDevice = N3DSAUDIO_CaptureFromDevice; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap N3DSAUDIO_bootstrap = { @@ -286,51 +280,4 @@ AudioBootStrap N3DSAUDIO_bootstrap = { 0 }; -/** - * Cleans up all allocated memory, safe to call with null pointers - */ -static void FreePrivateData(SDL_AudioDevice *_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(SDL_AudioDevice *_this) -{ - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(_this->spec.format); - while ((test_format = *(closefmts++)) != 0) { - _this->spec.format = test_format; - switch (test_format) { - case SDL_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; - return 0; - case SDL_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; - return 0; - } - } - - return -1; -} - -#endif /* SDL_AUDIO_DRIVER_N3DS */ +#endif // SDL_AUDIO_DRIVER_N3DS diff --git a/src/audio/n3ds/SDL_n3dsaudio.h b/src/audio/n3ds/SDL_n3dsaudio.h index 88b9ffcb..83f9ca83 100644 --- a/src/audio/n3ds/SDL_n3dsaudio.h +++ b/src/audio/n3ds/SDL_n3dsaudio.h @@ -30,12 +30,6 @@ 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; diff --git a/src/audio/netbsd/SDL_netbsdaudio.c b/src/audio/netbsd/SDL_netbsdaudio.c index 6474aa86..4165b056 100644 --- a/src/audio/netbsd/SDL_netbsdaudio.c +++ b/src/audio/netbsd/SDL_netbsdaudio.c @@ -22,10 +22,7 @@ #ifdef SDL_AUDIO_DRIVER_NETBSD -/* - * Driver for native NetBSD audio(4). - * nia@NetBSD.org - */ +// Driver for native NetBSD audio(4). #include #include @@ -41,26 +38,26 @@ #include "../SDL_audiodev_c.h" #include "SDL_netbsdaudio.h" -/* #define DEBUG_AUDIO */ +//#define DEBUG_AUDIO -static void NETBSDAUDIO_DetectDevices(void) +static void NETBSDAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - SDL_EnumUnixAudioDevices(0, NULL); + SDL_EnumUnixAudioDevices(SDL_FALSE, NULL); } -static void NETBSDAUDIO_Status(SDL_AudioDevice *_this) +static void NETBSDAUDIO_Status(SDL_AudioDevice *device) { #ifdef DEBUG_AUDIO /* *INDENT-OFF* */ /* clang-format off */ audio_info_t info; const struct audio_prinfo *prinfo; - if (ioctl(_this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { + if (ioctl(device->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { fprintf(stderr, "AUDIO_GETINFO failed.\n"); return; } - prinfo = _this->iscapture ? &info.record : &info.play; + prinfo = device->iscapture ? &info.record : &info.play; fprintf(stderr, "\n" "[%s info]\n" @@ -77,7 +74,7 @@ static void NETBSDAUDIO_Status(SDL_AudioDevice *_this) "waiting : %s\n" "active : %s\n" "", - _this->iscapture ? "record" : "play", + device->iscapture ? "record" : "play", prinfo->buffer_size, prinfo->sample_rate, prinfo->channels, @@ -103,7 +100,7 @@ static void NETBSDAUDIO_Status(SDL_AudioDevice *_this) info.blocksize, info.hiwat, info.lowat, (info.mode == AUMODE_PLAY) ? "PLAY" - : (info.mode = AUMODE_RECORD) ? "RECORD" + : (info.mode == AUMODE_RECORD) ? "RECORD" : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" : "?")); fprintf(stderr, "\n" @@ -111,23 +108,46 @@ static void NETBSDAUDIO_Status(SDL_AudioDevice *_this) "format : 0x%x\n" "size : %u\n" "", - _this->spec.format, - _this->spec.size); + device->spec.format, + device->buffer_size); /* *INDENT-ON* */ /* clang-format on */ -#endif /* DEBUG_AUDIO */ +#endif // DEBUG_AUDIO } -static void NETBSDAUDIO_PlayDevice(SDL_AudioDevice *_this) +static void NETBSDAUDIO_WaitDevice(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; - int written; + const SDL_bool iscapture = device->iscapture; + while (!SDL_AtomicGet(&device->shutdown)) { + audio_info_t info; + const int rc = ioctl(device->hidden->audio_fd, AUDIO_GETINFO, &info); + if (rc < 0) { + if (errno == EAGAIN) { + continue; + } + // Hmm, not much we can do - abort + fprintf(stderr, "netbsdaudio WaitDevice ioctl failed (unrecoverable): %s\n", strerror(errno)); + SDL_AudioDeviceDisconnected(device); + return; + } + const size_t remain = (size_t)((iscapture ? info.record.seek : info.play.seek) * (SDL_AUDIO_BITSIZE(device->spec.format) / 8)); + if (!iscapture && (remain >= device->buffer_size)) { + SDL_Delay(10); + } else if (iscapture && (remain < device->buffer_size)) { + SDL_Delay(10); + } else { + break; /* ready to go! */ + } + } +} - /* Write the audio data */ - written = write(h->audio_fd, h->mixbuf, h->mixlen); +static void NETBSDAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) +{ + struct SDL_PrivateAudioData *h = device->hidden; + const int written = write(h->audio_fd, buffer, buflen); if (written == -1) { - /* Non recoverable error has occurred. It should be reported!!! */ - SDL_OpenedAudioDeviceDisconnected(_this); + // Non recoverable error has occurred. It should be reported!!! + SDL_AudioDeviceDisconnected(device); perror("audio"); return; } @@ -137,19 +157,17 @@ static void NETBSDAUDIO_PlayDevice(SDL_AudioDevice *_this) #endif } -static Uint8 *NETBSDAUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *NETBSDAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + return device->hidden->mixbuf; } -static int NETBSDAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *_buffer, int buflen) +static int NETBSDAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *vbuffer, int buflen) { - Uint8 *buffer = (Uint8 *)_buffer; - int br; - - br = read(_this->hidden->audio_fd, buffer, buflen); + Uint8 *buffer = (Uint8 *)vbuffer; + const int br = read(device->hidden->audio_fd, buffer, buflen); if (br == -1) { - /* Non recoverable error has occurred. It should be reported!!! */ + // Non recoverable error has occurred. It should be reported!!! perror("audio"); return -1; } @@ -157,86 +175,73 @@ static int NETBSDAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *_buffer, #ifdef DEBUG_AUDIO fprintf(stderr, "Captured %d bytes of audio data\n", br); #endif - return 0; + return br; } -static void NETBSDAUDIO_FlushCapture(SDL_AudioDevice *_this) +static void NETBSDAUDIO_FlushCapture(SDL_AudioDevice *device) { + struct SDL_PrivateAudioData *h = device->hidden; audio_info_t info; - size_t remain; - Uint8 buf[512]; - - if (ioctl(_this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { - return; /* oh well. */ - } - - 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 int br = read(_this->hidden->audio_fd, buf, len); - if (br <= 0) { - return; /* oh well. */ + if (ioctl(device->hidden->audio_fd, AUDIO_GETINFO, &info) == 0) { + size_t remain = (size_t)(info.record.seek * (SDL_AUDIO_BITSIZE(device->spec.format) / 8)); + while (remain > 0) { + char buf[512]; + const size_t len = SDL_min(sizeof(buf), remain); + const ssize_t br = read(h->audio_fd, buf, len); + if (br <= 0) { + break; + } + remain -= br; } - remain -= br; } } -static void NETBSDAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void NETBSDAUDIO_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->audio_fd >= 0) { - close(_this->hidden->audio_fd); + if (device->hidden) { + if (device->hidden->audio_fd >= 0) { + close(device->hidden->audio_fd); + } + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); + device->hidden = NULL; } - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden); } -static int NETBSDAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int NETBSDAUDIO_OpenDevice(SDL_AudioDevice *device) { - SDL_bool iscapture = _this->iscapture; - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; + const SDL_bool iscapture = device->iscapture; 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) { - devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { - 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) { + // Initialize all variables that we clean on shutdown + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); - /* Open the audio device */ - _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)); + // Open the audio device; we hardcode the device path in `device->name` for lack of better info, so use that. + const int flags = ((device->iscapture) ? O_RDONLY : O_WRONLY); + device->hidden->audio_fd = open(device->name, flags | O_CLOEXEC); + if (device->hidden->audio_fd < 0) { + return SDL_SetError("Couldn't open %s: %s", device->name, strerror(errno)); } AUDIO_INITINFO(&info); -#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; +#ifdef AUDIO_GETFORMAT // Introduced in NetBSD 9.0 + if (ioctl(device->hidden->audio_fd, AUDIO_GETFORMAT, &hwinfo) != -1) { + // Use the device's native sample rate so the kernel doesn't have to resample. + device->spec.freq = iscapture ? hwinfo.record.sample_rate : hwinfo.play.sample_rate; } #endif - prinfo->sample_rate = _this->spec.freq; - prinfo->channels = _this->spec.channels; + prinfo->sample_rate = device->spec.freq; + prinfo->channels = device->spec.channels; - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { switch (test_format) { case SDL_AUDIO_U8: @@ -271,56 +276,56 @@ static int NETBSDAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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(device->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) { + return SDL_SetError("AUDIO_SETINFO failed for %s: %s", device->name, strerror(errno)); } - if (ioctl(_this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { - return SDL_SetError("AUDIO_GETINFO failed for %s: %s", devname, strerror(errno)); + if (ioctl(device->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { + return SDL_SetError("AUDIO_GETINFO failed for %s: %s", device->name, strerror(errno)); } - /* Final spec used for the device. */ - _this->spec.format = test_format; - _this->spec.freq = prinfo->sample_rate; - _this->spec.channels = prinfo->channels; + // Final spec used for the device. + device->spec.format = test_format; + device->spec.freq = prinfo->sample_rate; + device->spec.channels = prinfo->channels; - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); 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) { + // Allocate mixing buffer + device->hidden->mixlen = device->buffer_size; + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->hidden->mixlen); + if (device->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size); + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); } - NETBSDAUDIO_Status(_this); + NETBSDAUDIO_Status(device); - /* We're ready to rock and roll. :-) */ - return 0; + return 0; // We're ready to rock and roll. :-) } static SDL_bool NETBSDAUDIO_Init(SDL_AudioDriverImpl *impl) { - /* Set the function pointers */ impl->DetectDevices = NETBSDAUDIO_DetectDevices; impl->OpenDevice = NETBSDAUDIO_OpenDevice; + impl->WaitDevice = NETBSDAUDIO_WaitDevice; impl->PlayDevice = NETBSDAUDIO_PlayDevice; impl->GetDeviceBuf = NETBSDAUDIO_GetDeviceBuf; impl->CloseDevice = NETBSDAUDIO_CloseDevice; + impl->WaitCaptureDevice = NETBSDAUDIO_WaitDevice; impl->CaptureFromDevice = NETBSDAUDIO_CaptureFromDevice; impl->FlushCapture = NETBSDAUDIO_FlushCapture; impl->HasCaptureSupport = SDL_TRUE; impl->AllowsArbitraryDeviceNames = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap NETBSDAUDIO_bootstrap = { "netbsd", "NetBSD audio", NETBSDAUDIO_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_NETBSD */ +#endif // SDL_AUDIO_DRIVER_NETBSD diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c index 128fef61..37c7dc8c 100644 --- a/src/audio/openslES/SDL_openslES.c +++ b/src/audio/openslES/SDL_openslES.c @@ -22,9 +22,8 @@ #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 -*/ +// 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_sysaudio.h" #include "../SDL_audio_c.h" @@ -36,7 +35,7 @@ #include -#define NUM_BUFFERS 2 /* -- Don't lower this! */ +#define NUM_BUFFERS 2 // -- Don't lower this! struct SDL_PrivateAudioData { @@ -83,14 +82,14 @@ struct SDL_PrivateAudioData #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 */ +// engine interfaces static SLObjectItf engineObject = NULL; static SLEngineItf engineEngine = NULL; -/* output mix interfaces */ +// output mix interfaces static SLObjectItf outputMixObject = NULL; -/* buffer queue player interfaces */ +// buffer queue player interfaces static SLObjectItf bqPlayerObject = NULL; static SLPlayItf bqPlayerPlay = NULL; static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = NULL; @@ -98,7 +97,7 @@ static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = NULL; static SLVolumeItf bqPlayerVolume; #endif -/* recorder interfaces */ +// recorder interfaces static SLObjectItf recorderObject = NULL; static SLRecordItf recorderRecord = NULL; static SLAndroidSimpleBufferQueueItf recorderBufferQueue = NULL; @@ -123,13 +122,13 @@ static void openslES_DestroyEngine(void) { LOGI("openslES_DestroyEngine()"); - /* destroy output mix object, and invalidate all associated interfaces */ + // destroy output mix object, and invalidate all associated interfaces if (outputMixObject != NULL) { (*outputMixObject)->Destroy(outputMixObject); outputMixObject = NULL; } - /* destroy engine object, and invalidate all associated interfaces */ + // destroy engine object, and invalidate all associated interfaces if (engineObject != NULL) { (*engineObject)->Destroy(engineObject); engineObject = NULL; @@ -145,7 +144,7 @@ static int openslES_CreateEngine(void) LOGI("openSLES_CreateEngine()"); - /* create engine */ + // create engine result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); if (SL_RESULT_SUCCESS != result) { LOGE("slCreateEngine failed: %d", result); @@ -153,7 +152,7 @@ static int openslES_CreateEngine(void) } LOGI("slCreateEngine OK"); - /* realize the engine */ + // realize the engine result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeEngine failed: %d", result); @@ -161,7 +160,7 @@ static int openslES_CreateEngine(void) } LOGI("RealizeEngine OK"); - /* get the engine interface, which is needed in order to create other objects */ + // get the engine interface, which is needed in order to create other objects result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); if (SL_RESULT_SUCCESS != result) { LOGE("EngineGetInterface failed: %d", result); @@ -169,7 +168,7 @@ static int openslES_CreateEngine(void) } LOGI("EngineGetInterface OK"); - /* create output mix */ + // create output mix result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req); if (SL_RESULT_SUCCESS != result) { LOGE("CreateOutputMix failed: %d", result); @@ -177,7 +176,7 @@ static int openslES_CreateEngine(void) } LOGI("CreateOutputMix OK"); - /* realize the output mix */ + // realize the output mix result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeOutputMix failed: %d", result); @@ -190,7 +189,7 @@ error: return 0; } -/* this callback handler is called every time a buffer finishes recording */ +// this callback handler is called every time a buffer finishes recording static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *)context; @@ -199,12 +198,12 @@ static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) SDL_PostSemaphore(audiodata->playsem); } -static void openslES_DestroyPCMRecorder(SDL_AudioDevice *_this) +static void openslES_DestroyPCMRecorder(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; + struct SDL_PrivateAudioData *audiodata = device->hidden; SLresult result; - /* stop recording */ + // stop recording if (recorderRecord != NULL) { result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED); if (SL_RESULT_SUCCESS != result) { @@ -212,7 +211,7 @@ static void openslES_DestroyPCMRecorder(SDL_AudioDevice *_this) } } - /* destroy audio recorder object, and invalidate all associated interfaces */ + // destroy audio recorder object, and invalidate all associated interfaces if (recorderObject != NULL) { (*recorderObject)->Destroy(recorderObject); recorderObject = NULL; @@ -230,9 +229,9 @@ static void openslES_DestroyPCMRecorder(SDL_AudioDevice *_this) } } -static int openslES_CreatePCMRecorder(SDL_AudioDevice *_this) +static int openslES_CreatePCMRecorder(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; + struct SDL_PrivateAudioData *audiodata = device->hidden; SLDataFormat_PCM format_pcm; SLDataLocator_AndroidSimpleBufferQueue loc_bufq; SLDataSink audioSnk; @@ -248,19 +247,19 @@ static int openslES_CreatePCMRecorder(SDL_AudioDevice *_this) return SDL_SetError("This app doesn't have RECORD_AUDIO permission"); } - /* Just go with signed 16-bit audio as it's the most compatible */ - _this->spec.format = SDL_AUDIO_S16SYS; - _this->spec.channels = 1; - /*_this->spec.freq = SL_SAMPLINGRATE_16 / 1000;*/ + // Just go with signed 16-bit audio as it's the most compatible + device->spec.format = SDL_AUDIO_S16SYS; + device->spec.channels = 1; + //device->spec.freq = SL_SAMPLINGRATE_16 / 1000;*/ - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); + // Update the fragment size as size in bytes + SDL_UpdatedAudioDeviceFormat(device); 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); + device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format), + device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->sample_frames); - /* configure audio source */ + // configure audio source loc_dev.locatorType = SL_DATALOCATOR_IODEVICE; loc_dev.deviceType = SL_IODEVICE_AUDIOINPUT; loc_dev.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT; @@ -268,93 +267,93 @@ static int openslES_CreatePCMRecorder(SDL_AudioDevice *_this) audioSrc.pLocator = &loc_dev; audioSrc.pFormat = NULL; - /* configure audio sink */ + // configure audio sink 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.bitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format); - format_pcm.containerSize = SDL_AUDIO_BITSIZE(_this->spec.format); + format_pcm.numChannels = device->spec.channels; + format_pcm.samplesPerSec = device->spec.freq * 1000; // / kilo Hz to milli Hz + format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(device->spec.format); + format_pcm.containerSize = SDL_AUDIO_BITSIZE(device->spec.format); format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER; audioSnk.pLocator = &loc_bufq; audioSnk.pFormat = &format_pcm; - /* create audio recorder */ - /* (requires the RECORD_AUDIO permission) */ + // create audio recorder + // (requires the RECORD_AUDIO permission) result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc, &audioSnk, 1, ids, req); if (SL_RESULT_SUCCESS != result) { LOGE("CreateAudioRecorder failed: %d", result); goto failed; } - /* realize the recorder */ + // realize the recorder result = (*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeAudioPlayer failed: %d", result); goto failed; } - /* get the record interface */ + // get the record interface result = (*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_RECORD interface get failed: %d", result); goto failed; } - /* get the buffer queue interface */ + // get the buffer queue interface result = (*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_BUFFERQUEUE interface get failed: %d", result); goto failed; } - /* register callback on the buffer queue */ - /* context is '(SDL_PrivateAudioData *)_this->hidden' */ - result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, _this->hidden); + // register callback on the buffer queue + // context is '(SDL_PrivateAudioData *)device->hidden' + result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, device->hidden); if (SL_RESULT_SUCCESS != result) { LOGE("RegisterCallback failed: %d", result); goto failed; } - /* Create the audio buffer semaphore */ + // Create the audio buffer semaphore audiodata->playsem = SDL_CreateSemaphore(0); if (!audiodata->playsem) { LOGE("cannot create Semaphore!"); goto failed; } - /* Create the sound buffers */ - audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * _this->spec.size); + // Create the sound buffers + audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * device->buffer_size); if (audiodata->mixbuff == NULL) { LOGE("mixbuffer allocate - out of memory"); goto failed; } for (i = 0; i < NUM_BUFFERS; i++) { - audiodata->pmixbuff[i] = audiodata->mixbuff + i * _this->spec.size; + audiodata->pmixbuff[i] = audiodata->mixbuff + i * device->buffer_size; } - /* in case already recording, stop recording and clear buffer queue */ + // in case already recording, stop recording and clear buffer queue result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED); if (SL_RESULT_SUCCESS != result) { LOGE("Record set state failed: %d", result); goto failed; } - /* enqueue empty buffers to be filled by the recorder */ + // enqueue empty buffers to be filled by the recorder for (i = 0; i < NUM_BUFFERS; i++) { - result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[i], _this->spec.size); + result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[i], device->buffer_size); if (SL_RESULT_SUCCESS != result) { LOGE("Record enqueue buffers failed: %d", result); goto failed; } } - /* start recording */ + // start recording result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING); if (SL_RESULT_SUCCESS != result) { LOGE("Record set state failed: %d", result); @@ -367,7 +366,7 @@ failed: return SDL_SetError("Open device failed!"); } -/* this callback handler is called every time a buffer finishes playing */ +// this callback handler is called every time a buffer finishes playing static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *)context; @@ -376,20 +375,19 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) SDL_PostSemaphore(audiodata->playsem); } -static void openslES_DestroyPCMPlayer(SDL_AudioDevice *_this) +static void openslES_DestroyPCMPlayer(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; - SLresult result; + struct SDL_PrivateAudioData *audiodata = device->hidden; - /* set the player's state to 'stopped' */ + // set the player's state to 'stopped' if (bqPlayerPlay != NULL) { - result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); + const SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); if (SL_RESULT_SUCCESS != result) { LOGE("SetPlayState stopped failed: %d", result); } } - /* destroy buffer queue audio player object, and invalidate all associated interfaces */ + // destroy buffer queue audio player object, and invalidate all associated interfaces if (bqPlayerObject != NULL) { (*bqPlayerObject)->Destroy(bqPlayerObject); @@ -408,26 +406,14 @@ static void openslES_DestroyPCMPlayer(SDL_AudioDevice *_this) } } -static int openslES_CreatePCMPlayer(SDL_AudioDevice *_this) +static int openslES_CreatePCMPlayer(SDL_AudioDevice *device) { - 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; - /* If we want to add floating point audio support (requires API level 21) it can be done as described here: https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point */ if (SDL_GetAndroidSDKVersion() >= 21) { - const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(_this->spec.format); + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); SDL_AudioFormat test_format; while ((test_format = *(closefmts++)) != 0) { if (SDL_AUDIO_ISSIGNED(test_format)) { @@ -436,40 +422,42 @@ static int openslES_CreatePCMPlayer(SDL_AudioDevice *_this) } if (!test_format) { - /* Didn't find a compatible format : */ + // Didn't find a compatible format : LOGI("No compatible audio format, using signed 16-bit audio"); test_format = SDL_AUDIO_S16SYS; } - _this->spec.format = test_format; + device->spec.format = test_format; } else { - /* Just go with signed 16-bit audio as it's the most compatible */ - _this->spec.format = SDL_AUDIO_S16SYS; + // Just go with signed 16-bit audio as it's the most compatible + device->spec.format = SDL_AUDIO_S16SYS; } - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); + // Update the fragment size as size in bytes + SDL_UpdatedAudioDeviceFormat(device); 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); + device->spec.freq, SDL_AUDIO_ISFLOAT(device->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(device->spec.format), + device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->sample_frames); - /* configure audio source */ + // configure audio source + SLDataLocator_AndroidSimpleBufferQueue loc_bufq; loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; loc_bufq.numBuffers = NUM_BUFFERS; + SLDataFormat_PCM format_pcm; 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.numChannels = device->spec.channels; + format_pcm.samplesPerSec = device->spec.freq * 1000; // / kilo Hz to milli Hz + format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(device->spec.format); + format_pcm.containerSize = SDL_AUDIO_BITSIZE(device->spec.format); - if (SDL_AUDIO_ISBIGENDIAN(_this->spec.format)) { + if (SDL_AUDIO_ISBIGENDIAN(device->spec.format)) { format_pcm.endianness = SL_BYTEORDER_BIGENDIAN; } else { format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; } - switch (_this->spec.channels) { + switch (device->spec.channels) { case 1: format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT; break; @@ -495,14 +483,19 @@ static int openslES_CreatePCMPlayer(SDL_AudioDevice *_this) format_pcm.channelMask = SL_ANDROID_SPEAKER_7DOT1; break; default: - /* Unknown number of channels, fall back to stereo */ - _this->spec.channels = 2; + // Unknown number of channels, fall back to stereo + device->spec.channels = 2; format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; break; } - if (SDL_AUDIO_ISFLOAT(_this->spec.format)) { - /* Copy all setup into PCM EX structure */ + SLDataSink audioSnk; + SLDataSource audioSrc; + audioSrc.pFormat = (void *)&format_pcm; + + SLAndroidDataFormat_PCM_EX format_pcm_ex; + if (SDL_AUDIO_ISFLOAT(device->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; @@ -511,81 +504,87 @@ static int openslES_CreatePCMPlayer(SDL_AudioDevice *_this) format_pcm_ex.bitsPerSample = format_pcm.bitsPerSample; format_pcm_ex.containerSize = format_pcm.containerSize; format_pcm_ex.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; + audioSrc.pFormat = (void *)&format_pcm_ex; } audioSrc.pLocator = &loc_bufq; - audioSrc.pFormat = SDL_AUDIO_ISFLOAT(_this->spec.format) ? (void *)&format_pcm_ex : (void *)&format_pcm; - /* configure audio sink */ + // configure audio sink + SLDataLocator_OutputMix loc_outmix; loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; loc_outmix.outputMix = outputMixObject; audioSnk.pLocator = &loc_outmix; audioSnk.pFormat = NULL; - /* create audio player */ + // create audio player + const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME }; + const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE }; + SLresult result; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); if (SL_RESULT_SUCCESS != result) { LOGE("CreateAudioPlayer failed: %d", result); goto failed; } - /* realize the player */ + // realize the player result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeAudioPlayer failed: %d", result); goto failed; } - /* get the play interface */ + // get the play interface result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_PLAY interface get failed: %d", result); goto failed; } - /* get the buffer queue interface */ + // get the buffer queue interface result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_BUFFERQUEUE interface get failed: %d", result); goto failed; } - /* register callback on the buffer queue */ - /* context is '(SDL_PrivateAudioData *)_this->hidden' */ - result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, _this->hidden); + // register callback on the buffer queue + // context is '(SDL_PrivateAudioData *)device->hidden' + result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, device->hidden); if (SL_RESULT_SUCCESS != result) { LOGE("RegisterCallback failed: %d", result); goto failed; } #if 0 - /* get the volume interface */ + // get the volume interface result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_VOLUME interface get failed: %d", result); - /* goto failed; */ + // goto failed; } #endif - /* Create the audio buffer semaphore */ + struct SDL_PrivateAudioData *audiodata = device->hidden; + + // Create the audio buffer semaphore audiodata->playsem = SDL_CreateSemaphore(NUM_BUFFERS - 1); if (!audiodata->playsem) { LOGE("cannot create Semaphore!"); goto failed; } - /* Create the sound buffers */ - audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * _this->spec.size); + // Create the sound buffers + audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * device->buffer_size); if (audiodata->mixbuff == NULL) { LOGE("mixbuffer allocate - out of memory"); goto failed; } - for (i = 0; i < NUM_BUFFERS; i++) { - audiodata->pmixbuff[i] = audiodata->mixbuff + i * _this->spec.size; + for (int i = 0; i < NUM_BUFFERS; i++) { + audiodata->pmixbuff[i] = audiodata->mixbuff + i * device->buffer_size; } - /* set the player's state to playing */ + // set the player's state to playing result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); if (SL_RESULT_SUCCESS != result) { LOGE("Play set state failed: %d", result); @@ -598,103 +597,98 @@ failed: return -1; } -static int openslES_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int openslES_OpenDevice(SDL_AudioDevice *device) { - _this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - if (_this->iscapture) { - LOGI("openslES_OpenDevice() %s for capture", devname); - return openslES_CreatePCMRecorder(_this); + if (device->iscapture) { + LOGI("openslES_OpenDevice() for capture"); + return openslES_CreatePCMRecorder(device); } else { int ret; - LOGI("openslES_OpenDevice() %s for playing", devname); - ret = openslES_CreatePCMPlayer(_this); + LOGI("openslES_OpenDevice() for playing"); + ret = openslES_CreatePCMPlayer(device); 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); + // Another attempt to open the device with a lower frequency + if (device->spec.freq > 48000) { + openslES_DestroyPCMPlayer(device); + device->spec.freq = 48000; + ret = openslES_CreatePCMPlayer(device); } } - if (ret == 0) { - return 0; - } else { + if (ret != 0) { return SDL_SetError("Open device failed!"); } } + + return 0; } -static void openslES_WaitDevice(SDL_AudioDevice *_this) +static void openslES_WaitDevice(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; + struct SDL_PrivateAudioData *audiodata = device->hidden; LOGV("openslES_WaitDevice()"); - /* Wait for an audio chunk to finish */ + // Wait for an audio chunk to finish SDL_WaitSemaphore(audiodata->playsem); } -static void openslES_PlayDevice(SDL_AudioDevice *_this) +static void openslES_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; - SLresult result; + struct SDL_PrivateAudioData *audiodata = device->hidden; LOGV("======openslES_PlayDevice()======"); - /* Queue it up */ - result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], _this->spec.size); + // Queue it up + const SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer, buflen); audiodata->next_buffer++; if (audiodata->next_buffer >= NUM_BUFFERS) { audiodata->next_buffer = 0; } - /* If Enqueue fails, callback won't be called. - * Post the semaphore, not to run out of buffer */ + // If Enqueue fails, callback won't be called. + // Post the semaphore, not to run out of buffer if (SL_RESULT_SUCCESS != result) { SDL_PostSemaphore(audiodata->playsem); } } -/*/ n playn sem */ -/* getbuf 0 - 1 */ -/* fill buff 0 - 1 */ -/* play 0 - 0 1 */ -/* wait 1 0 0 */ -/* getbuf 1 0 0 */ -/* fill buff 1 0 0 */ -/* play 0 0 0 */ -/* wait */ -/* */ -/* okay.. */ +/// n playn sem +// getbuf 0 - 1 +// fill buff 0 - 1 +// play 0 - 0 1 +// wait 1 0 0 +// getbuf 1 0 0 +// fill buff 1 0 0 +// play 0 0 0 +// wait +// +// okay.. -static Uint8 *openslES_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *openslES_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; + struct SDL_PrivateAudioData *audiodata = device->hidden; LOGV("openslES_GetDeviceBuf()"); return audiodata->pmixbuff[audiodata->next_buffer]; } -static int openslES_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int openslES_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { - struct SDL_PrivateAudioData *audiodata = _this->hidden; - SLresult result; + struct SDL_PrivateAudioData *audiodata = device->hidden; - /* Wait for new recorded data */ - SDL_WaitSemaphore(audiodata->playsem); + // Copy it to the output buffer + SDL_assert(buflen == device->buffer_size); + SDL_memcpy(buffer, audiodata->pmixbuff[audiodata->next_buffer], device->buffer_size); - /* Copy it to the output buffer */ - SDL_assert(buflen == _this->spec.size); - SDL_memcpy(buffer, audiodata->pmixbuff[audiodata->next_buffer], _this->spec.size); - - /* Re-enqueue the buffer */ - result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], _this->spec.size); + // Re-enqueue the buffer + const SLresult result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], device->buffer_size); if (SL_RESULT_SUCCESS != result) { LOGE("Record enqueue buffers failed: %d", result); return -1; @@ -705,22 +699,24 @@ static int openslES_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int audiodata->next_buffer = 0; } - return _this->spec.size; + return device->buffer_size; } -static void openslES_CloseDevice(SDL_AudioDevice *_this) +static void openslES_CloseDevice(SDL_AudioDevice *device) { - /* struct SDL_PrivateAudioData *audiodata = _this->hidden; */ + // struct SDL_PrivateAudioData *audiodata = device->hidden; + if (device->hidden) { + if (device->iscapture) { + LOGI("openslES_CloseDevice() for capture"); + openslES_DestroyPCMRecorder(device); + } else { + LOGI("openslES_CloseDevice() for playing"); + openslES_DestroyPCMPlayer(device); + } - if (_this->iscapture) { - LOGI("openslES_CloseDevice() for capture"); - openslES_DestroyPCMRecorder(_this); - } else { - LOGI("openslES_CloseDevice() for playing"); - openslES_DestroyPCMPlayer(_this); + SDL_free(device->hidden); + device->hidden = NULL; } - - SDL_free(_this->hidden); } static SDL_bool openslES_Init(SDL_AudioDriverImpl *impl) @@ -733,24 +729,26 @@ static SDL_bool openslES_Init(SDL_AudioDriverImpl *impl) LOGI("openslES_Init() - set pointers"); - /* Set the function pointers */ - /* impl->DetectDevices = openslES_DetectDevices; */ + // Set the function pointers + // impl->DetectDevices = openslES_DetectDevices; + impl->ThreadInit = Android_AudioThreadInit; impl->OpenDevice = openslES_OpenDevice; impl->WaitDevice = openslES_WaitDevice; impl->PlayDevice = openslES_PlayDevice; impl->GetDeviceBuf = openslES_GetDeviceBuf; + impl->WaitCaptureDevice = openslES_WaitDevice; impl->CaptureFromDevice = openslES_CaptureFromDevice; impl->CloseDevice = openslES_CloseDevice; impl->Deinitialize = openslES_DestroyEngine; - /* and the capabilities */ + // and the capabilities impl->HasCaptureSupport = SDL_TRUE; impl->OnlyHasDefaultOutputDevice = SDL_TRUE; impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; LOGI("openslES_Init() - success"); - /* this audio target is available. */ + // this audio target is available. return SDL_TRUE; } @@ -761,7 +759,7 @@ AudioBootStrap openslES_bootstrap = { void openslES_ResumeDevices(void) { if (bqPlayerPlay != NULL) { - /* set the player's state to 'playing' */ + // set the player's state to 'playing' SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); if (SL_RESULT_SUCCESS != result) { LOGE("openslES_ResumeDevices failed: %d", result); @@ -772,7 +770,7 @@ void openslES_ResumeDevices(void) void openslES_PauseDevices(void) { if (bqPlayerPlay != NULL) { - /* set the player's state to 'paused' */ + // set the player's state to 'paused' SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED); if (SL_RESULT_SUCCESS != result) { LOGE("openslES_PauseDevices failed: %d", result); @@ -780,4 +778,4 @@ void openslES_PauseDevices(void) } } -#endif /* SDL_AUDIO_DRIVER_OPENSLES */ +#endif // SDL_AUDIO_DRIVER_OPENSLES diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index 1d1b1562..419fbfcb 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -327,7 +327,7 @@ static void io_list_remove(Uint32 id) spa_list_remove(&n->link); if (hotplug_events_enabled) { - SDL_RemoveAudioDevice(n->is_capture, PW_ID_TO_HANDLE(id)); + SDL_AudioDeviceDisconnected(SDL_FindPhysicalAudioDeviceByHandle(PW_ID_TO_HANDLE(id))); } SDL_free(n); @@ -337,31 +337,6 @@ static void io_list_remove(Uint32 id) } } -static void io_list_sort(void) -{ - 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 != NULL && SDL_strcmp(n->path, pipewire_default_sink_id) == 0) { - default_sink = n; - spa_list_remove(&n->link); - } else if (pipewire_default_source_id != NULL && 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(void) { struct io_node *n, *temp; @@ -383,17 +358,6 @@ static struct io_node *io_list_get_by_id(Uint32 id) 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); @@ -640,6 +604,19 @@ static char *get_name_from_json(const char *json) return SDL_strdup(value); } +static void change_default_device(const char *path) +{ + if (hotplug_events_enabled) { + struct io_node *n, *temp; + spa_list_for_each_safe (n, temp, &hotplug_io_list, link) { + if (SDL_strcmp(n->path, path) == 0) { + SDL_DefaultAudioDeviceChanged(SDL_FindPhysicalAudioDeviceByHandle(PW_ID_TO_HANDLE(n->id))); + return; // found it, we're done. + } + } + } +} + /* Metadata node callback */ static int metadata_property(void *object, Uint32 subject, const char *key, const char *type, const char *value) { @@ -652,12 +629,14 @@ static int metadata_property(void *object, Uint32 subject, const char *key, cons } pipewire_default_sink_id = get_name_from_json(value); node->persist = SDL_TRUE; + change_default_device(pipewire_default_sink_id); } else if (!SDL_strcmp(key, "default.audio.source")) { if (pipewire_default_source_id != NULL) { SDL_free(pipewire_default_source_id); } pipewire_default_source_id = get_name_from_json(value); node->persist = SDL_TRUE; + change_default_device(pipewire_default_source_id); } } @@ -833,7 +812,7 @@ static void hotplug_loop_destroy(void) } } -static void PIPEWIRE_DetectDevices(void) +static void PIPEWIRE_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { struct io_node *io; @@ -844,11 +823,15 @@ static void PIPEWIRE_DetectDevices(void) 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)); + SDL_AudioDevice *device = SDL_AddAudioDevice(io->is_capture, io->name, &io->spec, PW_ID_TO_HANDLE(io->id)); + if (pipewire_default_sink_id != NULL && SDL_strcmp(io->path, pipewire_default_sink_id) == 0) { + SDL_assert(!io->is_capture); + *default_output = device; + } else if (pipewire_default_source_id != NULL && SDL_strcmp(io->path, pipewire_default_source_id) == 0) { + SDL_assert(io->is_capture); + *default_capture = device; + } } hotplug_events_enabled = SDL_TRUE; @@ -936,167 +919,115 @@ static void initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info } } -static void output_callback(void *data) +static Uint8 *PIPEWIRE_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - struct pw_buffer *pw_buf; - struct spa_buffer *spa_buf; - Uint8 *dst; + // See if a buffer is available. If this returns NULL, SDL_OutputAudioThreadIterate will return SDL_FALSE, but since we own the thread, it won't kill playback. + // !!! FIXME: It's not clear to me if this ever returns NULL or if this was just defensive coding. - SDL_AudioDevice *_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); + struct pw_stream *stream = device->hidden->stream; + struct pw_buffer *pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream); if (pw_buf == NULL) { - return; + return NULL; } - spa_buf = pw_buf->buffer; - + struct spa_buffer *spa_buf = pw_buf->buffer; if (spa_buf->datas[0].data == NULL) { - return; + PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + return NULL; } - /* - * 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_GetAudioStreamAvailable(_this->stream) < _this->spec.size) { - _this->callbackspec.callback(_this->callbackspec.userdata, _this->work_buffer, _this->callbackspec.size); - SDL_PutAudioStreamData(_this->stream, _this->work_buffer, _this->callbackspec.size); - } - - got = SDL_GetAudioStreamData(_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); + device->hidden->pw_buf = pw_buf; + return (Uint8 *) spa_buf->datas[0].data; +} +static void PIPEWIRE_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) +{ + struct pw_stream *stream = device->hidden->stream; + struct pw_buffer *pw_buf = device->hidden->pw_buf; + struct spa_buffer *spa_buf = pw_buf->buffer; 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; + spa_buf->datas[0].chunk->stride = device->hidden->stride; + spa_buf->datas[0].chunk->size = buffer_size; PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + device->hidden->pw_buf = NULL; +} + +static void output_callback(void *data) +{ + SDL_OutputAudioThreadIterate((SDL_AudioDevice *)data); +} + +static void PIPEWIRE_FlushCapture(SDL_AudioDevice *device) +{ + struct pw_stream *stream = device->hidden->stream; + struct pw_buffer *pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream); + if (pw_buf != NULL) { // just requeue it without any further thought. + PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + } +} + +static int PIPEWIRE_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ + struct pw_stream *stream = device->hidden->stream; + struct pw_buffer *pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream); + if (!pw_buf) { + return 0; + } + + struct spa_buffer *spa_buf = pw_buf->buffer; + if (!spa_buf) { + PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + return 0; + } + + const Uint8 *src = (const Uint8 *)spa_buf->datas[0].data; + 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); + const int cpy = SDL_min(buflen, (int) size); + + SDL_assert(size <= buflen); // We'll have to reengineer some stuff if this turns out to not be true. + + SDL_memcpy(buffer, src + offset, cpy); + PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + + return cpy; } static void input_callback(void *data) { - struct pw_buffer *pw_buf; - struct spa_buffer *spa_buf; - Uint8 *src; - SDL_AudioDevice *_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 == NULL) { - return; - } - - spa_buf = pw_buf->buffer; - (src = (Uint8 *)spa_buf->datas[0].data); - if (src == NULL) { - 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_GetDataQueueSize(_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_GetDataQueueSize(_this->hidden->buffer) != 0) { - SDL_ClearDataQueue(_this->hidden->buffer, _this->hidden->input_buffer_packet_size); - } - } - - PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); + SDL_CaptureAudioThreadIterate((SDL_AudioDevice *)data); } static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer) { - SDL_AudioDevice *_this = data; + SDL_AudioDevice *device = (SDL_AudioDevice *) 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; + if (device->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 (device->buffer_size > buffer->buffer->datas[0].maxsize) { + SDL_LockMutex(device->lock); + device->sample_frames = buffer->buffer->datas[0].maxsize / device->hidden->stride; + device->buffer_size = buffer->buffer->datas[0].maxsize; + SDL_UnlockMutex(device->lock); } - } else if (_this->hidden->buffer == NULL) { - /* - * 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_CreateDataQueue(_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); + device->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED; + PIPEWIRE_pw_thread_loop_signal(device->hidden->loop, false); } static void stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error) { - SDL_AudioDevice *_this = data; + SDL_AudioDevice *device = (SDL_AudioDevice *) data; if (state == PW_STREAM_STATE_STREAMING) { - _this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY; + device->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); + PIPEWIRE_pw_thread_loop_signal(device->hidden->loop, false); } } @@ -1109,7 +1040,7 @@ static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_E .add_buffer = stream_add_buffer_callback, .process = input_callback }; -static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int PIPEWIRE_OpenDevice(SDL_AudioDevice *device) { /* * NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream @@ -1128,12 +1059,12 @@ static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname) struct SDL_PrivateAudioData *priv; struct pw_properties *props; const char *app_name, *app_id, *stream_name, *stream_role, *error; - Uint32 node_id = _this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(_this->handle); - SDL_bool iscapture = _this->iscapture; + Uint32 node_id = device->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(device->handle); + const SDL_bool iscapture = device->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); + const int min_period = PW_MIN_SAMPLES * SPA_MAX(device->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); @@ -1162,27 +1093,28 @@ static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname) } /* Initialize the Pipewire stream info from the SDL audio spec */ - initialize_spa_info(&_this->spec, &spa_info); + initialize_spa_info(&device->spec, &spa_info); params = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &spa_info); if (params == NULL) { return SDL_SetError("Pipewire: Failed to set audio format parameters"); } priv = SDL_calloc(1, sizeof(struct SDL_PrivateAudioData)); - _this->hidden = priv; + device->hidden = priv; if (priv == NULL) { return SDL_OutOfMemory(); } /* Size of a single audio frame in bytes */ - priv->stride = (SDL_AUDIO_BITSIZE(_this->spec.format) >> 3) * _this->spec.channels; + priv->stride = (SDL_AUDIO_BITSIZE(device->spec.format) / 8) * device->spec.channels; - if (_this->spec.samples < min_period) { - _this->spec.samples = min_period; - _this->spec.size = _this->spec.samples * priv->stride; + if (device->sample_frames < min_period) { + device->sample_frames = min_period; } - (void)SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)_this->handle); + SDL_UpdatedAudioDeviceFormat(device); + + SDL_GetAudioThreadName(device, thread_name, sizeof(thread_name)); priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL); if (priv->loop == NULL) { return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno); @@ -1213,9 +1145,10 @@ static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname) } 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_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", device->sample_frames, device->spec.freq); + PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", device->spec.freq); PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true"); + PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DONT_RECONNECT, "true"); // Requesting a specific device, don't migrate to new default hardware. /* * Pipewire 0.3.44 introduced PW_KEY_TARGET_OBJECT that takes either a path @@ -1240,7 +1173,7 @@ static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname) /* 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); + iscapture ? &stream_input_events : &stream_output_events, device); if (priv->stream == NULL) { return SDL_SetError("Pipewire: Failed to create stream (%i)", errno); } @@ -1268,75 +1201,35 @@ static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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 == NULL) { - return SDL_SetError("Pipewire: Failed to allocate source buffer"); - } - return 0; } -static void PIPEWIRE_CloseDevice(SDL_AudioDevice *_this) +static void PIPEWIRE_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->loop) { - PIPEWIRE_pw_thread_loop_stop(_this->hidden->loop); + if (!device->hidden) { + return; } - if (_this->hidden->stream) { - PIPEWIRE_pw_stream_destroy(_this->hidden->stream); + if (device->hidden->loop) { + PIPEWIRE_pw_thread_loop_stop(device->hidden->loop); } - if (_this->hidden->context) { - PIPEWIRE_pw_context_destroy(_this->hidden->context); + if (device->hidden->stream) { + PIPEWIRE_pw_stream_destroy(device->hidden->stream); } - if (_this->hidden->loop) { - PIPEWIRE_pw_thread_loop_destroy(_this->hidden->loop); + if (device->hidden->context) { + PIPEWIRE_pw_context_destroy(device->hidden->context); } - if (_this->hidden->buffer) { - SDL_DestroyDataQueue(_this->hidden->buffer); + if (device->hidden->loop) { + PIPEWIRE_pw_thread_loop_destroy(device->hidden->loop); } - SDL_free(_this->hidden); -} + SDL_free(device->hidden); + device->hidden = NULL; -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 == NULL) { - ret = SDL_SetError("PipeWire could not find a default source"); - goto failed; - } - target = pipewire_default_source_id; - } else { - if (pipewire_default_sink_id == NULL) { - 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 == NULL) { - ret = SDL_SetError("PipeWire device list is out of sync with defaults"); - goto failed; - } - - if (name != NULL) { - *name = SDL_strdup(node->name); - } - SDL_copyp(spec, &node->spec); - -failed: - PIPEWIRE_pw_thread_loop_unlock(hotplug_loop); - return ret; + SDL_AudioThreadFinalize(device); } static void PIPEWIRE_Deinitialize(void) @@ -1366,13 +1259,15 @@ static SDL_bool PIPEWIRE_Init(SDL_AudioDriverImpl *impl) /* 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->PlayDevice = PIPEWIRE_PlayDevice; + impl->GetDeviceBuf = PIPEWIRE_GetDeviceBuf; + impl->CaptureFromDevice = PIPEWIRE_CaptureFromDevice; + impl->FlushCapture = PIPEWIRE_FlushCapture; + impl->CloseDevice = PIPEWIRE_CloseDevice; impl->HasCaptureSupport = SDL_TRUE; impl->ProvidesOwnCallbackThread = SDL_TRUE; - impl->SupportsNonPow2Samples = SDL_TRUE; return SDL_TRUE; } diff --git a/src/audio/pipewire/SDL_pipewire.h b/src/audio/pipewire/SDL_pipewire.h index 4ca3315b..5a6772ab 100644 --- a/src/audio/pipewire/SDL_pipewire.h +++ b/src/audio/pipewire/SDL_pipewire.h @@ -32,11 +32,12 @@ 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; + + // Set in GetDeviceBuf, filled in AudioThreadIterate, queued in PlayDevice + struct pw_buffer *pw_buf; }; #endif /* SDL_pipewire_h_ */ diff --git a/src/audio/ps2/SDL_ps2audio.c b/src/audio/ps2/SDL_ps2audio.c index f14eb6ee..e50a497d 100644 --- a/src/audio/ps2/SDL_ps2audio.c +++ b/src/audio/ps2/SDL_ps2audio.c @@ -20,8 +20,6 @@ */ #include "SDL_internal.h" -/* Output audio to nowhere... */ - #include "../SDL_audio_c.h" #include "SDL_ps2audio.h" @@ -29,23 +27,15 @@ #include #include -/* The tag name used by PS2 audio */ -#define PS2AUDIO_DRIVER_NAME "ps2" - -static int PS2AUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int PS2AUDIO_OpenDevice(SDL_AudioDevice *device) { - int i, mixlen; - struct audsrv_fmt_t format; - - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); - /* These are the native supported audio PS2 configs */ - switch (_this->spec.freq) { + // These are the native supported audio PS2 configs + switch (device->spec.freq) { case 11025: case 12000: case 22050: @@ -53,93 +43,89 @@ static int PS2AUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) case 32000: case 44100: case 48000: - _this->spec.freq = _this->spec.freq; - break; + break; // acceptable value, keep it default: - _this->spec.freq = 48000; + device->spec.freq = 48000; break; } - _this->spec.samples = 512; - _this->spec.channels = _this->spec.channels == 1 ? 1 : 2; - _this->spec.format = _this->spec.format == SDL_AUDIO_S8 ? SDL_AUDIO_S8 : SDL_AUDIO_S16; + device->sample_frames = 512; + device->spec.channels = device->spec.channels == 1 ? 1 : 2; + device->spec.format = device->spec.format == SDL_AUDIO_S8 ? SDL_AUDIO_S8 : SDL_AUDIO_S16; - SDL_CalculateAudioSpec(&_this->spec); + struct audsrv_fmt_t format; + format.bits = device->spec.format == SDL_AUDIO_S8 ? 8 : 16; + format.freq = device->spec.freq; + format.channels = device->spec.channels; - format.bits = _this->spec.format == SDL_AUDIO_S8 ? 8 : 16; - format.freq = _this->spec.freq; - format.channels = _this->spec.channels; - - _this->hidden->channel = audsrv_set_format(&format); + device->hidden->channel = audsrv_set_format(&format); audsrv_set_volume(MAX_VOLUME); - if (_this->hidden->channel < 0) { - SDL_aligned_free(_this->hidden->rawbuf); - _this->hidden->rawbuf = NULL; + if (device->hidden->channel < 0) { return SDL_SetError("Couldn't reserve hardware channel"); } - /* Update the fragment size as size in bytes. */ - SDL_CalculateAudioSpec(&_this->spec); + // Update the fragment size as size in bytes. + SDL_UpdatedAudioDeviceFormat(device); /* 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 *)SDL_aligned_alloc(64, mixlen); - if (_this->hidden->rawbuf == NULL) { + const int mixlen = device->buffer_size * NUM_BUFFERS; + device->hidden->rawbuf = (Uint8 *)SDL_aligned_alloc(64, mixlen); + if (device->hidden->rawbuf == NULL) { 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]; + SDL_memset(device->hidden->rawbuf, device->silence_value, mixlen); + for (int i = 0; i < NUM_BUFFERS; i++) { + device->hidden->mixbufs[i] = &device->hidden->rawbuf[i * device->buffer_size]; } - _this->hidden->next_buffer = 0; return 0; } -static void PS2AUDIO_PlayDevice(SDL_AudioDevice *_this) +static void PS2AUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - 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; + audsrv_play_audio((char *)buffer, buflen); } -/* This function waits until it is possible to write a full sound buffer */ -static void PS2AUDIO_WaitDevice(SDL_AudioDevice *_this) +static void PS2AUDIO_WaitDevice(SDL_AudioDevice *device) { - audsrv_wait_audio(_this->spec.size); + audsrv_wait_audio(device->buffer_size); } -static Uint8 *PS2AUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *PS2AUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbufs[_this->hidden->next_buffer]; + Uint8 *buffer = device->hidden->mixbufs[device->hidden->next_buffer]; + device->hidden->next_buffer = (device->hidden->next_buffer + 1) % NUM_BUFFERS; + return buffer; } -static void PS2AUDIO_CloseDevice(SDL_AudioDevice *_this) +static void PS2AUDIO_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->channel >= 0) { - audsrv_stop_audio(); - _this->hidden->channel = -1; - } + if (device->hidden) { + if (device->hidden->channel >= 0) { + audsrv_stop_audio(); + device->hidden->channel = -1; + } - if (_this->hidden->rawbuf != NULL) { - SDL_aligned_free(_this->hidden->rawbuf); - _this->hidden->rawbuf = NULL; + if (device->hidden->rawbuf != NULL) { + SDL_aligned_free(device->hidden->rawbuf); + device->hidden->rawbuf = NULL; + } + SDL_free(device->hidden); + device->hidden = NULL; } } -static void PS2AUDIO_ThreadInit(SDL_AudioDevice *_this) +static void PS2AUDIO_ThreadInit(SDL_AudioDevice *device) { /* Increase the priority of this audio thread by 1 to put it ahead of other SDL threads. */ - int32_t thid; + const int32_t thid = GetThreadId(); ee_thread_status_t status; - thid = GetThreadId(); - if (ReferThreadStatus(GetThreadId(), &status) == 0) { + if (ReferThreadStatus(thid, &status) == 0) { ChangeThreadPriority(thid, status.current_priority - 1); } } @@ -155,7 +141,6 @@ static SDL_bool PS2AUDIO_Init(SDL_AudioDriverImpl *impl) return SDL_FALSE; } - /* Set the function pointers */ impl->OpenDevice = PS2AUDIO_OpenDevice; impl->PlayDevice = PS2AUDIO_PlayDevice; impl->WaitDevice = PS2AUDIO_WaitDevice; @@ -164,7 +149,7 @@ static SDL_bool PS2AUDIO_Init(SDL_AudioDriverImpl *impl) impl->ThreadInit = PS2AUDIO_ThreadInit; impl->Deinitialize = PS2AUDIO_Deinitialize; impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; // this audio target is available. } AudioBootStrap PS2AUDIO_bootstrap = { diff --git a/src/audio/psp/SDL_pspaudio.c b/src/audio/psp/SDL_pspaudio.c index e43f692e..b5af4e88 100644 --- a/src/audio/psp/SDL_pspaudio.c +++ b/src/audio/psp/SDL_pspaudio.c @@ -34,41 +34,34 @@ #include #include -/* The tag name used by PSP audio */ -#define PSPAUDIO_DRIVER_NAME "psp" - static inline SDL_bool isBasicAudioConfig(const SDL_AudioSpec *spec) { return spec->freq == 44100; } -static int PSPAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int PSPAUDIO_OpenDevice(SDL_AudioDevice *device) { - int format, mixlen, i; - - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); - /* device only natively supports S16LSB */ - _this->spec.format = SDL_AUDIO_S16LSB; + // device only natively supports S16LSB + device->spec.format = SDL_AUDIO_S16LSB; /* PSP has some limitations with the Audio. It fully supports 44.1KHz (Mono & Stereo), however with frequencies different 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); + if (isBasicAudioConfig(&device->spec)) { + // The sample count must be a multiple of 64. + device->sample_frames = PSP_AUDIO_SAMPLE_ALIGN(device->sample_frames); + // The number of channels (1 or 2). + device->spec.channels = device->spec.channels == 1 ? 1 : 2; + const int format = (device->spec.channels == 1) ? PSP_AUDIO_FORMAT_MONO : PSP_AUDIO_FORMAT_STEREO; + device->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, device->sample_frames, format); } else { - /* 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11050, 8000 */ - switch (_this->spec.freq) { + // 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11050, 8000 + switch (device->spec.freq) { case 8000: case 11025: case 12000: @@ -78,93 +71,90 @@ static int PSPAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) case 32000: case 44100: case 48000: - _this->spec.freq = _this->spec.freq; - break; + break; // acceptable, keep it default: - _this->spec.freq = 48000; + device->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 number of samples to output in one output call (min 17, max 4111). + device->sample_frames = device->sample_frames < 17 ? 17 : (device->sample_frames > 4111 ? 4111 : device->sample_frames); + device->spec.channels = 2; // we're forcing the hardware to stereo. + device->hidden->channel = sceAudioSRCChReserve(device->sample_frames, device->spec.freq, 2); } - if (_this->hidden->channel < 0) { - SDL_aligned_free(_this->hidden->rawbuf); - _this->hidden->rawbuf = NULL; + if (device->hidden->channel < 0) { return SDL_SetError("Couldn't reserve hardware channel"); } - /* Update the fragment size as size in bytes. */ - SDL_CalculateAudioSpec(&_this->spec); + // Update the fragment size as size in bytes. + SDL_UpdatedAudioDeviceFormat(device); /* 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 *)SDL_aligned_alloc(64, mixlen); - if (_this->hidden->rawbuf == NULL) { + const int mixlen = device->buffer_size * NUM_BUFFERS; + device->hidden->rawbuf = (Uint8 *)SDL_aligned_alloc(64, mixlen); + if (device->hidden->rawbuf == NULL) { 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]; + SDL_memset(device->hidden->rawbuf, device->silence_value, mixlen); + for (int i = 0; i < NUM_BUFFERS; i++) { + device->hidden->mixbufs[i] = &device->hidden->rawbuf[i * device->buffer_size]; } - _this->hidden->next_buffer = 0; return 0; } -static void PSPAUDIO_PlayDevice(SDL_AudioDevice *_this) +static void PSPAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - Uint8 *mixbuf = _this->hidden->mixbufs[_this->hidden->next_buffer]; - if (!isBasicAudioConfig(&_this->spec)) { - SDL_assert(_this->spec.channels == 2); - sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, mixbuf); + if (!isBasicAudioConfig(&device->spec)) { + SDL_assert(device->spec.channels == 2); + sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, (void *) buffer); } else { - sceAudioOutputPannedBlocking(_this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf); + sceAudioOutputPannedBlocking(device->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, (void *) buffer); } - - _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 PSPAUDIO_WaitDevice(SDL_AudioDevice *_this) +static void PSPAUDIO_WaitDevice(SDL_AudioDevice *device) { - /* Because we block when sending audio, there's no need for this function to do anything. */ + // Because we block when sending audio, there's no need for this function to do anything. } -static Uint8 *PSPAUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *PSPAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbufs[_this->hidden->next_buffer]; + Uint8 *buffer = device->hidden->mixbufs[device->hidden->next_buffer]; + device->hidden->next_buffer = (device->hidden->next_buffer + 1) % NUM_BUFFERS; + return buffer; } -static void PSPAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void PSPAUDIO_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->channel >= 0) { - if (!isBasicAudioConfig(&_this->spec)) { - sceAudioSRCChRelease(); - } else { - sceAudioChRelease(_this->hidden->channel); + if (device->hidden) { + if (device->hidden->channel >= 0) { + if (!isBasicAudioConfig(&device->spec)) { + sceAudioSRCChRelease(); + } else { + sceAudioChRelease(device->hidden->channel); + } + device->hidden->channel = -1; } - _this->hidden->channel = -1; - } - if (_this->hidden->rawbuf != NULL) { - SDL_aligned_free(_this->hidden->rawbuf); - _this->hidden->rawbuf = NULL; + if (device->hidden->rawbuf != NULL) { + SDL_aligned_free(device->hidden->rawbuf); + device->hidden->rawbuf = NULL; + } + SDL_free(device->hidden); + device->hidden = NULL; } } -static void PSPAUDIO_ThreadInit(SDL_AudioDevice *_this) +static void PSPAUDIO_ThreadInit(SDL_AudioDevice *device) { /* Increase the priority of this audio thread by 1 to put it ahead of other SDL threads. */ - SceUID thid; + const SceUID thid = sceKernelGetThreadId(); SceKernelThreadInfo status; - thid = sceKernelGetThreadId(); status.size = sizeof(SceKernelThreadInfo); if (sceKernelReferThreadStatus(thid, &status) == 0) { sceKernelChangeThreadPriority(thid, status.currentPriority - 1); @@ -173,25 +163,20 @@ static void PSPAUDIO_ThreadInit(SDL_AudioDevice *_this) static SDL_bool PSPAUDIO_Init(SDL_AudioDriverImpl *impl) { - /* Set the function pointers */ impl->OpenDevice = PSPAUDIO_OpenDevice; impl->PlayDevice = PSPAUDIO_PlayDevice; impl->WaitDevice = PSPAUDIO_WaitDevice; impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf; impl->CloseDevice = PSPAUDIO_CloseDevice; impl->ThreadInit = PSPAUDIO_ThreadInit; - - /* PSP audio device */ impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - /* - impl->HasCaptureSupport = SDL_TRUE; - impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; - */ - return SDL_TRUE; /* this audio target is available. */ + //impl->HasCaptureSupport = SDL_TRUE; + //impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; + return SDL_TRUE; } AudioBootStrap PSPAUDIO_bootstrap = { "psp", "PSP audio driver", PSPAUDIO_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_PSP */ +#endif // SDL_AUDIO_DRIVER_PSP diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index 5a13a06d..fb6c3518 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -43,13 +43,12 @@ static pa_context *pulseaudio_context = NULL; static SDL_Thread *pulseaudio_hotplug_thread = NULL; static SDL_AtomicInt pulseaudio_hotplug_thread_active; -/* These are the OS identifiers (i.e. ALSA strings)... */ +// 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; - +// ... and these are the PulseAudio device indices of the default devices. +static uint32_t default_sink_index = 0; +static uint32_t default_source_index = 0; static const char *(*PULSEAUDIO_pa_get_library_version)(void); static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto)( @@ -359,12 +358,6 @@ failed: return -1; } -/* This function waits until it is possible to write a full sound buffer */ -static void PULSEAUDIO_WaitDevice(SDL_AudioDevice *_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; @@ -373,50 +366,56 @@ static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata) PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); } -static void PULSEAUDIO_PlayDevice(SDL_AudioDevice *_this) +/* This function waits until it is possible to write a full sound buffer */ +static void PULSEAUDIO_WaitDevice(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; - int available = h->mixlen; - int written = 0; - int cpy; + struct SDL_PrivateAudioData *h = device->hidden; /*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; - } + while (!SDL_AtomicGet(&device->shutdown) && (h->bytes_requested < (device->buffer_size / 2))) { + /*printf("PULSEAUDIO WAIT IN WAITDEVICE!\n");*/ + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); - 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; - } + 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 WAITDEVICE!\n");*/ + SDL_AudioDeviceDisconnected(device); + break; } } - PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); +} + +static void PULSEAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) +{ + struct SDL_PrivateAudioData *h = device->hidden; + + /*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/ + + SDL_assert(h->bytes_requested >= buffer_size); + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + const int rc = PULSEAUDIO_pa_stream_write(h->stream, buffer, buffer_size, NULL, 0LL, PA_SEEK_RELATIVE); + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + if (rc < 0) { + SDL_AudioDeviceDisconnected(device); + return; + } + + /*printf("PULSEAUDIO FEED! nbytes=%d\n", buffer_size);*/ + h->bytes_requested -= buffer_size; + /*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/ } -static Uint8 *PULSEAUDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *PULSEAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + struct SDL_PrivateAudioData *h = device->hidden; + *buffer_size = SDL_min(*buffer_size, h->bytes_requested); + return device->hidden->mixbuf; } static void ReadCallback(pa_stream *p, size_t nbytes, void *userdata) @@ -425,67 +424,70 @@ static void ReadCallback(pa_stream *p, size_t nbytes, void *userdata) 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(SDL_AudioDevice *_this, void *buffer, int buflen) +static void PULSEAUDIO_WaitCaptureDevice(SDL_AudioDevice *device) { - struct SDL_PrivateAudioData *h = _this->hidden; - const void *data = NULL; - size_t nbytes = 0; - int retval = 0; + struct SDL_PrivateAudioData *h = device->hidden; + + if (h->capturebuf != NULL) { + return; // there's still data available to read. + } PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); - while (SDL_AtomicGet(&_this->enabled)) { - if (h->capturebuf != NULL) { - 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. */ + while (!SDL_AtomicGet(&device->shutdown)) { + 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 WAITCAPTUREDEVICE!\n"); + SDL_AudioDeviceDisconnected(device); 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; + } else if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) { + // a new fragment is available! + const void *data = NULL; + size_t nbytes = 0; + PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); + SDL_assert(nbytes > 0); + if (data == NULL) { // If NULL, then the buffer had a hole, ignore that + PULSEAUDIO_pa_stream_drop(h->stream); // drop this fragment. + } else { + // store this fragment's data for use with CaptureFromDevice + //printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes); + h->capturebuf = (const Uint8 *)data; + h->capturelen = nbytes; 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 == NULL) { - 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(SDL_AudioDevice *_this) +static int PULSEAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { - struct SDL_PrivateAudioData *h = _this->hidden; + struct SDL_PrivateAudioData *h = device->hidden; + + if (h->capturebuf != NULL) { + const int cpy = SDL_min(buflen, h->capturelen); + if (cpy > 0) { + //printf("PULSEAUDIO: fed %d captured bytes\n", cpy); + SDL_memcpy(buffer, h->capturebuf, cpy); + h->capturebuf += cpy; + h->capturelen -= cpy; + } + if (h->capturelen == 0) { + h->capturebuf = NULL; + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); // don't know if you _have_ to lock for this, but just in case. + PULSEAUDIO_pa_stream_drop(h->stream); // done with this fragment. + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + } + return cpy; /* new data, return it. */ + } + + return 0; +} + +static void PULSEAUDIO_FlushCapture(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *h = device->hidden; const void *data = NULL; size_t nbytes = 0; @@ -497,11 +499,11 @@ static void PULSEAUDIO_FlushCapture(SDL_AudioDevice *_this) h->capturelen = 0; } - while (SDL_AtomicGet(&_this->enabled) && (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0)) { + while (!SDL_AtomicGet(&device->shutdown) && (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); + SDL_AudioDeviceDisconnected(device); break; } @@ -515,22 +517,23 @@ static void PULSEAUDIO_FlushCapture(SDL_AudioDevice *_this) PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); } -static void PULSEAUDIO_CloseDevice(SDL_AudioDevice *_this) +static void PULSEAUDIO_CloseDevice(SDL_AudioDevice *device) { PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); - if (_this->hidden->stream) { - if (_this->hidden->capturebuf != NULL) { - PULSEAUDIO_pa_stream_drop(_this->hidden->stream); + if (device->hidden->stream) { + if (device->hidden->capturebuf != NULL) { + PULSEAUDIO_pa_stream_drop(device->hidden->stream); } - PULSEAUDIO_pa_stream_disconnect(_this->hidden->stream); - PULSEAUDIO_pa_stream_unref(_this->hidden->stream); + PULSEAUDIO_pa_stream_disconnect(device->hidden->stream); + PULSEAUDIO_pa_stream_unref(device->hidden->stream); } + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); // in case the device thread is waiting somewhere, this will unblock it. PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden->device_name); - SDL_free(_this->hidden); + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden->device_name); + SDL_free(device->hidden); } static void SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) @@ -551,15 +554,13 @@ static void SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); } -static SDL_bool FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle) +static SDL_bool FindDeviceName(SDL_AudioDevice *device) { - const uint32_t idx = ((uint32_t)((intptr_t)handle)) - 1; + struct SDL_PrivateAudioData *h = device->hidden; + SDL_assert(device->handle != NULL); // this was a thing in SDL2, but shouldn't be in SDL3. + const uint32_t idx = ((uint32_t)((intptr_t)device->handle)) - 1; - if (handle == NULL) { /* NULL == default device. */ - return SDL_TRUE; - } - - if (iscapture) { + if (device->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)); @@ -573,8 +574,9 @@ 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(SDL_AudioDevice *_this, const char *devname) +static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *device) { + const SDL_bool iscapture = device->iscapture; struct SDL_PrivateAudioData *h = NULL; SDL_AudioFormat test_format; const SDL_AudioFormat *closefmts; @@ -582,7 +584,6 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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; @@ -590,14 +591,13 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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 == NULL) { + h = device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); /* Try for a closest match on audio format */ - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); @@ -632,28 +632,27 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) if (!test_format) { return SDL_SetError("pulseaudio: Unsupported audio format"); } - _this->spec.format = test_format; + device->spec.format = test_format; paspec.format = format; /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); /* Allocate mixing buffer */ if (!iscapture) { - h->mixlen = _this->spec.size; - h->mixbuf = (Uint8 *)SDL_malloc(h->mixlen); + h->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); if (h->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(h->mixbuf, _this->spec.silence, _this->spec.size); + SDL_memset(h->mixbuf, device->silence_value, device->buffer_size); } - paspec.channels = _this->spec.channels; - paspec.rate = _this->spec.freq; + paspec.channels = device->spec.channels; + paspec.rate = device->spec.freq; /* Reduced prebuffering compared to the defaults. */ - paattr.fragsize = _this->spec.size; - paattr.tlength = h->mixlen; + paattr.fragsize = device->buffer_size; + paattr.tlength = device->buffer_size; paattr.prebuf = -1; paattr.maxlength = -1; paattr.minreq = -1; @@ -661,14 +660,13 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); - if (!FindDeviceName(h, iscapture, _this->handle)) { + if (!FindDeviceName(device)) { 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); + PULSEAUDIO_pa_channel_map_init_auto(&pacmap, device->spec.channels, PA_CHANNEL_MAP_WAVEEX); h->stream = PULSEAUDIO_pa_stream_new( pulseaudio_context, @@ -684,11 +682,8 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) 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 != NULL) { - flags |= PA_STREAM_DONT_MOVE; - } + // SDL manages device moves if the default changes, so don't ever let Pulse automatically migrate this stream. + flags |= PA_STREAM_DONT_MOVE; if (iscapture) { PULSEAUDIO_pa_stream_set_read_callback(h->stream, ReadCallback, h); @@ -744,62 +739,46 @@ static SDL_AudioFormat PulseFormatToSDLFormat(pa_sample_format_t format) } } -/* This is called when PulseAudio adds an output ("sink") device. */ +// This is called when PulseAudio adds an output ("sink") device. +// !!! FIXME: this is almost identical to SourceInfoCallback, merge the two. 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; + const SDL_bool add = (SDL_bool) ((intptr_t)data); if (add) { + SDL_AudioSpec spec; + spec.format = PulseFormatToSDLFormat(i->sample_spec.format); + spec.channels = i->sample_spec.channels; + spec.freq = i->sample_spec.rate; SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *)((intptr_t)i->index + 1)); } if (default_sink_path != NULL && SDL_strcmp(i->name, default_sink_path) == 0) { - if (default_sink_name != NULL) { - SDL_free(default_sink_name); - } - default_sink_name = SDL_strdup(i->description); + default_sink_index = i->index; } } PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); } /* This is called when PulseAudio adds a capture ("source") device. */ +// !!! FIXME: this is almost identical to SinkInfoCallback, merge the two. 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; + /* Maybe skip "monitor" sources. These are just output from other sinks. */ + if (i && (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX))) { + const SDL_bool add = (SDL_bool) ((intptr_t)data); + + if (add) { + SDL_AudioSpec spec; spec.format = PulseFormatToSDLFormat(i->sample_spec.format); - spec.silence = 0; - spec.samples = 0; - spec.size = 0; - spec.callback = NULL; - spec.userdata = NULL; + spec.channels = i->sample_spec.channels; + spec.freq = i->sample_spec.rate; + SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *)((intptr_t)i->index + 1)); + } - if (add) { - SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *)((intptr_t)i->index + 1)); - } - - if (default_source_path != NULL && SDL_strcmp(i->name, default_source_path) == 0) { - if (default_source_name != NULL) { - SDL_free(default_source_name); - } - default_source_name = SDL_strdup(i->description); - } + if (default_source_path != NULL && SDL_strcmp(i->name, default_source_path) == 0) { + default_source_index = i->index; } } PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); @@ -807,14 +786,22 @@ static void SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_la 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); + if (!default_sink_path || (SDL_strcmp(i->default_sink_name, default_sink_path) != 0)) { + /*printf("DEFAULT SINK PATH CHANGED TO '%s'\n", i->default_sink_name);*/ + SDL_free(default_sink_path); + default_sink_path = SDL_strdup(i->default_sink_name); + } + + if (!default_source_path || (SDL_strcmp(i->default_source_name, default_source_path) != 0)) { + /*printf("DEFAULT SOURCE PATH CHANGED TO '%s'\n", i->default_source_name);*/ + SDL_free(default_source_path); + 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. */ +// 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); @@ -825,29 +812,41 @@ static void HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint3 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 (changed) { + PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL)); + } + + /* 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)); + // removes we can handle just with the device index. + SDL_AudioDeviceDisconnected(SDL_FindPhysicalAudioDeviceByHandle((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 void CheckDefaultDevice(uint32_t *prev_default, uint32_t new_default) +{ + if (*prev_default != new_default) { + SDL_AudioDevice *device = SDL_FindPhysicalAudioDeviceByHandle((void *)((intptr_t)new_default + 1)); + if (device) { + *prev_default = new_default; + SDL_DefaultAudioDeviceChanged(device); + } + } +} + +// this runs as a thread while the Pulse target is initialized to catch hotplug events. static int SDLCALL HotplugThread(void *data) { + uint32_t prev_default_sink_index = default_sink_index; + uint32_t prev_default_source_index = default_source_index; pa_operation *op; SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); @@ -855,7 +854,7 @@ static int SDLCALL HotplugThread(void *data) 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); + op = PULSEAUDIO_pa_context_subscribe(pulseaudio_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SERVER, NULL, NULL); SDL_PostSemaphore((SDL_Semaphore *) data); @@ -865,6 +864,13 @@ static int SDLCALL HotplugThread(void *data) PULSEAUDIO_pa_operation_unref(op); op = NULL; } + + // Update default devices; don't hold the pulse lock during this, since it could deadlock vs a playing device that we're about to lock here. + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + CheckDefaultDevice(&prev_default_sink_index, default_sink_index); + CheckDefaultDevice(&prev_default_source_index, default_source_index); + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + } if (op) { @@ -874,9 +880,11 @@ static int SDLCALL HotplugThread(void *data) PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, NULL, NULL); PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); return 0; + + } -static void PULSEAUDIO_DetectDevices(void) +static void PULSEAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { SDL_Semaphore *ready_sem = SDL_CreateSemaphore(0); @@ -886,44 +894,24 @@ static void PULSEAUDIO_DetectDevices(void) WaitForPulseOperation(PULSEAUDIO_pa_context_get_source_info_list(pulseaudio_context, SourceInfoCallback, (void *)((intptr_t)SDL_TRUE))); PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + SDL_AudioDevice *device; + device = SDL_FindPhysicalAudioDeviceByHandle((void *)((intptr_t)default_sink_index + 1)); + if (device) { + *default_output = device; + } + + device = SDL_FindPhysicalAudioDeviceByHandle((void *)((intptr_t)default_source_index + 1)); + if (device) { + *default_capture = device; + } + /* 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. */ + pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, ready_sem); // !!! FIXME: this can probably survive in significantly less stack space. SDL_WaitSemaphore(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 == NULL) { - return SDL_SetError("PulseAudio could not find a default source"); - } - target = default_source_name; - } else { - if (default_sink_name == NULL) { - 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 != NULL) { - *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) { @@ -941,10 +929,9 @@ static void PULSEAUDIO_Deinitialize(void) 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; + + default_source_index = 0; + default_sink_index = 0; UnloadPulseAudioLibrary(); } @@ -968,12 +955,11 @@ static SDL_bool PULSEAUDIO_Init(SDL_AudioDriverImpl *impl) impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf; impl->CloseDevice = PULSEAUDIO_CloseDevice; impl->Deinitialize = PULSEAUDIO_Deinitialize; + impl->WaitCaptureDevice = PULSEAUDIO_WaitCaptureDevice; 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. */ } diff --git a/src/audio/pulseaudio/SDL_pulseaudio.h b/src/audio/pulseaudio/SDL_pulseaudio.h index 709f00da..10a7d9d1 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.h +++ b/src/audio/pulseaudio/SDL_pulseaudio.h @@ -36,7 +36,6 @@ struct SDL_PrivateAudioData /* Raw mixing buffer */ Uint8 *mixbuf; - int mixlen; int bytes_requested; /* bytes of data the hardware wants _now_. */ diff --git a/src/audio/qnx/SDL_qsa_audio.c b/src/audio/qnx/SDL_qsa_audio.c index 92f999fb..5c60e555 100644 --- a/src/audio/qnx/SDL_qsa_audio.c +++ b/src/audio/qnx/SDL_qsa_audio.c @@ -19,13 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -/* - * !!! FIXME: streamline this a little by removing all the - * !!! FIXME: if (capture) {} else {} sections that are identical - * !!! FIXME: except for one flag. - */ - -/* !!! FIXME: can this target support hotplugging? */ +// !!! FIXME: can this target support hotplugging? #include "../../SDL_internal.h" @@ -48,7 +42,7 @@ #include "../SDL_audio_c.h" #include "SDL_qsa_audio.h" -/* default channel communication parameters */ +// default channel communication parameters #define DEFAULT_CPARAMS_RATE 44100 #define DEFAULT_CPARAMS_VOICES 1 @@ -56,32 +50,17 @@ #define DEFAULT_CPARAMS_FRAGS_MIN 1 #define DEFAULT_CPARAMS_FRAGS_MAX 1 -/* List of found devices */ -#define QSA_MAX_DEVICES 32 -#define QSA_MAX_NAME_LENGTH 81+16 /* Hardcoded in QSA, can't be changed */ - -typedef struct _QSA_Device -{ - char name[QSA_MAX_NAME_LENGTH]; /* Long audio device name for SDL */ - int cardno; - int deviceno; -} QSA_Device; - -QSA_Device qsa_playback_device[QSA_MAX_DEVICES]; -uint32_t qsa_playback_devices; - -QSA_Device qsa_capture_device[QSA_MAX_DEVICES]; -uint32_t qsa_capture_devices; +#define QSA_MAX_NAME_LENGTH 81+16 // Hardcoded in QSA, can't be changed 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(SDL_AudioDevice *_this) +// !!! FIXME: does this need to be here? Does the SDL version not work? +static void QSA_ThreadInit(SDL_AudioDevice *device) { - /* Increase default 10 priority to 25 to avoid jerky sound */ + // Increase default 10 priority to 25 to avoid jerky sound struct sched_param param; if (SchedGet(0, 0, ¶m) != -1) { param.sched_priority = param.sched_curpriority + 15; @@ -89,7 +68,7 @@ static void QSA_ThreadInit(SDL_AudioDevice *_this) } } -/* PCM channel parameters initialize function */ +// PCM channel parameters initialize function static void QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) { SDL_zerop(cpars); @@ -106,209 +85,150 @@ static void QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; } -/* This function waits until it is possible to write a full sound buffer */ -static void QSA_WaitDevice(SDL_AudioDevice *_this) +// This function waits until it is possible to write a full sound buffer +static void QSA_WaitDevice(SDL_AudioDevice *device) { int result; - /* Setup timeout for playing one fragment equal to 2 seconds */ - /* 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 ? SDL_IOR_READ : SDL_IOR_WRITE, + // Setup timeout for playing one fragment equal to 2 seconds + // 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(device->hidden->audio_fd, + device->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE, 2 * 1000); switch (result) { case -1: - SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno)); + SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno)); // !!! FIXME: Should we just disconnect the device in this case? break; case 0: - SDL_SetError("QSA: timeout on buffer waiting occurred"); - _this->hidden->timeout_on_wait = 1; + device->hidden->timeout_on_wait = SDL_TRUE; // !!! FIXME: Should we just disconnect the device in this case? break; default: - _this->hidden->timeout_on_wait = 0; + device->hidden->timeout_on_wait = SDL_FALSE; break; } } -static void QSA_PlayDevice(SDL_AudioDevice *_this) +static void QSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - snd_pcm_channel_status_t cstatus; - int written; - int status; - int towrite; - void *pcmbuffer; - - if (!SDL_AtomicGet(&_this->enabled) || !_this->hidden) { + if (SDL_AtomicGet(&device->shutdown) || !device->hidden) { return; } - towrite = _this->spec.size; - pcmbuffer = _this->hidden->pcm_buf; + int towrite = buflen; - /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ - do { - written = - snd_pcm_plugin_write(_this->hidden->audio_handle, pcmbuffer, - towrite); - if (written != towrite) { - /* Check if samples playback got stuck somewhere in hardware or in */ - /* the audio device driver */ - if ((errno == EAGAIN) && (written == 0)) { - if (_this->hidden->timeout_on_wait != 0) { - SDL_SetError("QSA: buffer playback timeout"); - return; + // Write the audio data, checking for EAGAIN (buffer full) and underrun + while ((towrite > 0) && !SDL_AtomicGet(&device->shutdown)); + const int bw = snd_pcm_plugin_write(device->hidden->audio_handle, buffer, towrite); + if (bw != towrite) { + // Check if samples playback got stuck somewhere in hardware or in the audio device driver + if ((errno == EAGAIN) && (bw == 0)) { + if (device->hidden->timeout_on_wait) { + return; // oh well, try again next time. !!! FIXME: Should we just disconnect the device in this case? } } - /* Check for errors or conditions */ + // Check for errors or conditions if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - /* Let a little CPU time go by and try to write again */ - SDL_Delay(1); + SDL_Delay(1); // Let a little CPU time go by and try to write again - /* if we wrote some data */ - towrite -= written; - pcmbuffer += written * _this->spec.channels; + // if we wrote some data + towrite -= bw; + buffer += bw * device->spec.channels; + continue; + } else if ((errno == EINVAL) || (errno == EIO)) { + snd_pcm_channel_status_t cstatus; + SDL_zero(cstatus); + cstatus.channel = device->iscapture ? SND_PCM_CHANNEL_CAPTURE : SND_PCM_CHANNEL_PLAYBACK; + + int status = snd_pcm_plugin_status(device->hidden->audio_handle, &cstatus); + if (status < 0) { + QSA_SetError("snd_pcm_plugin_status", status); + return; // !!! FIXME: disconnect the device? + } else if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || (cstatus.status == SND_PCM_STATUS_READY)) { + status = snd_pcm_plugin_prepare(device->hidden->audio_handle, device->iscapture ? SND_PCM_CHANNEL_CAPTURE : SND_PCM_CHANNEL_PLAYBACK); + if (status < 0) { + QSA_SetError("snd_pcm_plugin_prepare", status); + return; // !!! FIXME: disconnect the device? + } + } continue; } else { - if ((errno == EINVAL) || (errno == EIO)) { - SDL_zero(cstatus); - if (!_this->hidden->iscapture) { - cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; - } else { - cstatus.channel = SND_PCM_CHANNEL_CAPTURE; - } - - status = - snd_pcm_plugin_status(_this->hidden->audio_handle, - &cstatus); - if (status < 0) { - QSA_SetError("snd_pcm_plugin_status", status); - return; - } - - if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || - (cstatus.status == SND_PCM_STATUS_READY)) { - if (!_this->hidden->iscapture) { - status = - snd_pcm_plugin_prepare(_this->hidden-> - audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - status = - snd_pcm_plugin_prepare(_this->hidden-> - audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - if (status < 0) { - QSA_SetError("snd_pcm_plugin_prepare", status); - return; - } - } - continue; - } else { - return; - } + return; // !!! FIXME: disconnect the device? } } else { - /* we wrote all remaining data */ - towrite -= written; - pcmbuffer += written * _this->spec.channels; + // we wrote all remaining data + towrite -= bw; + buffer += bw * device->spec.channels; } - } while ((towrite > 0) && SDL_AtomicGet(&_this->enabled)); + } - /* If we couldn't write, assume fatal error for now */ + // If we couldn't write, assume fatal error for now if (towrite != 0) { - SDL_OpenedAudioDeviceDisconnected(_this); + SDL_AudioDeviceDisconnected(device); } } -static Uint8 *QSA_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *QSA_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->pcm_buf; + return device->hidden->pcm_buf; } -static void QSA_CloseDevice(SDL_AudioDevice *_this) +static void QSA_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->audio_handle != NULL) { -#if _NTO_VERSION < 710 - if (!_this->hidden->iscapture) { - /* Finish playing available samples */ - snd_pcm_plugin_flush(_this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - /* Cancel unread samples during capture */ - snd_pcm_plugin_flush(_this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); + if (device->hidden) { + if (device->hidden->audio_handle != NULL) { + #if _NTO_VERSION < 710 + // Finish playing available samples or cancel unread samples during capture + snd_pcm_plugin_flush(device->hidden->audio_handle, device->iscapture ? SND_PCM_CHANNEL_CAPTURE : SND_PCM_CHANNEL_PLAYBACK); + #endif + snd_pcm_close(device->hidden->audio_handle); } -#endif - snd_pcm_close(_this->hidden->audio_handle); - } - SDL_free(_this->hidden->pcm_buf); - SDL_free(_this->hidden); + SDL_free(device->hidden->pcm_buf); + SDL_free(device->hidden); + device->hidden = NULL; + } } -static int QSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int QSA_OpenDevice(SDL_AudioDevice *device) { -#if 0 - /* !!! FIXME: SDL2 used to pass this handle. What's the alternative? */ - const QSA_Device *device = (const QSA_Device *) handle; -#else - const QSA_Device *device = NULL; -#endif - int status = 0; - int format = 0; - SDL_AudioFormat test_format = 0; - const SDL_AudioFormat *closefmts; - snd_pcm_channel_setup_t csetup; - snd_pcm_channel_params_t cparams; - SDL_bool iscapture = _this->iscapture; + if (device->iscapture) { + return SDL_SetError("SDL capture support isn't available on QNX atm"); // !!! FIXME: most of this code has support for capture devices, but there's no CaptureFromDevice, etc functions. Fill them in! + } - /* Initialize all variables that we clean on shutdown */ - _this->hidden = - (struct SDL_PrivateAudioData *) SDL_calloc(1, - (sizeof - (struct - SDL_PrivateAudioData))); - if (_this->hidden == NULL) { + SDL_assert(device->handle != NULL); // NULL used to mean "system default device" in SDL2; it does not mean that in SDL3. + const Uint32 sdlhandle = (Uint32) ((size_t) device->handle); + const uint32_t cardno = (uint32_t) (sdlhandle & 0xFFFF); + const uint32_t deviceno = (uint32_t) ((sdlhandle >> 16) & 0xFFFF); + const SDL_bool iscapture = device->iscapture; + int status = 0; + + // Initialize all variables that we clean on shutdown + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof (struct SDL_PrivateAudioData))); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - /* Initialize channel transfer parameters to default */ + // Initialize channel transfer parameters to default + snd_pcm_channel_params_t cparams; QSA_InitAudioParams(&cparams); - /* Initialize channel direction: capture or playback */ - _this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; - - if (device != NULL) { - /* Open requested audio device */ - _this->hidden->deviceno = device->deviceno; - _this->hidden->cardno = device->cardno; - status = snd_pcm_open(&_this->hidden->audio_handle, - device->cardno, device->deviceno, - iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); - } else { - /* Open system default audio device */ - status = snd_pcm_open_preferred(&_this->hidden->audio_handle, - &_this->hidden->cardno, - &_this->hidden->deviceno, - iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); - } - - /* Check if requested device is opened */ + // Open requested audio device + status = snd_pcm_open(&device->hidden->audio_handle, cardno, deviceno, iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); if (status < 0) { - _this->hidden->audio_handle = NULL; + device->hidden->audio_handle = NULL; return QSA_SetError("snd_pcm_open", status); } - /* Try for a closest match on audio format */ - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + // Try for a closest match on audio format + SDL_AudioFormat test_format = 0; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { - /* if match found set format to equivalent QSA format */ + // if match found set format to equivalent QSA format switch (test_format) { - #define CHECKFMT(sdlfmt, qsafmt) case SDL_AUDIO_##sdlfmt: format = SND_PCM_SFMT_##qsafmt; break + #define CHECKFMT(sdlfmt, qsafmt) case SDL_AUDIO_##sdlfmt: cparams.format.format = SND_PCM_SFMT_##qsafmt; break CHECKFMT(U8, U8); CHECKFMT(S8, S8); CHECKFMT(S16LSB, S16_LE); @@ -323,267 +243,192 @@ static int QSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) break; } - /* assumes test_format not 0 on success */ + // assumes test_format not 0 on success if (test_format == 0) { return SDL_SetError("QSA: Couldn't find any hardware audio formats"); } - _this->spec.format = test_format; + device->spec.format = test_format; - /* Set the audio format */ - cparams.format.format = format; + // Set mono/stereo/4ch/6ch/8ch audio + cparams.format.voices = device->spec.channels; - /* Set mono/stereo/4ch/6ch/8ch audio */ - cparams.format.voices = _this->spec.channels; + // Set rate + cparams.format.rate = device->spec.freq; - /* Set rate */ - cparams.format.rate = _this->spec.freq; - - /* Setup the transfer parameters according to cparams */ - status = snd_pcm_plugin_params(_this->hidden->audio_handle, &cparams); + // Setup the transfer parameters according to cparams + status = snd_pcm_plugin_params(device->hidden->audio_handle, &cparams); if (status < 0) { return QSA_SetError("snd_pcm_plugin_params", status); } - /* Make sure channel is setup right one last time */ + // Make sure channel is setup right one last time + snd_pcm_channel_setup_t csetup; SDL_zero(csetup); - if (!_this->hidden->iscapture) { - csetup.channel = SND_PCM_CHANNEL_PLAYBACK; - } else { - csetup.channel = SND_PCM_CHANNEL_CAPTURE; - } - - /* Setup an audio channel */ - if (snd_pcm_plugin_setup(_this->hidden->audio_handle, &csetup) < 0) { + csetup.channel = iscapture ? SND_PCM_CHANNEL_CAPTURE : SND_PCM_CHANNEL_PLAYBACK; + if (snd_pcm_plugin_setup(device->hidden->audio_handle, &csetup) < 0) { return SDL_SetError("QSA: Unable to setup channel"); } - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); + device->sample_frames = csetup.buf.block.frag_size; - _this->hidden->pcm_len = _this->spec.size; + // Calculate the final parameters for this audio specification + SDL_UpdatedAudioDeviceFormat(device); - if (_this->hidden->pcm_len == 0) { - _this->hidden->pcm_len = - csetup.buf.block.frag_size * _this->spec.channels * - (snd_pcm_format_width(format) / 8); - } - - /* - * Allocate memory to the audio buffer and initialize with silence - * (Note that buffer size must be a multiple of fragment size, so find - * closest multiple) - */ - _this->hidden->pcm_buf = - (Uint8 *) SDL_malloc(_this->hidden->pcm_len); - if (_this->hidden->pcm_buf == NULL) { + device->hidden->pcm_buf = (Uint8 *) SDL_malloc(device->buffer_size); + if (device->hidden->pcm_buf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->pcm_buf, _this->spec.silence, - _this->hidden->pcm_len); + SDL_memset(device->hidden->pcm_buf, device->silence_value, device->buffer_size); - /* get the file descriptor */ - if (!_this->hidden->iscapture) { - _this->hidden->audio_fd = - snd_pcm_file_descriptor(_this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - _this->hidden->audio_fd = - snd_pcm_file_descriptor(_this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - - if (_this->hidden->audio_fd < 0) { - return QSA_SetError("snd_pcm_file_descriptor", status); - } - - /* Prepare an audio channel */ - if (!_this->hidden->iscapture) { - /* Prepare audio playback */ - status = - snd_pcm_plugin_prepare(_this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - /* Prepare audio capture */ - status = - snd_pcm_plugin_prepare(_this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); + // get the file descriptor + device->hidden->audio_fd = snd_pcm_file_descriptor(device->hidden->audio_handle, csetup.channel); + if (device->hidden->audio_fd < 0) { + return QSA_SetError("snd_pcm_file_descriptor", device->hidden->audio_fd); } + // Prepare an audio channel + status = snd_pcm_plugin_prepare(device->hidden->audio_handle, csetup.channel) if (status < 0) { return QSA_SetError("snd_pcm_plugin_prepare", status); } - /* We're really ready to rock and roll. :-) */ - return 0; + return 0; // We're really ready to rock and roll. :-) } -static void QSA_DetectDevices(void) +static SDL_AudioFormat QnxFormatToSDLFormat(const int32_t qnxfmt) { - uint32_t it; - uint32_t cards; - uint32_t devices; - int32_t status; + switch (qnxfmt) { + #define CHECKFMT(sdlfmt, qsafmt) case SND_PCM_SFMT_##qsafmt: return SDL_AUDIO_##sdlfmt + CHECKFMT(U8, U8); + CHECKFMT(S8, S8); + CHECKFMT(S16LSB, S16_LE); + CHECKFMT(S16MSB, S16_BE); + CHECKFMT(S32LSB, S32_LE); + CHECKFMT(S32MSB, S32_BE); + CHECKFMT(F32LSB, FLOAT_LE); + CHECKFMT(F32MSB, FLOAT_BE); + #undef CHECKFMT + default: break; + } + return SDL_AUDIO_S16SYS; // oh well. +} - /* Detect amount of available devices */ - /* this value can be changed in the runtime */ - cards = snd_cards(); +static void QSA_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) +{ + // Detect amount of available devices + // this value can be changed in the runtime + int num_cards = 0; + (void) snd_cards_list(NULL, 0, &alloc_num_cards); + SDL_bool isstack = SDL_FALSE; + int *cards = SDL_small_alloc(int, num_cards, &isstack); + if (!cards) { + return; // we're in trouble. + } + int overflow_cards = 0; + const int total_num_cards = snd_cards_list(cards, num_cards, &overflow_cards); + // if overflow_cards > 0 or total_num_cards > num_cards, it changed at the last moment; oh well, we lost some. + num_cards = SDL_min(num_cards, total_num_cards); // ...but make sure it didn't _shrink_. - /* If io-audio manager is not running we will get 0 as number */ - /* of available audio devices */ - if (cards == 0) { - /* We have no any available audio devices */ + // If io-audio manager is not running we will get 0 as number of available audio devices + if (num_cards == 0) { // not any available audio devices? + SDL_small_free(cards, isstack); return; } - /* !!! FIXME: code duplication */ - /* Find requested devices by type */ - { /* output devices */ - /* Playback devices enumeration requested */ - for (it = 0; it < cards; it++) { - devices = 0; - do { - status = - snd_card_get_longname(it, - qsa_playback_device - [qsa_playback_devices].name, - QSA_MAX_NAME_LENGTH); - if (status == EOK) { - snd_pcm_t *handle; + // Find requested devices by type + for (int it = 0; it < num_cards; it++) { + const int card = cards[it]; + for (uint32_t deviceno = 0; ; deviceno++) { + int32_t status; + char name[QSA_MAX_NAME_LENGTH]; - /* Add device number to device name */ - sprintf(qsa_playback_device[qsa_playback_devices].name + - SDL_strlen(qsa_playback_device - [qsa_playback_devices].name), " d%d", - devices); + status = snd_card_get_longname(card, name, sizeof (name)); + if (status == EOK) { + snd_pcm_t *handle; - /* Store associated card number id */ - qsa_playback_device[qsa_playback_devices].cardno = it; + // Add device number to device name + char fullname[QSA_MAX_NAME_LENGTH + 32]; + SDL_snprintf(fullname, sizeof (fullname), "%s d%d", name, (int) deviceno); - /* Check if this device id could play anything */ - status = - snd_pcm_open(&handle, it, devices, - SND_PCM_OPEN_PLAYBACK); + // Check if this device id could play anything + SDL_bool iscapture = SDL_FALSE; + status = snd_pcm_open(&handle, card, deviceno, SND_PCM_OPEN_PLAYBACK); + if (status != EOK) { // no? See if it's a capture device instead. + #if 0 // !!! FIXME: most of this code has support for capture devices, but there's no CaptureFromDevice, etc functions. Fill them in! + status = snd_pcm_open(&handle, card, deviceno, SND_PCM_OPEN_CAPTURE); if (status == EOK) { - qsa_playback_device[qsa_playback_devices].deviceno = - devices; - status = snd_pcm_close(handle); - if (status == EOK) { - /* 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++; - } + iscapture = SDL_TRUE; + } + #endif + } + + if (status == EOK) { + SDL_AudioSpec spec; + SDL_AudioSpec *pspec = &spec; + snd_pcm_channel_setup_t csetup; + SDL_zero(csetup); + csetup.channel = iscapture ? SND_PCM_CHANNEL_CAPTURE : SND_PCM_CHANNEL_PLAYBACK; + + if (snd_pcm_plugin_setup(device->hidden->audio_handle, &csetup) < 0) { + pspec = NULL; // go on without spec info. } else { - /* Check if we got end of devices list */ - if (status == -ENOENT) { - break; - } + spec.format = QnxFormatToSDLFormat(csetup.format.format); + spec.channels = csetup.format.channels; + spec.freq = csetup.format.rate; + } + + status = snd_pcm_close(handle); + if (status == EOK) { + // !!! FIXME: I'm assuming each of these values are way less than 0xFFFF. Fix this if not. + SDL_assert(card <= 0xFFFF); + SDL_assert(deviceno <= 0xFFFF); + const Uint32 sdlhandle = ((Uint32) card) | (((Uint32) deviceno) << 16); + SDL_AddAudioDevice(iscapture, fullname, pspec, (void *) ((size_t) sdlhandle)); } } else { - break; + // Check if we got end of devices list + if (status == -ENOENT) { + break; + } } - - /* Check if we reached maximum devices count */ - if (qsa_playback_devices >= QSA_MAX_DEVICES) { - break; - } - devices++; - } while (1); - - /* Check if we reached maximum devices count */ - if (qsa_playback_devices >= QSA_MAX_DEVICES) { + } else { break; } } } - { /* capture devices */ - /* Capture devices enumeration requested */ - for (it = 0; it < cards; it++) { - devices = 0; - do { - status = - snd_card_get_longname(it, - qsa_capture_device - [qsa_capture_devices].name, - QSA_MAX_NAME_LENGTH); - if (status == EOK) { - snd_pcm_t *handle; + SDL_small_free(cards, isstack); - /* Add device number to device name */ - sprintf(qsa_capture_device[qsa_capture_devices].name + - SDL_strlen(qsa_capture_device - [qsa_capture_devices].name), " d%d", - devices); + // Try to open the "preferred" devices, which will tell us the card/device pairs for the default devices. + snd_pcm_t handle; + int cardno, deviceno; + if (snd_pcm_open_preferred(&handle, &cardno, &deviceno, SND_PCM_OPEN_PLAYBACK) == 0) { + snd_pcm_close(handle); + // !!! FIXME: I'm assuming each of these values are way less than 0xFFFF. Fix this if not. + SDL_assert(cardno <= 0xFFFF); + SDL_assert(deviceno <= 0xFFFF); + const Uint32 sdlhandle = ((Uint32) card) | (((Uint32) deviceno) << 16); + *default_output = SDL_FindPhysicalAudioDeviceByHandle((void *) ((size_t) sdlhandle)); + } - /* Store associated card number id */ - qsa_capture_device[qsa_capture_devices].cardno = it; - - /* Check if this device id could play anything */ - status = - snd_pcm_open(&handle, it, devices, - SND_PCM_OPEN_CAPTURE); - if (status == EOK) { - qsa_capture_device[qsa_capture_devices].deviceno = - devices; - status = snd_pcm_close(handle); - if (status == EOK) { - /* 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 { - /* Check if we got end of devices list */ - if (status == -ENOENT) { - break; - } - } - - /* Check if we reached maximum devices count */ - if (qsa_capture_devices >= QSA_MAX_DEVICES) { - break; - } - } else { - break; - } - devices++; - } while (1); - - /* Check if we reached maximum devices count */ - if (qsa_capture_devices >= QSA_MAX_DEVICES) { - break; - } - } + if (snd_pcm_open_preferred(&handle, &cardno, &deviceno, SND_PCM_OPEN_CAPTURE) == 0) { + snd_pcm_close(handle); + // !!! FIXME: I'm assuming each of these values are way less than 0xFFFF. Fix this if not. + SDL_assert(cardno <= 0xFFFF); + SDL_assert(deviceno <= 0xFFFF); + const Uint32 sdlhandle = ((Uint32) card) | (((Uint32) deviceno) << 16); + *default_capture = SDL_FindPhysicalAudioDeviceByHandle((void *) ((size_t) sdlhandle)); } } static void QSA_Deinitialize(void) { - /* Clear devices array on shutdown */ - /* !!! FIXME: we zero these on init...any reason to do it here? */ - SDL_zeroa(qsa_playback_device); - SDL_zeroa(qsa_capture_device); - qsa_playback_devices = 0; - qsa_capture_devices = 0; + // nothing to do here atm. } static SDL_bool QSA_Init(SDL_AudioDriverImpl * impl) { - /* Clear devices array */ - SDL_zeroa(qsa_playback_device); - SDL_zeroa(qsa_capture_device); - qsa_playback_devices = 0; - qsa_capture_devices = 0; - - /* Set function pointers */ - /* DeviceLock and DeviceUnlock functions are used default, */ - /* provided by SDL, which uses pthread_mutex for lock/unlock */ impl->DetectDevices = QSA_DetectDevices; impl->OpenDevice = QSA_OpenDevice; impl->ThreadInit = QSA_ThreadInit; @@ -592,21 +437,16 @@ static SDL_bool 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->HasCaptureSupport = 1; - impl->OnlyHasDefaultOutputDevice = 0; - impl->OnlyHasDefaultCaptureDevice = 0; + // !!! FIXME: most of this code has support for capture devices, but there's no CaptureFromDevice, etc functions. Fill them in! + //impl->HasCaptureSupport = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap QSAAUDIO_bootstrap = { "qsa", "QNX QSA Audio", QSA_Init, 0 }; -#endif /* SDL_AUDIO_DRIVER_QNX */ +#endif // SDL_AUDIO_DRIVER_QNX -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/qnx/SDL_qsa_audio.h b/src/audio/qnx/SDL_qsa_audio.h index da74db9c..29dba24f 100644 --- a/src/audio/qnx/SDL_qsa_audio.h +++ b/src/audio/qnx/SDL_qsa_audio.h @@ -30,23 +30,10 @@ struct SDL_PrivateAudioData { - /* SDL capture state */ - SDL_bool iscapture; - - /* The audio device handle */ - int cardno; - int deviceno; - snd_pcm_t *audio_handle; - - /* The audio file descriptor */ - int audio_fd; - - /* Select timeout status */ - uint32_t timeout_on_wait; - - /* Raw mixing buffer */ - Uint8 *pcm_buf; - Uint32 pcm_len; + snd_pcm_t *audio_handle; // The audio device handle + int audio_fd; // The audio file descriptor, for selecting on + SDL_bool timeout_on_wait; // Select timeout status + Uint8 *pcm_buf; // Raw mixing buffer }; #endif /* __SDL_QSA_AUDIO_H__ */ diff --git a/src/audio/sndio/SDL_sndioaudio.c b/src/audio/sndio/SDL_sndioaudio.c index 583aeb08..a7ac91dd 100644 --- a/src/audio/sndio/SDL_sndioaudio.c +++ b/src/audio/sndio/SDL_sndioaudio.c @@ -23,7 +23,7 @@ #ifdef SDL_AUDIO_DRIVER_SNDIO -/* OpenBSD sndio target */ +// OpenBSD sndio target #ifdef HAVE_STDIO_H #include @@ -72,14 +72,13 @@ static int load_sndio_sym(const char *fn, void **addr) { *addr = SDL_LoadFunction(sndio_handle, fn); if (*addr == NULL) { - /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ - return 0; + return 0; // Don't call SDL_SetError(): SDL_LoadFunction already did. } return 1; } -/* cast funcs to char* first, to please GCC's strict aliasing rules. */ +// 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 @@ -123,8 +122,7 @@ static int LoadSNDIOLibrary(void) if (sndio_handle == NULL) { sndio_handle = SDL_LoadObject(sndio_library); if (sndio_handle == NULL) { - retval = -1; - /* Don't call SDL_SetError(): SDL_LoadObject already did. */ + retval = -1; // Don't call SDL_SetError(): SDL_LoadObject already did. } else { retval = load_sndio_syms(); if (retval < 0) { @@ -147,129 +145,128 @@ static int LoadSNDIOLibrary(void) return 0; } -#endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ +#endif // SDL_AUDIO_DRIVER_SNDIO_DYNAMIC -static void SNDIO_WaitDevice(SDL_AudioDevice *_this) +static void SNDIO_WaitDevice(SDL_AudioDevice *device) { - /* no-op; SNDIO_sio_write() blocks if necessary. */ + const SDL_bool iscapture = device->iscapture; + + while (!SDL_AtomicGet(&device->shutdown)) { + if (SNDIO_sio_eof(device->hidden->dev)) { + SDL_AudioDeviceDisconnected(device); + return; + } + + const int nfds = SNDIO_sio_pollfd(device->hidden->dev, device->hidden->pfd, iscapture ? POLLIN : POLLOUT); + if (nfds <= 0 || poll(device->hidden->pfd, nfds, 10) < 0) { + SDL_AudioDeviceDisconnected(device); + return; + } + + const int revents = SNDIO_sio_revents(device->hidden->dev, device->hidden->pfd); + if (iscapture && (revents & POLLIN)) { + return; + } else if (!iscapture && (revents & POLLOUT)) { + return; + } else if (revents & POLLHUP) { + SDL_AudioDeviceDisconnected(device); + return; + } + } } -static void SNDIO_PlayDevice(SDL_AudioDevice *_this) +static void SNDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - 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) { - SDL_OpenedAudioDeviceDisconnected(_this); + // !!! FIXME: this should be non-blocking so we can check device->shutdown. + // this is set to blocking, because we _have_ to send the entire buffer down, but hopefully WaitDevice took most of the delay time. + if (SNDIO_sio_write(device->hidden->dev, buffer, buflen) != buflen) { + SDL_AudioDeviceDisconnected(device); // If we couldn't write, assume fatal error for now } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); #endif } -static int SNDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static int SNDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { - size_t r; - int revents; - int nfds; - - /* Emulate a blocking read */ - r = SNDIO_sio_read(_this->hidden->dev, buffer, buflen); - while (r == 0 && !SNDIO_sio_eof(_this->hidden->dev)) { - 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); - if (revents & POLLIN) { - r = SNDIO_sio_read(_this->hidden->dev, buffer, buflen); - } - if (revents & POLLHUP) { - break; - } + // We set capture devices non-blocking; this can safely return 0 in SDL3, but we'll check for EOF to cause a device disconnect. + const size_t br = SNDIO_sio_read(device->hidden->dev, buffer, buflen); + if ((br == 0) && SNDIO_sio_eof(device->hidden->dev)) { + return -1; } - return (int)r; + return (int) br; } -static void SNDIO_FlushCapture(SDL_AudioDevice *_this) +static void SNDIO_FlushCapture(SDL_AudioDevice *device) { char buf[512]; - - while (SNDIO_sio_read(_this->hidden->dev, buf, sizeof(buf)) != 0) { - /* do nothing */; + while (!SDL_AtomicGet(&device->shutdown) && (SNDIO_sio_read(device->hidden->dev, buf, sizeof(buf)) > 0)) { + // do nothing } } -static Uint8 *SNDIO_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *SNDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbuf; + return device->hidden->mixbuf; } -static void SNDIO_CloseDevice(SDL_AudioDevice *_this) +static void SNDIO_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->pfd != NULL) { - SDL_free(_this->hidden->pfd); + if (device->hidden) { + if (device->hidden->dev != NULL) { + SNDIO_sio_stop(device->hidden->dev); + SNDIO_sio_close(device->hidden->dev); + } + SDL_free(device->hidden->pfd); + SDL_free(device->hidden->mixbuf); + SDL_free(device->hidden); + device->hidden = NULL; } - if (_this->hidden->dev != NULL) { - SNDIO_sio_stop(_this->hidden->dev); - SNDIO_sio_close(_this->hidden->dev); - } - SDL_free(_this->hidden->mixbuf); - SDL_free(_this->hidden); } -static int SNDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int SNDIO_OpenDevice(SDL_AudioDevice *device) { - SDL_AudioFormat test_format; - const SDL_AudioFormat *closefmts; - struct sio_par par; - SDL_bool iscapture = _this->iscapture; - - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_zerop(_this->hidden); - _this->hidden->mixlen = _this->spec.size; + // !!! FIXME: we really should standardize this on a specific SDL hint. + const char *audiodev = SDL_getenv("AUDIODEV"); - /* Capture devices must be non-blocking for SNDIO_FlushCapture */ - _this->hidden->dev = SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY, - iscapture ? SIO_REC : SIO_PLAY, iscapture); - if (_this->hidden->dev == NULL) { + // Capture devices must be non-blocking for SNDIO_FlushCapture + device->hidden->dev = SNDIO_sio_open(audiodev != NULL ? audiodev : SIO_DEVANY, + device->iscapture ? SIO_REC : SIO_PLAY, device->iscapture); + if (device->hidden->dev == NULL) { 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)); - if (_this->hidden->pfd == NULL) { - return SDL_OutOfMemory(); - } + device->hidden->pfd = SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(device->hidden->dev)); + if (device->hidden->pfd == NULL) { + return SDL_OutOfMemory(); } + struct sio_par par; SNDIO_sio_initpar(&par); - par.rate = _this->spec.freq; - par.pchan = _this->spec.channels; - par.round = _this->spec.samples; + par.rate = device->spec.freq; + par.pchan = device->spec.channels; + par.round = device->sample_frames; par.appbufsz = par.round * 2; - /* Try for a closest match on audio format */ - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + // Try for a closest match on audio format + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { if (!SDL_AUDIO_ISFLOAT(test_format)) { par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0; par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0; par.bits = SDL_AUDIO_BITSIZE(test_format); - if (SNDIO_sio_setpar(_this->hidden->dev, &par) == 0) { + if (SNDIO_sio_setpar(device->hidden->dev, &par) == 0) { continue; } - if (SNDIO_sio_getpar(_this->hidden->dev, &par) == 0) { + if (SNDIO_sio_getpar(device->hidden->dev, &par) == 0) { return SDL_SetError("sio_getpar() failed"); } if (par.bps != SIO_BPS(par.bits)) { @@ -282,46 +279,44 @@ static int SNDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname) } if (!test_format) { - return SDL_SetError("%s: Unsupported audio format", "sndio"); + return SDL_SetError("sndio: Unsupported audio format"); } if ((par.bps == 4) && (par.sig) && (par.le)) { - _this->spec.format = SDL_AUDIO_S32LSB; + device->spec.format = SDL_AUDIO_S32LSB; } else if ((par.bps == 4) && (par.sig) && (!par.le)) { - _this->spec.format = SDL_AUDIO_S32MSB; + device->spec.format = SDL_AUDIO_S32MSB; } else if ((par.bps == 2) && (par.sig) && (par.le)) { - _this->spec.format = SDL_AUDIO_S16LSB; + device->spec.format = SDL_AUDIO_S16LSB; } else if ((par.bps == 2) && (par.sig) && (!par.le)) { - _this->spec.format = SDL_AUDIO_S16MSB; + device->spec.format = SDL_AUDIO_S16MSB; } else if ((par.bps == 1) && (par.sig)) { - _this->spec.format = SDL_AUDIO_S8; + device->spec.format = SDL_AUDIO_S8; } else if ((par.bps == 1) && (!par.sig)) { - _this->spec.format = SDL_AUDIO_U8; + device->spec.format = SDL_AUDIO_U8; } else { return SDL_SetError("sndio: Got unsupported hardware audio format."); } - _this->spec.freq = par.rate; - _this->spec.channels = par.pchan; - _this->spec.samples = par.round; + device->spec.freq = par.rate; + device->spec.channels = par.pchan; + device->sample_frames = par.round; - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); + // Calculate the final parameters for this audio specification + SDL_UpdatedAudioDeviceFormat(device); - /* Allocate mixing buffer */ - _this->hidden->mixlen = _this->spec.size; - _this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->hidden->mixlen); - if (_this->hidden->mixbuf == NULL) { + // Allocate mixing buffer + device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->buffer_size); + if (device->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->hidden->mixlen); + SDL_memset(device->hidden->mixbuf, device->silence_value, device->buffer_size); - if (!SNDIO_sio_start(_this->hidden->dev)) { + if (!SNDIO_sio_start(device->hidden->dev)) { return SDL_SetError("sio_start() failed"); } - /* We're ready to rock and roll. :-) */ - return 0; + return 0; // We're ready to rock and roll. :-) } static void SNDIO_Deinitialize(void) @@ -329,10 +324,10 @@ static void SNDIO_Deinitialize(void) UnloadSNDIOLibrary(); } -static void SNDIO_DetectDevices(void) +static void SNDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1); - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2); + *default_output = SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1); + *default_capture = SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2); } static SDL_bool SNDIO_Init(SDL_AudioDriverImpl *impl) @@ -341,12 +336,12 @@ static SDL_bool SNDIO_Init(SDL_AudioDriverImpl *impl) return SDL_FALSE; } - /* Set the function pointers */ impl->OpenDevice = SNDIO_OpenDevice; impl->WaitDevice = SNDIO_WaitDevice; impl->PlayDevice = SNDIO_PlayDevice; impl->GetDeviceBuf = SNDIO_GetDeviceBuf; impl->CloseDevice = SNDIO_CloseDevice; + impl->WaitCaptureDevice = SNDIO_WaitDevice; impl->CaptureFromDevice = SNDIO_CaptureFromDevice; impl->FlushCapture = SNDIO_FlushCapture; impl->Deinitialize = SNDIO_Deinitialize; @@ -355,11 +350,11 @@ static SDL_bool SNDIO_Init(SDL_AudioDriverImpl *impl) impl->AllowsArbitraryDeviceNames = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return SDL_TRUE; /* this audio target is available. */ + return SDL_TRUE; } AudioBootStrap SNDIO_bootstrap = { "sndio", "OpenBSD sndio", SNDIO_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_SNDIO */ +#endif // SDL_AUDIO_DRIVER_SNDIO diff --git a/src/audio/sndio/SDL_sndioaudio.h b/src/audio/sndio/SDL_sndioaudio.h index 17900979..6a36b7df 100644 --- a/src/audio/sndio/SDL_sndioaudio.h +++ b/src/audio/sndio/SDL_sndioaudio.h @@ -30,15 +30,9 @@ struct SDL_PrivateAudioData { - /* The audio device handle */ - struct sio_hdl *dev; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Polling structures for non-blocking sndio devices */ - struct pollfd *pfd; + struct sio_hdl *dev; // The audio device handle + Uint8 *mixbuf; // Raw mixing buffer + struct pollfd *pfd; // Polling structures for non-blocking sndio devices }; #endif /* SDL_sndioaudio_h_ */ diff --git a/src/audio/vita/SDL_vitaaudio.c b/src/audio/vita/SDL_vitaaudio.c index 5cd40e69..efe51955 100644 --- a/src/audio/vita/SDL_vitaaudio.c +++ b/src/audio/vita/SDL_vitaaudio.c @@ -38,41 +38,41 @@ #define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63) #define SCE_AUDIO_MAX_VOLUME 0x8000 -static int VITAAUD_OpenCaptureDevice(SDL_AudioDevice *_this) +static int VITAAUD_OpenCaptureDevice(SDL_AudioDevice *device) { - _this->spec.freq = 16000; - _this->spec.samples = 512; - _this->spec.channels = 1; + device->spec.freq = 16000; + device->spec.channels = 1; + device->sample_frames = 512; - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(device); - _this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE, 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO); + device->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); + if (device->hidden->port < 0) { + return SDL_SetError("Couldn't open audio in port: %x", device->hidden->port); } return 0; } -static int VITAAUD_OpenDevice(SDL_AudioDevice *_this, const char *devname) +static int VITAAUD_OpenDevice(SDL_AudioDevice *device) { 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; const SDL_AudioFormat *closefmts; - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { + device->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc(sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden, 0, sizeof(*_this->hidden)); + SDL_memset(device->hidden, 0, sizeof(*device->hidden)); - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { if (test_format == SDL_AUDIO_S16LSB) { - _this->spec.format = test_format; + device->spec.format = test_format; break; } } @@ -81,106 +81,127 @@ static int VITAAUD_OpenDevice(SDL_AudioDevice *_this, const char *devname) return SDL_SetError("Unsupported audio format"); } - if (_this->iscapture) { - return VITAAUD_OpenCaptureDevice(_this); + if (device->iscapture) { + return VITAAUD_OpenCaptureDevice(device); } - /* The sample count must be a multiple of 64. */ - _this->spec.samples = SCE_AUDIO_SAMPLE_ALIGN(_this->spec.samples); + // The sample count must be a multiple of 64. + device->sample_frames = SCE_AUDIO_SAMPLE_ALIGN(device->sample_frames); - /* Update the fragment size as size in bytes. */ - SDL_CalculateAudioSpec(&_this->spec); + // Update the fragment size as size in bytes. + SDL_UpdatedAudioDeviceFormat(device); /* 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 *)SDL_aligned_alloc(64, mixlen); - if (_this->hidden->rawbuf == NULL) { + mixlen = device->buffer_size * NUM_BUFFERS; + device->hidden->rawbuf = (Uint8 *)SDL_aligned_alloc(64, mixlen); + if (device->hidden->rawbuf == NULL) { return SDL_SetError("Couldn't allocate mixing buffer"); } - /* Setup the hardware channel. */ - if (_this->spec.channels == 1) { + // Setup the hardware channel. + if (device->spec.channels == 1) { format = SCE_AUDIO_OUT_MODE_MONO; } else { format = SCE_AUDIO_OUT_MODE_STEREO; } - if (_this->spec.freq < 48000) { + // the main port requires 48000Hz audio, so this drops to the background music port if necessary + if (device->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) { - SDL_aligned_free(_this->hidden->rawbuf); - _this->hidden->rawbuf = NULL; - return SDL_SetError("Couldn't open audio out port: %x", _this->hidden->port); + device->hidden->port = sceAudioOutOpenPort(port, device->sample_frames, device->spec.freq, format); + if (device->hidden->port < 0) { + SDL_aligned_free(device->hidden->rawbuf); + device->hidden->rawbuf = NULL; + return SDL_SetError("Couldn't open audio out port: %x", device->hidden->port); } - sceAudioOutSetVolume(_this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols); + sceAudioOutSetVolume(device->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols); - SDL_memset(_this->hidden->rawbuf, 0, mixlen); + SDL_memset(device->hidden->rawbuf, 0, mixlen); for (i = 0; i < NUM_BUFFERS; i++) { - _this->hidden->mixbufs[i] = &_this->hidden->rawbuf[i * _this->spec.size]; + device->hidden->mixbufs[i] = &device->hidden->rawbuf[i * device->buffer_size]; } - _this->hidden->next_buffer = 0; + device->hidden->next_buffer = 0; return 0; } -static void VITAAUD_PlayDevice(SDL_AudioDevice *_this) +static void VITAAUD_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { - 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; + sceAudioOutOutput(device->hidden->port, buffer); } -/* This function waits until it is possible to write a full sound buffer */ -static void VITAAUD_WaitDevice(SDL_AudioDevice *_this) +// This function waits until it is possible to write a full sound buffer +static void VITAAUD_WaitDevice(SDL_AudioDevice *device) { - /* Because we block when sending audio, there's no need for this function to do anything. */ + // !!! FIXME: we might just need to sleep roughly as long as playback buffers take to process, based on sample rate, etc. + while (!SDL_AtomicGet(&device->shutdown) && (sceAudioOutGetRestSample(device->hidden->port) >= device->buffer_size)) { + SDL_Delay(1); + } } -static Uint8 *VITAAUD_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *VITAAUD_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - return _this->hidden->mixbufs[_this->hidden->next_buffer]; + Uint8 *retval = device->hidden->mixbufs[device->hidden->next_buffer]; + device->hidden->next_buffer = (device->hidden->next_buffer + 1) % NUM_BUFFERS; + return retval; } -static void VITAAUD_CloseDevice(SDL_AudioDevice *_this) +static void VITAAUD_CloseDevice(SDL_AudioDevice *device) { - if (_this->hidden->port >= 0) { - if (_this->iscapture) { - sceAudioInReleasePort(_this->hidden->port); - } else { - sceAudioOutReleasePort(_this->hidden->port); + if (device->hidden) { + if (device->hidden->port >= 0) { + if (device->iscapture) { + sceAudioInReleasePort(device->hidden->port); + } else { + sceAudioOutReleasePort(device->hidden->port); + } + device->hidden->port = -1; } - _this->hidden->port = -1; - } - if (!_this->iscapture && _this->hidden->rawbuf != NULL) { - SDL_aligned_free(_this->hidden->rawbuf); - _this->hidden->rawbuf = NULL; + if (!device->iscapture && device->hidden->rawbuf != NULL) { + SDL_aligned_free(device->hidden->rawbuf); // this uses memalign(), not SDL_malloc(). + device->hidden->rawbuf = NULL; + } + SDL_free(device->hidden); + device->hidden = NULL; } } -static int VITAAUD_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) +static void VITAAUD_WaitCaptureDevice(SDL_AudioDevice *device) +{ + // there's only a blocking call to obtain more data, so we'll just sleep as + // long as a buffer would run. + const Uint64 endticks = SDL_GetTicks() + ((device->sample_frames * 1000) / device->spec.freq); + while (!SDL_AtomicGet(&device->shutdown) && (SDL_GetTicks() < endticks)) { + SDL_Delay(1); + } +} + +static int VITAAUD_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { int ret; - SDL_assert(buflen == _this->spec.size); - ret = sceAudioInInput(_this->hidden->port, buffer); + SDL_assert(buflen == device->buffer_size); + ret = sceAudioInInput(device->hidden->port, buffer); if (ret < 0) { return SDL_SetError("Failed to capture from device: %x", ret); } - return _this->spec.size; + return device->buffer_size; } -static void VITAAUD_ThreadInit(SDL_AudioDevice *_this) +static void VITAAUD_FlushCapture(SDL_AudioDevice *device) { - /* Increase the priority of this audio thread by 1 to put it - ahead of other SDL threads. */ + // just grab the latest and dump it. + sceAudioInInput(device->hidden->port, device->work_buffer); +} + +static void VITAAUD_ThreadInit(SDL_AudioDevice *device) +{ + // Increase the priority of this audio thread by 1 to put it ahead of other SDL threads. SceUID thid; SceKernelThreadInfo info; thid = sceKernelGetThreadId(); @@ -192,26 +213,25 @@ static void VITAAUD_ThreadInit(SDL_AudioDevice *_this) 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->WaitCaptureDevice = VITAAUD_WaitCaptureDevice; + impl->FlushCapture = VITAAUD_FlushCapture; 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. */ + return SDL_TRUE; } AudioBootStrap VITAAUD_bootstrap = { "vita", "VITA audio driver", VITAAUD_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_VITA */ +#endif // SDL_AUDIO_DRIVER_VITA diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c index ba3a9c53..2041bc88 100644 --- a/src/audio/wasapi/SDL_wasapi.c +++ b/src/audio/wasapi/SDL_wasapi.c @@ -24,6 +24,7 @@ #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_immdevice.h" +#include "../../thread/SDL_systhread.h" #include "../SDL_audio_c.h" #include "../SDL_sysaudio.h" @@ -32,7 +33,7 @@ #include "SDL_wasapi.h" -/* These constants aren't available in older SDKs */ +// These constants aren't available in older SDKs #ifndef AUDCLNT_STREAMFLAGS_RATEADJUST #define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000 #endif @@ -43,140 +44,367 @@ #define AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 0x80000000 #endif -/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ +// 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 void WASAPI_DetectDevices(void) +// WASAPI is _really_ particular about various things happening on the same thread, for COM and such, +// so we proxy various stuff to a single background thread to manage. + +typedef struct ManagementThreadPendingTask { - WASAPI_EnumerateEndpoints(); + ManagementThreadTask fn; + void *userdata; + int result; + SDL_Semaphore *task_complete_sem; + char *errorstr; + struct ManagementThreadPendingTask *next; +} ManagementThreadPendingTask; + +static SDL_Thread *ManagementThread = NULL; +static ManagementThreadPendingTask *ManagementThreadPendingTasks = NULL; +static SDL_Mutex *ManagementThreadLock = NULL; +static SDL_Condition *ManagementThreadCondition = NULL; +static SDL_AtomicInt ManagementThreadShutdown; + +static void ManagementThreadMainloop(void) +{ + SDL_LockMutex(ManagementThreadLock); + ManagementThreadPendingTask *task; + while (((task = SDL_AtomicGetPtr((void **) &ManagementThreadPendingTasks)) != NULL) || !SDL_AtomicGet(&ManagementThreadShutdown)) { + if (!task) { + SDL_WaitCondition(ManagementThreadCondition, ManagementThreadLock); // block until there's something to do. + } else { + SDL_AtomicSetPtr((void **) &ManagementThreadPendingTasks, task->next); // take task off the pending list. + SDL_UnlockMutex(ManagementThreadLock); // let other things add to the list while we chew on this task. + task->result = task->fn(task->userdata); // run this task. + if (task->task_complete_sem) { // something waiting on result? + task->errorstr = SDL_strdup(SDL_GetError()); + SDL_PostSemaphore(task->task_complete_sem); + } else { // nothing waiting, we're done, free it. + SDL_free(task); + } + SDL_LockMutex(ManagementThreadLock); // regrab the lock so we can get the next task; if nothing to do, we'll release the lock in SDL_WaitCondition. + } + } + SDL_UnlockMutex(ManagementThreadLock); // told to shut down and out of tasks, let go of the lock and return. } -static SDL_INLINE SDL_bool WasapiFailed(SDL_AudioDevice *_this, const HRESULT err) +int WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, int *wait_on_result) +{ + // We want to block for a result, but we are already running from the management thread! Just run the task now so we don't deadlock. + if ((wait_on_result != NULL) && (SDL_ThreadID() == SDL_GetThreadID(ManagementThread))) { + *wait_on_result = task(userdata); + return 0; // completed! + } + + if (SDL_AtomicGet(&ManagementThreadShutdown)) { + return SDL_SetError("Can't add task, we're shutting down"); + } + + ManagementThreadPendingTask *pending = SDL_calloc(1, sizeof(ManagementThreadPendingTask)); + if (!pending) { + return SDL_OutOfMemory(); + } + + pending->fn = task; + pending->userdata = userdata; + + if (wait_on_result) { + pending->task_complete_sem = SDL_CreateSemaphore(0); + if (!pending->task_complete_sem) { + SDL_free(pending); + return -1; + } + } + + pending->next = NULL; + + SDL_LockMutex(ManagementThreadLock); + + // add to end of task list. + ManagementThreadPendingTask *prev = NULL; + for (ManagementThreadPendingTask *i = SDL_AtomicGetPtr((void **) &ManagementThreadPendingTasks); i != NULL; i = i->next) { + prev = i; + } + + if (prev != NULL) { + prev->next = pending; + } else { + SDL_AtomicSetPtr((void **) &ManagementThreadPendingTasks, pending); + } + + // task is added to the end of the pending list, let management thread rip! + SDL_SignalCondition(ManagementThreadCondition); + SDL_UnlockMutex(ManagementThreadLock); + + if (wait_on_result) { + SDL_WaitSemaphore(pending->task_complete_sem); + SDL_DestroySemaphore(pending->task_complete_sem); + *wait_on_result = pending->result; + if (pending->errorstr) { + SDL_SetError("%s", pending->errorstr); + SDL_free(pending->errorstr); + } + SDL_free(pending); + } + + return 0; // successfully added (and possibly executed)! +} + +static int ManagementThreadPrepare(void) +{ + if (WASAPI_PlatformInit() == -1) { + return -1; + } + + ManagementThreadLock = SDL_CreateMutex(); + if (!ManagementThreadLock) { + WASAPI_PlatformDeinit(); + return -1; + } + + ManagementThreadCondition = SDL_CreateCondition(); + if (!ManagementThreadCondition) { + SDL_DestroyMutex(ManagementThreadLock); + ManagementThreadLock = NULL; + WASAPI_PlatformDeinit(); + return -1; + } + + return 0; +} + +typedef struct +{ + char *errorstr; + SDL_Semaphore *ready_sem; +} ManagementThreadEntryData; + +static int ManagementThreadEntry(void *userdata) +{ + ManagementThreadEntryData *data = (ManagementThreadEntryData *)userdata; + + if (ManagementThreadPrepare() < 0) { + data->errorstr = SDL_strdup(SDL_GetError()); + SDL_PostSemaphore(data->ready_sem); // unblock calling thread. + return 0; + } + + SDL_PostSemaphore(data->ready_sem); // unblock calling thread. + ManagementThreadMainloop(); + + WASAPI_PlatformDeinit(); + return 0; +} + +static int InitManagementThread(void) +{ + ManagementThreadEntryData mgmtdata; + SDL_zero(mgmtdata); + mgmtdata.ready_sem = SDL_CreateSemaphore(0); + if (!mgmtdata.ready_sem) { + return -1; + } + + SDL_AtomicSetPtr((void **) &ManagementThreadPendingTasks, NULL); + SDL_AtomicSet(&ManagementThreadShutdown, 0); + ManagementThread = SDL_CreateThreadInternal(ManagementThreadEntry, "SDLWASAPIMgmt", 256 * 1024, &mgmtdata); // !!! FIXME: maybe even smaller stack size? + if (!ManagementThread) { + return -1; + } + + SDL_WaitSemaphore(mgmtdata.ready_sem); + SDL_DestroySemaphore(mgmtdata.ready_sem); + + if (mgmtdata.errorstr) { + SDL_WaitThread(ManagementThread, NULL); + ManagementThread = NULL; + SDL_SetError("%s", mgmtdata.errorstr); + SDL_free(mgmtdata.errorstr); + return -1; + } + + return 0; +} + +static void DeinitManagementThread(void) +{ + if (ManagementThread) { + SDL_AtomicSet(&ManagementThreadShutdown, 1); + SDL_LockMutex(ManagementThreadLock); + SDL_SignalCondition(ManagementThreadCondition); + SDL_UnlockMutex(ManagementThreadLock); + SDL_WaitThread(ManagementThread, NULL); + ManagementThread = NULL; + } + + SDL_assert(SDL_AtomicGetPtr((void **) &ManagementThreadPendingTasks) == NULL); + + SDL_DestroyCondition(ManagementThreadCondition); + SDL_DestroyMutex(ManagementThreadLock); + ManagementThreadCondition = NULL; + ManagementThreadLock = NULL; + SDL_AtomicSet(&ManagementThreadShutdown, 0); +} + +typedef struct +{ + SDL_AudioDevice **default_output; + SDL_AudioDevice **default_capture; +} mgmtthrtask_DetectDevicesData; + +static int mgmtthrtask_DetectDevices(void *userdata) +{ + mgmtthrtask_DetectDevicesData *data = (mgmtthrtask_DetectDevicesData *)userdata; + WASAPI_EnumerateEndpoints(data->default_output, data->default_capture); + return 0; +} + +static void WASAPI_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) +{ + int rc; + mgmtthrtask_DetectDevicesData data = { default_output, default_capture }; + WASAPI_ProxyToManagementThread(mgmtthrtask_DetectDevices, &data, &rc); +} + +static int mgmtthrtask_DisconnectDevice(void *userdata) +{ + SDL_AudioDeviceDisconnected((SDL_AudioDevice *)userdata); + return 0; +} + +void WASAPI_DisconnectDevice(SDL_AudioDevice *device) +{ + // this runs async, so it can hold the device lock from the management thread. + WASAPI_ProxyToManagementThread(mgmtthrtask_DisconnectDevice, device, NULL); +} + +static SDL_bool WasapiFailed(SDL_AudioDevice *device, const HRESULT err) { if (err == S_OK) { return SDL_FALSE; } if (err == AUDCLNT_E_DEVICE_INVALIDATED) { - _this->hidden->device_lost = SDL_TRUE; - } else if (SDL_AtomicGet(&_this->enabled)) { - IAudioClient_Stop(_this->hidden->client); - SDL_OpenedAudioDeviceDisconnected(_this); - SDL_assert(!SDL_AtomicGet(&_this->enabled)); + device->hidden->device_lost = SDL_TRUE; + } else { + IAudioClient_Stop(device->hidden->client); + WASAPI_DisconnectDevice(device); } return SDL_TRUE; } -static int UpdateAudioStream(SDL_AudioDevice *_this, const SDL_AudioSpec *oldspec) +static int mgmtthrtask_ReleaseCaptureClient(void *userdata) { - /* 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. */ + IAudioCaptureClient_Release((IAudioCaptureClient *)userdata); + return 0; +} - 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_DestroyAudioStream(_this->stream); - _this->stream = NULL; - } 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_DestroyAudioStream(_this->stream); - if (_this->iscapture) { - _this->stream = SDL_CreateAudioStream(_this->spec.format, - _this->spec.channels, _this->spec.freq, - _this->callbackspec.format, - _this->callbackspec.channels, - _this->callbackspec.freq); - } else { - _this->stream = SDL_CreateAudioStream(_this->callbackspec.format, - _this->callbackspec.channels, - _this->callbackspec.freq, _this->spec.format, - _this->spec.channels, _this->spec.freq); - } +static int mgmtthrtask_ReleaseRenderClient(void *userdata) +{ + IAudioRenderClient_Release((IAudioRenderClient *)userdata); + return 0; +} - if (!_this->stream) { - return -1; /* SDL_CreateAudioStream should have called SDL_SetError. */ - } +static int mgmtthrtask_ResetWasapiDevice(void *userdata) +{ + SDL_AudioDevice *device = (SDL_AudioDevice *)userdata; + + if (!device || !device->hidden) { + return 0; } - /* 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) { - return SDL_OutOfMemory(); - } - _this->work_buffer = ptr; - _this->work_buffer_len = _this->spec.size; + if (device->hidden->client) { + IAudioClient_Stop(device->hidden->client); + IAudioClient_Release(device->hidden->client); + device->hidden->client = NULL; + } + + if (device->hidden->render) { + // this is silly, but this will block indefinitely if you call it from SDLMMNotificationClient_OnDefaultDeviceChanged, so + // proxy this to the management thread to be released later. + WASAPI_ProxyToManagementThread(mgmtthrtask_ReleaseRenderClient, device->hidden->render, NULL); + device->hidden->render = NULL; + } + + if (device->hidden->capture) { + // this is silly, but this will block indefinitely if you call it from SDLMMNotificationClient_OnDefaultDeviceChanged, so + // proxy this to the management thread to be released later. + WASAPI_ProxyToManagementThread(mgmtthrtask_ReleaseCaptureClient, device->hidden->capture, NULL); + device->hidden->capture = NULL; + } + + if (device->hidden->waveformat) { + CoTaskMemFree(device->hidden->waveformat); + device->hidden->waveformat = NULL; + } + + if (device->hidden->activation_handler) { + WASAPI_PlatformDeleteActivationHandler(device->hidden->activation_handler); + device->hidden->activation_handler = NULL; + } + + if (device->hidden->event) { + CloseHandle(device->hidden->event); + device->hidden->event = NULL; } return 0; } -static void ReleaseWasapiDevice(SDL_AudioDevice *_this); - -static SDL_bool RecoverWasapiDevice(SDL_AudioDevice *_this) +static void ResetWasapiDevice(SDL_AudioDevice *device) { - ReleaseWasapiDevice(_this); /* dump the lost device's handles. */ + int rc; + WASAPI_ProxyToManagementThread(mgmtthrtask_ResetWasapiDevice, device, &rc); +} - if (_this->hidden->default_device_generation) { - _this->hidden->default_device_generation = SDL_AtomicGet(_this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration); - } +static int mgmtthrtask_ActivateDevice(void *userdata) +{ + return WASAPI_ActivateDevice((SDL_AudioDevice *)userdata); +} - /* this can fail for lots of reasons, but the most likely is we had a - non-default device that was disconnected, so we can't recover. Default - devices try to reinitialize whatever the new default is, so it's more - likely to carry on here, but this handles a non-default device that - simply had its format changed in the Windows Control Panel. */ - if (WASAPI_ActivateDevice(_this, SDL_TRUE) == -1) { - SDL_OpenedAudioDeviceDisconnected(_this); +static int ActivateWasapiDevice(SDL_AudioDevice *device) +{ + int rc; + return ((WASAPI_ProxyToManagementThread(mgmtthrtask_ActivateDevice, device, &rc) < 0) || (rc < 0)) ? -1 : 0; +} + +static SDL_bool RecoverWasapiDevice(SDL_AudioDevice *device) +{ + ResetWasapiDevice(device); // dump the lost device's handles. + + // This handles a non-default device that simply had its format changed in the Windows Control Panel. + if (ActivateWasapiDevice(device) == -1) { + WASAPI_DisconnectDevice(device); return SDL_FALSE; } - _this->hidden->device_lost = SDL_FALSE; + device->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(SDL_AudioDevice *_this) +static SDL_bool RecoverWasapiIfLost(SDL_AudioDevice *device) { - 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. */ + if (SDL_AtomicGet(&device->shutdown)) { + return SDL_FALSE; // already failed. + } else if (!device->hidden->client) { + return SDL_TRUE; // still waiting for activation. } - if (!_this->hidden->client) { - return SDL_TRUE; /* still waiting for activation. */ - } - - if (!lost && (generation > 0)) { /* is a default device? */ - 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; - } - } - - return lost ? RecoverWasapiDevice(_this) : SDL_TRUE; + return device->hidden->device_lost ? RecoverWasapiDevice(device) : SDL_TRUE; } -static Uint8 *WASAPI_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *WASAPI_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) { - /* get an endpoint buffer from WASAPI. */ + // 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))) { + while (RecoverWasapiIfLost(device) && device->hidden->render) { + if (!WasapiFailed(device, IAudioRenderClient_GetBuffer(device->hidden->render, device->sample_frames, &buffer))) { return (Uint8 *)buffer; } SDL_assert(buffer == NULL); @@ -185,197 +413,108 @@ static Uint8 *WASAPI_GetDeviceBuf(SDL_AudioDevice *_this) return (Uint8 *)buffer; } -static void WASAPI_PlayDevice(SDL_AudioDevice *_this) +static void WASAPI_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) { - if (_this->hidden->render != NULL) { /* definitely activated? */ - /* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */ - WasapiFailed(_this, IAudioRenderClient_ReleaseBuffer(_this->hidden->render, _this->spec.samples, 0)); + if (device->hidden->render != NULL) { // definitely activated? + // WasapiFailed() will mark the device for reacquisition or removal elsewhere. + WasapiFailed(device, IAudioRenderClient_ReleaseBuffer(device->hidden->render, device->sample_frames, 0)); } } -static void WASAPI_WaitDevice(SDL_AudioDevice *_this) +static void WASAPI_WaitDevice(SDL_AudioDevice *device) { - while (RecoverWasapiIfLost(_this) && _this->hidden->client && _this->hidden->event) { - DWORD waitResult = WaitForSingleObjectEx(_this->hidden->event, 200, FALSE); + while (RecoverWasapiIfLost(device) && device->hidden->client && device->hidden->event) { + DWORD waitResult = WaitForSingleObjectEx(device->hidden->event, 200, FALSE); if (waitResult == WAIT_OBJECT_0) { - const UINT32 maxpadding = _this->spec.samples; + const UINT32 maxpadding = device->sample_frames; 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 (_this->iscapture) { - if (padding > 0) { - break; - } - } else { - if (padding <= maxpadding) { - break; - } + if (!WasapiFailed(device, IAudioClient_GetCurrentPadding(device->hidden->client, &padding))) { + //SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/ + if (device->iscapture && (padding > 0)) { + break; + } else if (!device->iscapture && (padding <= maxpadding)) { + break; } } } else if (waitResult != WAIT_TIMEOUT) { - /*SDL_Log("WASAPI FAILED EVENT!");*/ - IAudioClient_Stop(_this->hidden->client); - SDL_OpenedAudioDeviceDisconnected(_this); + //SDL_Log("WASAPI FAILED EVENT!");*/ + IAudioClient_Stop(device->hidden->client); + WASAPI_DisconnectDevice(device); } } } -static int WASAPI_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) -{ - SDL_AudioStream *stream = _this->hidden->capturestream; - const int avail = SDL_GetAudioStreamAvailable(stream); - if (avail > 0) { - const int cpy = SDL_min(buflen, avail); - SDL_GetAudioStreamData(stream, buffer, cpy); - return cpy; - } - - while (RecoverWasapiIfLost(_this)) { - HRESULT ret; - BYTE *ptr = NULL; - UINT32 frames = 0; - DWORD flags = 0; - - /* uhoh, client isn't activated yet, just return silence. */ - if (!_this->hidden->capture) { - /* Delay so we run at about the speed that audio would be arriving. */ - SDL_Delay(((_this->spec.samples * 1000) / _this->spec.freq)); - SDL_memset(buffer, _this->spec.silence, buflen); - return buflen; - } - - ret = IAudioCaptureClient_GetBuffer(_this->hidden->capture, &ptr, &frames, &flags, NULL, NULL); - if (ret != AUDCLNT_S_BUFFER_EMPTY) { - WasapiFailed(_this, ret); /* mark device lost/failed if necessary. */ - } - - 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 cpy = SDL_min(buflen, total); - const int leftover = total - cpy; - const SDL_bool silent = (flags & AUDCLNT_BUFFERFLAGS_SILENT) ? SDL_TRUE : SDL_FALSE; - - if (silent) { - SDL_memset(buffer, _this->spec.silence, cpy); - } 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? */ - } - - if (SDL_PutAudioStreamData(stream, ptr, leftover) == -1) { - return -1; /* uhoh, out of memory, etc. Kill device. :( */ - } - } - - ret = IAudioCaptureClient_ReleaseBuffer(_this->hidden->capture, frames); - WasapiFailed(_this, ret); /* mark device lost/failed if necessary. */ - - return cpy; - } - } - - return -1; /* unrecoverable error. */ -} - -static void WASAPI_FlushCapture(SDL_AudioDevice *_this) +static int WASAPI_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen) { BYTE *ptr = NULL; UINT32 frames = 0; DWORD flags = 0; - if (!_this->hidden->capture) { - 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); + while (RecoverWasapiIfLost(device) && device->hidden->capture) { + HRESULT ret = IAudioCaptureClient_GetBuffer(device->hidden->capture, &ptr, &frames, &flags, NULL, NULL); if (ret == AUDCLNT_S_BUFFER_EMPTY) { - break; /* no more buffered data; we're done. */ - } else if (WasapiFailed(_this, ret)) { - break; /* failed for some other reason, abort. */ - } else if (WasapiFailed(_this, IAudioCaptureClient_ReleaseBuffer(_this->hidden->capture, frames))) { - break; /* something broke. */ + return 0; // in theory we should have waited until there was data, but oh well, we'll go back to waiting. Returning 0 is safe in SDL + } + + WasapiFailed(device, ret); // mark device lost/failed if necessary. + + if (ret == S_OK) { + const int total = ((int)frames) * device->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; + + SDL_assert(leftover == 0); // according to MSDN, this isn't everything available, just one "packet" of data per-GetBuffer call. + + if (silent) { + SDL_memset(buffer, device->silence_value, cpy); + } else { + SDL_memcpy(buffer, ptr, cpy); + } + + ret = IAudioCaptureClient_ReleaseBuffer(device->hidden->capture, frames); + WasapiFailed(device, ret); // mark device lost/failed if necessary. + + return cpy; } } - SDL_ClearAudioStream(_this->hidden->capturestream); + + return -1; // unrecoverable error. } -static void ReleaseWasapiDevice(SDL_AudioDevice *_this) +static void WASAPI_FlushCapture(SDL_AudioDevice *device) { - if (_this->hidden->client) { - IAudioClient_Stop(_this->hidden->client); - IAudioClient_Release(_this->hidden->client); - _this->hidden->client = NULL; - } + BYTE *ptr = NULL; + UINT32 frames = 0; + DWORD flags = 0; - if (_this->hidden->render) { - IAudioRenderClient_Release(_this->hidden->render); - _this->hidden->render = NULL; - } - - if (_this->hidden->capture) { - IAudioCaptureClient_Release(_this->hidden->capture); - _this->hidden->capture = NULL; - } - - if (_this->hidden->waveformat) { - CoTaskMemFree(_this->hidden->waveformat); - _this->hidden->waveformat = NULL; - } - - if (_this->hidden->capturestream) { - SDL_DestroyAudioStream(_this->hidden->capturestream); - _this->hidden->capturestream = NULL; - } - - if (_this->hidden->activation_handler) { - WASAPI_PlatformDeleteActivationHandler(_this->hidden->activation_handler); - _this->hidden->activation_handler = NULL; - } - - if (_this->hidden->event) { - CloseHandle(_this->hidden->event); - _this->hidden->event = NULL; + // just read until we stop getting packets, throwing them away. + while (!SDL_AtomicGet(&device->shutdown) && device->hidden->capture) { + const HRESULT ret = IAudioCaptureClient_GetBuffer(device->hidden->capture, &ptr, &frames, &flags, NULL, NULL); + if (ret == AUDCLNT_S_BUFFER_EMPTY) { + break; // no more buffered data; we're done. + } else if (WasapiFailed(device, ret)) { + break; // failed for some other reason, abort. + } else if (WasapiFailed(device, IAudioCaptureClient_ReleaseBuffer(device->hidden->capture, frames))) { + break; // something broke. + } } } -static void WASAPI_CloseDevice(SDL_AudioDevice *_this) +static void WASAPI_CloseDevice(SDL_AudioDevice *device) { - WASAPI_UnrefDevice(_this); -} - -void WASAPI_RefDevice(SDL_AudioDevice *_this) -{ - SDL_AtomicIncRef(&_this->hidden->refcount); -} - -void WASAPI_UnrefDevice(SDL_AudioDevice *_this) -{ - if (!SDL_AtomicDecRef(&_this->hidden->refcount)) { - return; + if (device->hidden) { + ResetWasapiDevice(device); + SDL_free(device->hidden->devid); + SDL_free(device->hidden); + device->hidden = NULL; } - - /* actual closing happens here. */ - - /* don't touch _this->hidden->task in here; it has to be reverted from - our callback thread. We do that in WASAPI_ThreadDeinit(). - (likewise for _this->hidden->coinitialized). */ - ReleaseWasapiDevice(_this); - SDL_free(_this->hidden->devid); - SDL_free(_this->hidden); } -/* This is called once a device is activated, possibly asynchronously. */ -int WASAPI_PrepDevice(SDL_AudioDevice *_this, const SDL_bool updatestream) +static int mgmtthrtask_PrepDevice(void *userdata) { + SDL_AudioDevice *device = (SDL_AudioDevice *)userdata; + /* !!! FIXME: we could request an exclusive mode stream, which is lower latency; !!! it will write into the kernel's audio buffer directly instead of !!! shared memory that a user-mode mixer then writes to the kernel with @@ -387,49 +526,42 @@ int WASAPI_PrepDevice(SDL_AudioDevice *_this, const SDL_bool updatestream) !!! wins actually look like. Maybe add a hint to force exclusive mode at !!! some point. To be sure, defaulting to shared mode is the right thing to !!! 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 default_period = 0; - IAudioClient *client = _this->hidden->client; - IAudioRenderClient *render = NULL; - IAudioCaptureClient *capture = NULL; - WAVEFORMATEX *waveformat = NULL; - SDL_AudioFormat test_format; - SDL_AudioFormat wasapi_format = 0; - const SDL_AudioFormat *closefmts; - HRESULT ret = S_OK; - DWORD streamflags = 0; + IAudioClient *client = device->hidden->client; SDL_assert(client != NULL); -#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); +#if defined(__WINRT__) || defined(__GDK__) // CreateEventEx() arrived in Vista, so we need an #ifdef for XP. + device->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS); #else - _this->hidden->event = CreateEventW(NULL, 0, 0, NULL); + device->hidden->event = CreateEventW(NULL, 0, 0, NULL); #endif - if (_this->hidden->event == NULL) { + if (device->hidden->event == NULL) { return WIN_SetError("WASAPI can't create an event handle"); } + HRESULT ret; + + WAVEFORMATEX *waveformat = NULL; ret = IAudioClient_GetMixFormat(client, &waveformat); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't determine mix format", ret); } - SDL_assert(waveformat != NULL); - _this->hidden->waveformat = waveformat; + device->hidden->waveformat = waveformat; - _this->spec.channels = (Uint8)waveformat->nChannels; + SDL_AudioSpec newspec; + newspec.channels = (Uint8)waveformat->nChannels; - /* Make sure we have a valid format that we can convert to whatever WASAPI wants. */ - wasapi_format = WaveFormatToSDLFormat(waveformat); + // Make sure we have a valid format that we can convert to whatever WASAPI wants. + const SDL_AudioFormat wasapi_format = SDL_WaveFormatExToSDLFormat(waveformat); - closefmts = SDL_ClosestAudioFormats(_this->spec.format); + SDL_AudioFormat test_format; + const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); while ((test_format = *(closefmts++)) != 0) { if (test_format == wasapi_format) { - _this->spec.format = test_format; + newspec.format = test_format; break; } } @@ -438,36 +570,40 @@ int WASAPI_PrepDevice(SDL_AudioDevice *_this, const SDL_bool updatestream) return SDL_SetError("%s: Unsupported audio format", "wasapi"); } + REFERENCE_TIME default_period = 0; ret = IAudioClient_GetDevicePeriod(client, &default_period, NULL); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret); } + DWORD streamflags = 0; + /* 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 ((DWORD)_this->spec.freq != waveformat->nSamplesPerSec) { +#if 1 + // favor WASAPI's resampler over our own + if ((DWORD)device->spec.freq != waveformat->nSamplesPerSec) { streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY); - waveformat->nSamplesPerSec = _this->spec.freq; + waveformat->nSamplesPerSec = device->spec.freq; waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8); } #endif + newspec.freq = waveformat->nSamplesPerSec; + streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK; ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't initialize audio client", ret); } - ret = IAudioClient_SetEventHandle(client, _this->hidden->event); + ret = IAudioClient_SetEventHandle(client, device->hidden->event); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't set event handle", ret); } + UINT32 bufsize = 0; // this is in sample frames, not samples, not bytes. ret = IAudioClient_GetBufferSize(client, &bufsize); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't determine buffer size", ret); @@ -475,116 +611,108 @@ int WASAPI_PrepDevice(SDL_AudioDevice *_this, const SDL_bool updatestream) /* 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); + const float period_millis = default_period / 10000.0f; + const float period_frames = period_millis * newspec.freq / 1000.0f; + const int new_sample_frames = (int) SDL_ceilf(period_frames); + + // Update the fragment size as size in bytes + if (SDL_AudioDeviceFormatChangedAlreadyLocked(device, &newspec, new_sample_frames) < 0) { + return -1; } - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); - - _this->hidden->framesize = (SDL_AUDIO_BITSIZE(_this->spec.format) / 8) * _this->spec.channels; - - if (_this->iscapture) { - _this->hidden->capturestream = SDL_CreateAudioStream(_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 */ - } + device->hidden->framesize = (SDL_AUDIO_BITSIZE(device->spec.format) / 8) * device->spec.channels; + if (device->iscapture) { + IAudioCaptureClient *capture = NULL; ret = IAudioClient_GetService(client, &SDL_IID_IAudioCaptureClient, (void **)&capture); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't get capture client service", ret); } SDL_assert(capture != NULL); - _this->hidden->capture = capture; + device->hidden->capture = capture; ret = IAudioClient_Start(client); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't start capture", ret); } - WASAPI_FlushCapture(_this); /* MSDN says you should flush capture endpoint right after startup. */ + WASAPI_FlushCapture(device); // MSDN says you should flush capture endpoint right after startup. } else { + IAudioRenderClient *render = NULL; ret = IAudioClient_GetService(client, &SDL_IID_IAudioRenderClient, (void **)&render); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't get render client service", ret); } SDL_assert(render != NULL); - _this->hidden->render = render; + device->hidden->render = render; ret = IAudioClient_Start(client); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't start playback", ret); } } - if (updatestream) { - return UpdateAudioStream(_this, &oldspec); - } - - return 0; /* good to go. */ + return 0; // good to go. } -static int WASAPI_OpenDevice(SDL_AudioDevice *_this, const char *devname) +// This is called once a device is activated, possibly asynchronously. +int WASAPI_PrepDevice(SDL_AudioDevice *device) { - LPCWSTR devid = (LPCWSTR)_this->handle; + int rc = 0; + return (WASAPI_ProxyToManagementThread(mgmtthrtask_PrepDevice, device, &rc) < 0) ? -1 : rc; +} - /* Initialize all variables that we clean on shutdown */ - _this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*_this->hidden)); - if (_this->hidden == NULL) { +static int WASAPI_OpenDevice(SDL_AudioDevice *device) +{ + // Initialize all variables that we clean on shutdown + device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden)); + if (device->hidden == NULL) { return SDL_OutOfMemory(); - } - SDL_zerop(_this->hidden); - - WASAPI_RefDevice(_this); /* so CloseDevice() will unref to zero. */ - - if (!devid) { /* is default device? */ - _this->hidden->default_device_generation = SDL_AtomicGet(_this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration); - } else { - _this->hidden->devid = SDL_wcsdup(devid); - if (!_this->hidden->devid) { - return SDL_OutOfMemory(); - } + } else if (ActivateWasapiDevice(device) < 0) { + return -1; // already set error. } - if (WASAPI_ActivateDevice(_this, SDL_FALSE) == -1) { - return -1; /* already set error. */ - } - - /* Ready, but waiting for async device activation. + /* Ready, but possibly waiting for async device activation. Until activation is successful, we will report silence from capture - devices and ignore data on playback devices. - Also, since we don't know the _actual_ device format until after - activation, we let the app have whatever it asks for. We set up - an SDL_AudioStream to convert, if necessary, once the activation - completes. */ + devices and ignore data on playback devices. Upon activation, we'll make + sure any bound audio streams are adjusted for the final device format. */ return 0; } -static void WASAPI_ThreadInit(SDL_AudioDevice *_this) +static void WASAPI_ThreadInit(SDL_AudioDevice *device) { - WASAPI_PlatformThreadInit(_this); + WASAPI_PlatformThreadInit(device); } -static void WASAPI_ThreadDeinit(SDL_AudioDevice *_this) +static void WASAPI_ThreadDeinit(SDL_AudioDevice *device) { - WASAPI_PlatformThreadDeinit(_this); + WASAPI_PlatformThreadDeinit(device); +} + +static int mgmtthrtask_FreeDeviceHandle(void *userdata) +{ + WASAPI_PlatformFreeDeviceHandle((SDL_AudioDevice *)userdata); + return 0; +} + +static void WASAPI_FreeDeviceHandle(SDL_AudioDevice *device) +{ + int rc; + WASAPI_ProxyToManagementThread(mgmtthrtask_FreeDeviceHandle, device, &rc); } static void WASAPI_Deinitialize(void) { - WASAPI_PlatformDeinit(); + DeinitManagementThread(); } static SDL_bool WASAPI_Init(SDL_AudioDriverImpl *impl) { - if (WASAPI_PlatformInit() == -1) { + if (InitManagementThread() < 0) { return SDL_FALSE; } - /* Set the function pointers */ impl->DetectDevices = WASAPI_DetectDevices; impl->ThreadInit = WASAPI_ThreadInit; impl->ThreadDeinit = WASAPI_ThreadDeinit; @@ -592,19 +720,20 @@ static SDL_bool WASAPI_Init(SDL_AudioDriverImpl *impl) impl->PlayDevice = WASAPI_PlayDevice; impl->WaitDevice = WASAPI_WaitDevice; impl->GetDeviceBuf = WASAPI_GetDeviceBuf; + impl->WaitCaptureDevice = WASAPI_WaitDevice; impl->CaptureFromDevice = WASAPI_CaptureFromDevice; impl->FlushCapture = WASAPI_FlushCapture; impl->CloseDevice = WASAPI_CloseDevice; impl->Deinitialize = WASAPI_Deinitialize; - impl->GetDefaultAudioInfo = WASAPI_GetDefaultAudioInfo; - impl->HasCaptureSupport = SDL_TRUE; - impl->SupportsNonPow2Samples = SDL_TRUE; + impl->FreeDeviceHandle = WASAPI_FreeDeviceHandle; - return SDL_TRUE; /* this audio target is available. */ + impl->HasCaptureSupport = SDL_TRUE; + + return SDL_TRUE; } AudioBootStrap WASAPI_bootstrap = { "wasapi", "WASAPI", WASAPI_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_WASAPI */ +#endif // SDL_AUDIO_DRIVER_WASAPI diff --git a/src/audio/wasapi/SDL_wasapi.h b/src/audio/wasapi/SDL_wasapi.h index 5fdd0bbd..7ea47ccb 100644 --- a/src/audio/wasapi/SDL_wasapi.h +++ b/src/audio/wasapi/SDL_wasapi.h @@ -31,37 +31,38 @@ extern "C" { struct SDL_PrivateAudioData { - SDL_AtomicInt refcount; WCHAR *devid; WAVEFORMATEX *waveformat; IAudioClient *client; IAudioRenderClient *render; IAudioCaptureClient *capture; - SDL_AudioStream *capturestream; HANDLE event; HANDLE task; SDL_bool coinitialized; int framesize; - int default_device_generation; SDL_bool device_lost; void *activation_handler; - SDL_AtomicInt just_activated; }; /* win32 and winrt implementations call into these. */ -int WASAPI_PrepDevice(SDL_AudioDevice *_this, const SDL_bool updatestream); -void WASAPI_RefDevice(SDL_AudioDevice *_this); -void WASAPI_UnrefDevice(SDL_AudioDevice *_this); +int WASAPI_PrepDevice(SDL_AudioDevice *device); +void WASAPI_DisconnectDevice(SDL_AudioDevice *device); + + +// BE CAREFUL: if you are holding the device lock and proxy to the management thread with wait_until_complete, and grab the lock again, you will deadlock. +typedef int (*ManagementThreadTask)(void *userdata); +int WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, int *wait_until_complete); /* These are functions that are implemented differently for Windows vs WinRT. */ +// UNLESS OTHERWISE NOTED THESE ALL HAPPEN ON THE MANAGEMENT THREAD. 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(SDL_AudioDevice *_this, const SDL_bool isrecovery); -void WASAPI_PlatformThreadInit(SDL_AudioDevice *_this); -void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *_this); +void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture); +int WASAPI_ActivateDevice(SDL_AudioDevice *device); +void WASAPI_PlatformThreadInit(SDL_AudioDevice *device); // this happens on the audio device thread, not the management thread. +void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device); // this happens on the audio device thread, not the management thread. void WASAPI_PlatformDeleteActivationHandler(void *handler); +void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device); #ifdef __cplusplus } diff --git a/src/audio/wasapi/SDL_wasapi_win32.c b/src/audio/wasapi/SDL_wasapi_win32.c index f991092c..719ac94a 100644 --- a/src/audio/wasapi/SDL_wasapi_win32.c +++ b/src/audio/wasapi/SDL_wasapi_win32.c @@ -49,7 +49,7 @@ static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x int WASAPI_PlatformInit(void) { - if (SDL_IMMDevice_Init() < 0) { + if (SDL_IMMDevice_Init() < 0) { // this will call WIN_CoInitialize for us! return -1; /* This is set by SDL_IMMDevice_Init */ } @@ -72,72 +72,68 @@ void WASAPI_PlatformDeinit(void) pAvSetMmThreadCharacteristicsW = NULL; pAvRevertMmThreadCharacteristics = NULL; - SDL_IMMDevice_Quit(); + SDL_IMMDevice_Quit(); // This will call WIN_CoUninitialize for us! } -void WASAPI_PlatformThreadInit(SDL_AudioDevice *_this) +void WASAPI_PlatformThreadInit(SDL_AudioDevice *device) { /* this thread uses COM. */ if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */ - _this->hidden->coinitialized = SDL_TRUE; + device->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); + device->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx); + } else { + SDL_SetThreadPriority(device->iscapture ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL); } + } -void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *_this) +void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device) { /* Set this thread back to normal priority. */ - if (_this->hidden->task && pAvRevertMmThreadCharacteristics) { - pAvRevertMmThreadCharacteristics(_this->hidden->task); - _this->hidden->task = NULL; + if (device->hidden->task && pAvRevertMmThreadCharacteristics) { + pAvRevertMmThreadCharacteristics(device->hidden->task); + device->hidden->task = NULL; } - if (_this->hidden->coinitialized) { + if (device->hidden->coinitialized) { WIN_CoUninitialize(); - _this->hidden->coinitialized = SDL_FALSE; + device->hidden->coinitialized = SDL_FALSE; } } -int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery) +int WASAPI_ActivateDevice(SDL_AudioDevice *device) { - IMMDevice *device = NULL; - HRESULT ret; - - if (SDL_IMMDevice_Get(_this->hidden->devid, &device, _this->iscapture) < 0) { - _this->hidden->client = NULL; + IMMDevice *immdevice = NULL; + if (SDL_IMMDevice_Get(device, &immdevice, device->iscapture) < 0) { + device->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); + /* this is _not_ async in standard win32, yay! */ + HRESULT ret = IMMDevice_Activate(immdevice, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&device->hidden->client); + IMMDevice_Release(immdevice); if (FAILED(ret)) { - SDL_assert(_this->hidden->client == NULL); + SDL_assert(device->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. */ + SDL_assert(device->hidden->client != NULL); + if (WASAPI_PrepDevice(device) == -1) { /* not async, fire it right away. */ return -1; } return 0; /* good to go. */ } -void WASAPI_EnumerateEndpoints(void) +void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - SDL_IMMDevice_EnumerateEndpoints(SDL_FALSE); -} - -int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) -{ - return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture); + SDL_IMMDevice_EnumerateEndpoints(default_output, default_capture); } void WASAPI_PlatformDeleteActivationHandler(void *handler) @@ -146,4 +142,9 @@ void WASAPI_PlatformDeleteActivationHandler(void *handler) SDL_assert(!"This function should have only been called on WinRT."); } +void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device) +{ + SDL_IMMDevice_FreeDeviceHandle(device); +} + #endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */ diff --git a/src/audio/wasapi/SDL_wasapi_winrt.cpp b/src/audio/wasapi/SDL_wasapi_winrt.cpp index 795c29b7..a4030f39 100644 --- a/src/audio/wasapi/SDL_wasapi_winrt.cpp +++ b/src/audio/wasapi/SDL_wasapi_winrt.cpp @@ -53,21 +53,16 @@ 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_AtomicInt SDL_IMMDevice_DefaultPlaybackGeneration; -SDL_AtomicInt SDL_IMMDevice_DefaultCaptureGeneration; + +static SDL_bool FindWinRTAudioDeviceCallback(SDL_AudioDevice *device, void *userdata) +{ + return (SDL_wcscmp((LPCWSTR) device->handle, (LPCWSTR) userdata) == 0) ? SDL_TRUE : SDL_FALSE; } -/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ -typedef struct DevIdList +static SDL_AudioDevice *FindWinRTAudioDevice(LPCWSTR devid) { - WCHAR *str; - struct DevIdList *next; -} DevIdList; - -static DevIdList *deviceid_list = NULL; + return SDL_FindPhysicalAudioDeviceByCallback(FindWinRTAudioDeviceCallback, (void *) devid); +} class SDL_WasapiDeviceEventHandler { @@ -80,9 +75,10 @@ class SDL_WasapiDeviceEventHandler void OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args); void OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args); void OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args); - SDL_Semaphore *completed; + void WaitForCompletion(); private: + SDL_Semaphore *completed_semaphore; const SDL_bool iscapture; DeviceWatcher ^ watcher; Windows::Foundation::EventRegistrationToken added_handler; @@ -93,10 +89,11 @@ class SDL_WasapiDeviceEventHandler }; SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture) - : iscapture(_iscapture), completed(SDL_CreateSemaphore(0)) + : iscapture(_iscapture), completed_semaphore(SDL_CreateSemaphore(0)) { - if (!completed) + if (!completed_semaphore) { return; // uhoh. + } Platform::String ^ selector = _iscapture ? MediaDevice::GetAudioCaptureSelector() : MediaDevice::GetAudioRenderSelector(); Platform::Collections::Vector properties; @@ -128,9 +125,10 @@ SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler() watcher->Stop(); watcher = nullptr; } - if (completed) { - SDL_DestroySemaphore(completed); - completed = nullptr; + + if (completed_semaphore) { + SDL_DestroySemaphore(completed_semaphore); + completed_semaphore = nullptr; } if (iscapture) { @@ -142,21 +140,34 @@ SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler() void SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ info) { + /* 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...?) */ + SDL_assert(sender == this->watcher); char *utf8dev = WIN_StringToUTF8(info->Name->Data()); if (utf8dev) { - WAVEFORMATEXTENSIBLE fmt; + SDL_AudioSpec spec; + SDL_zero(spec); + 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 { + WAVEFORMATEXTENSIBLE fmt; SDL_zero(fmt); + SDL_memcpy(&fmt, data->Data, SDL_min(data->Length, sizeof(WAVEFORMATEXTENSIBLE))); + spec.channels = (Uint8)fmt.Format.nChannels; + spec.freq = fmt.Format.nSamplesPerSec; + spec.format = SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)&fmt); } - WASAPI_AddDevice(this->iscapture, utf8dev, &fmt, info->Id->Data()); + LPWSTR devid = SDL_wcsdup(info->Id->Data()); + if (devid) { + SDL_AddAudioDevice(this->iscapture, utf8dev, spec.channels ? &spec : NULL, devid); + } SDL_free(utf8dev); } } @@ -164,7 +175,7 @@ void SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher ^ sender, DeviceI void SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ info) { SDL_assert(sender == this->watcher); - WASAPI_RemoveDevice(this->iscapture, info->Id->Data()); + WASAPI_DisconnectDevice(FindWinRTAudioDevice(info->Id->Data())); } void SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) @@ -175,19 +186,30 @@ void SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher ^ sender, Devic void SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args) { SDL_assert(sender == this->watcher); - SDL_PostSemaphore(this->completed); + if (this->completed_semaphore) { + SDL_PostSemaphore(this->completed_semaphore); + } } void SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args) { SDL_assert(!this->iscapture); - SDL_AtomicAdd(&SDL_IMMDevice_DefaultPlaybackGeneration, 1); + SDL_DefaultAudioDeviceChanged(FindWinRTAudioDevice(args->Id->Data())); } void SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args) { SDL_assert(this->iscapture); - SDL_AtomicAdd(&SDL_IMMDevice_DefaultCaptureGeneration, 1); + SDL_DefaultAudioDeviceChanged(FindWinRTAudioDevice(args->Id->Data())); +} + +void SDL_WasapiDeviceEventHandler::WaitForCompletion() +{ + if (this->completed_semaphore) { + SDL_WaitSemaphore(this->completed_semaphore); + SDL_DestroySemaphore(this->completed_semaphore); + this->completed_semaphore = nullptr; + } } static SDL_WasapiDeviceEventHandler *playback_device_event_handler; @@ -195,54 +217,63 @@ 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) +void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { + Platform::String ^ defdevid; + // 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); + playback_device_event_handler->WaitForCompletion(); + defdevid = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default); + if (defdevid) { + *default_output = FindWinRTAudioDevice(defdevid->Data()); + } + capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE); - SDL_WaitSemaphore(playback_device_event_handler->completed); - SDL_WaitSemaphore(capture_device_event_handler->completed); + capture_device_event_handler->WaitForCompletion(); + defdevid = MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default); + if (defdevid) { + *default_capture = FindWinRTAudioDevice(defdevid->Data()); + } } -struct SDL_WasapiActivationHandler : public RuntimeClass, FtmBase, IActivateAudioInterfaceCompletionHandler> +class SDL_WasapiActivationHandler : public RuntimeClass, FtmBase, IActivateAudioInterfaceCompletionHandler> { - SDL_WasapiActivationHandler() : device(nullptr) {} - STDMETHOD(ActivateCompleted) - (IActivateAudioInterfaceAsyncOperation *operation); - SDL_AudioDevice *device; +public: + SDL_WasapiActivationHandler() : completion_semaphore(SDL_CreateSemaphore(0)) { SDL_assert(completion_semaphore != NULL); } + STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation); + void WaitForCompletion(); +private: + SDL_Semaphore *completion_semaphore; }; +void SDL_WasapiActivationHandler::WaitForCompletion() +{ + if (completion_semaphore) { + SDL_WaitSemaphore(completion_semaphore); + SDL_DestroySemaphore(completion_semaphore); + completion_semaphore = NULL; + } +} + 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); + SDL_PostSemaphore(completion_semaphore); return S_OK; } @@ -251,24 +282,10 @@ void WASAPI_PlatformDeleteActivationHandler(void *handler) ((SDL_WasapiActivationHandler *)handler)->Release(); } -int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +int WASAPI_ActivateDevice(SDL_AudioDevice *device) { - return SDL_Unsupported(); -} - -int WASAPI_ActivateDevice(SDL_AudioDevice *_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); + LPCWSTR devid = (LPCWSTR) device->handle; + SDL_assert(devid != NULL); ComPtr handler = Make(); if (handler == nullptr) { @@ -276,10 +293,8 @@ int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery) } 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(); + device->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); @@ -288,21 +303,11 @@ int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery) 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); - } + // !!! FIXME: the problems in SDL2 that needed this to be synchronous are _probably_ solved by SDL3, and this can block indefinitely if a user prompt is shown to get permission to use a microphone. + handler.Get()->WaitForCompletion(); // block here until we have an answer, so this is synchronous to us after all. HRESULT activateRes = S_OK; IUnknown *iunknown = nullptr; @@ -314,114 +319,32 @@ int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery) return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes); } - iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client)); - if (!_this->hidden->client) { + iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client)); + if (!device->hidden->client) { return SDL_SetError("Failed to query WASAPI client interface"); } - if (WASAPI_PrepDevice(_this, isrecovery) == -1) { + if (WASAPI_PrepDevice(device) == -1) { return -1; } return 0; } -void WASAPI_PlatformThreadInit(SDL_AudioDevice *_this) +void WASAPI_PlatformThreadInit(SDL_AudioDevice *device) +{ + // !!! FIXME: set this thread to "Pro Audio" priority. + SDL_SetThreadPriority(device->iscapture ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL); +} + +void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device) { // !!! FIXME: set this thread to "Pro Audio" priority. } -void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *_this) +void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device) { - // !!! 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 SDL_AUDIO_F32SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { - return SDL_AUDIO_S16SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { - return SDL_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 SDL_AUDIO_F32SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { - return SDL_AUDIO_S16SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { - return SDL_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 == NULL) { - 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); + SDL_free(device->handle); } #endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 1d3909b6..41a0ad00 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -233,7 +233,7 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)( JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL - SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture, + SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture, jstring name, jint device_id); JNIEXPORT void JNICALL @@ -242,7 +242,7 @@ JNIEXPORT void JNICALL static JNINativeMethod SDLAudioManager_tab[] = { { "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) }, - { "addAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(addAudioDevice) }, + { "addAudioDevice", "(ZLjava/lang/String;I)V", SDL_JAVA_AUDIO_INTERFACE(addAudioDevice) }, { "removeAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice) } }; @@ -350,8 +350,8 @@ static jmethodID midSupportsRelativeMouse; static jclass mAudioManagerClass; /* method signatures */ -static jmethodID midGetAudioOutputDevices; -static jmethodID midGetAudioInputDevices; +static jmethodID midRegisterAudioDeviceCallback; +static jmethodID midUnregisterAudioDeviceCallback; static jmethodID midAudioOpen; static jmethodID midAudioWriteByteBuffer; static jmethodID midAudioWriteShortBuffer; @@ -681,12 +681,12 @@ 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"); + midRegisterAudioDeviceCallback = (*env)->GetStaticMethodID(env, mAudioManagerClass, + "registerAudioDeviceCallback", + "()V"); + midUnregisterAudioDeviceCallback = (*env)->GetStaticMethodID(env, mAudioManagerClass, + "unregisterAudioDeviceCallback", + "()V"); midAudioOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass, "audioOpen", "(IIIII)[I"); midAudioWriteByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, @@ -710,7 +710,7 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jcl midAudioSetThreadPriority = (*env)->GetStaticMethodID(env, mAudioManagerClass, "audioSetThreadPriority", "(ZI)V"); - if (!midGetAudioOutputDevices || !midGetAudioInputDevices || !midAudioOpen || + if (!midRegisterAudioDeviceCallback || !midUnregisterAudioDeviceCallback || !midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose || !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || @@ -1002,18 +1002,17 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)( 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) + jstring name, 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)); + void *handle = (void *)((size_t)device_id); + if (!SDL_FindPhysicalAudioDeviceByHandle(handle)) { + const char *utf8name = (*env)->GetStringUTFChars(env, name, NULL); + SDL_AddAudioDevice(is_capture ? SDL_TRUE : SDL_FALSE, SDL_strdup(utf8name), NULL, handle); + (*env)->ReleaseStringUTFChars(env, name, utf8name); + } } } @@ -1022,8 +1021,8 @@ SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice)(JNIEnv *env, jclass jcls, jboolean i 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)); + SDL_Log("Removing device with handle %d, capture %d", device_id, is_capture); + SDL_AudioDeviceDisconnected(SDL_FindPhysicalAudioDeviceByHandle((void *)((size_t)device_id))); } } @@ -1152,7 +1151,6 @@ retry: SDL_LockMutex(Android_ActivityMutex); if (Android_Window) { - SDL_VideoDevice *_this = SDL_GetVideoDevice(); SDL_WindowData *data = Android_Window->driverdata; /* Wait for Main thread being paused and context un-activated to release 'egl_surface' */ @@ -1169,7 +1167,7 @@ retry: #ifdef SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { - SDL_EGL_DestroySurface(_this, data->egl_surface); + SDL_EGL_DestroySurface(SDL_GetVideoDevice(), data->egl_surface); data->egl_surface = EGL_NO_SURFACE; } #endif @@ -1564,58 +1562,25 @@ static void *audioBufferPinned = NULL; static int captureBufferFormat = 0; static jobject captureBuffer = NULL; -static void Android_JNI_GetAudioDevices(int *devices, int *length, int max_len, int is_input) +void Android_StartAudioHotplug(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { 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); + // this will fire the callback for each existing device right away (which will eventually SDL_AddAudioDevice), and again later when things change. + (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midRegisterAudioDeviceCallback); + *default_output = *default_capture = NULL; // !!! FIXME: how do you decide the default device id? } -void Android_DetectDevices(void) +void Android_StopAudioHotplug(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)); - } + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midUnregisterAudioDeviceCallback); } -int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spec) +int Android_JNI_OpenAudioDevice(SDL_AudioDevice *device) { + const SDL_bool iscapture = device->iscapture; + SDL_AudioSpec *spec = &device->spec; + const int device_id = (int) ((size_t) device->handle); int audioformat; jobject jbufobj = NULL; jobject result; @@ -1640,10 +1605,10 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe 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, device_id); + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, device->sample_frames, 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, device_id); + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, device->sample_frames, device_id); } if (result == NULL) { /* Error during audio initialization, error printed from Java */ @@ -1668,10 +1633,10 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe spec->format = SDL_AUDIO_F32; break; default: - return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); + return SDL_SetError("Unexpected audio format from Java: %d", audioformat); } spec->channels = resultElements[2]; - spec->samples = resultElements[3]; + device->sample_frames = resultElements[3]; (*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT); (*env)->DeleteLocalRef(env, result); @@ -1680,7 +1645,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe switch (audioformat) { case ENCODING_PCM_8BIT: { - jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels); + jbyteArray audioBufferLocal = (*env)->NewByteArray(env, device->sample_frames * spec->channels); if (audioBufferLocal) { jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); (*env)->DeleteLocalRef(env, audioBufferLocal); @@ -1688,7 +1653,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe } break; case ENCODING_PCM_16BIT: { - jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels); + jshortArray audioBufferLocal = (*env)->NewShortArray(env, device->sample_frames * spec->channels); if (audioBufferLocal) { jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); (*env)->DeleteLocalRef(env, audioBufferLocal); @@ -1696,7 +1661,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe } break; case ENCODING_PCM_FLOAT: { - jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels); + jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, device->sample_frames * spec->channels); if (audioBufferLocal) { jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); (*env)->DeleteLocalRef(env, audioBufferLocal); @@ -1887,12 +1852,17 @@ void Android_JNI_CloseAudioDevice(const int iscapture) } } -void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id) +static void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id) { JNIEnv *env = Android_JNI_GetEnv(); (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioSetThreadPriority, iscapture, device_id); } +void Android_AudioThreadInit(SDL_AudioDevice *device) +{ + Android_JNI_AudioSetThreadPriority((int) device->iscapture, (int)device->instance_id); +} + /* Test for an exception and call SDL_SetError with its detail if one occurs */ /* If the parameter silent is truthy then SDL_SetError() will not be called. */ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) @@ -2013,13 +1983,18 @@ int Android_JNI_FileOpen(SDL_RWops *ctx, return 0; } -Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size) +size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size) { AAsset *asset = (AAsset *)ctx->hidden.androidio.asset; - return (Sint64) AAsset_read(asset, buffer, (size_t) size); + int bytes = AAsset_read(asset, buffer, size); + if (bytes < 0) { + SDL_SetError("AAsset_read() failed"); + return 0; + } + return (size_t)bytes; } -Sint64 Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, Sint64 size) +size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size) { return SDL_SetError("Cannot write to Android package filesystem"); } diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index a245af98..bc090b88 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -30,6 +30,8 @@ extern "C" { #include #include +#include "../../audio/SDL_sysaudio.h" + /* Interface from the SDL library into the Android Java activity */ extern void Android_JNI_SetActivityTitle(const char *title); extern void Android_JNI_SetWindowStyle(SDL_bool fullscreen); @@ -47,14 +49,15 @@ extern SDL_DisplayOrientation Android_JNI_GetDisplayNaturalOrientation(void); extern SDL_DisplayOrientation Android_JNI_GetDisplayCurrentOrientation(void); /* Audio support */ -extern void Android_DetectDevices(void); -extern int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spec); +void Android_StartAudioHotplug(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture); +void Android_StopAudioHotplug(void); +extern void Android_AudioThreadInit(SDL_AudioDevice *device); +extern int Android_JNI_OpenAudioDevice(SDL_AudioDevice *device); 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); extern void Android_JNI_CloseAudioDevice(const int iscapture); -extern void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id); /* Detecting device type */ extern SDL_bool Android_IsDeXMode(void); @@ -63,8 +66,8 @@ extern SDL_bool Android_IsChromebook(void); int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode); Sint64 Android_JNI_FileSize(SDL_RWops *ctx); Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence); -Sint64 Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, Sint64 size); -Sint64 Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, Sint64 size); +size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size); +size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size); int Android_JNI_FileClose(SDL_RWops *ctx); /* Environment support */ diff --git a/src/core/windows/SDL_immdevice.c b/src/core/windows/SDL_immdevice.c index 8f91268f..160297e3 100644 --- a/src/core/windows/SDL_immdevice.c +++ b/src/core/windows/SDL_immdevice.c @@ -27,6 +27,12 @@ #include "../../audio/SDL_sysaudio.h" #include /* For CLSIDFromString */ +typedef struct SDL_IMMDevice_HandleData +{ + LPWSTR immdevice_id; + GUID directsound_guid; +} SDL_IMMDevice_HandleData; + 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. */ @@ -47,13 +53,28 @@ static const IID SDL_IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089,{ 0x85, 0x86 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_AtomicInt SDL_IMMDevice_DefaultPlaybackGeneration; -SDL_AtomicInt SDL_IMMDevice_DefaultCaptureGeneration; +static SDL_bool FindByDevIDCallback(SDL_AudioDevice *device, void *userdata) +{ + const SDL_IMMDevice_HandleData *handle = (const SDL_IMMDevice_HandleData *) device->handle; + return (SDL_wcscmp(handle->immdevice_id, (LPCWSTR) userdata) == 0) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_AudioDevice *SDL_IMMDevice_FindByDevID(LPCWSTR devid) +{ + return SDL_FindPhysicalAudioDeviceByCallback(FindByDevIDCallback, (void *) devid); +} + +LPGUID SDL_IMMDevice_GetDirectSoundGUID(SDL_AudioDevice *device) +{ + return (device && device->handle) ? &(((SDL_IMMDevice_HandleData *) device->handle)->directsound_guid) : NULL; +} + +LPCWSTR SDL_IMMDevice_GetDevID(SDL_AudioDevice *device) +{ + return (device && device->handle) ? ((const SDL_IMMDevice_HandleData *) device->handle)->immdevice_id : NULL; +} static void GetMMDeviceInfo(IMMDevice *device, char **utf8dev, WAVEFORMATEXTENSIBLE *fmt, GUID *guid) { @@ -82,94 +103,54 @@ static void GetMMDeviceInfo(IMMDevice *device, char **utf8dev, WAVEFORMATEXTENSI } } -/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ -typedef struct DevIdList +void SDL_IMMDevice_FreeDeviceHandle(SDL_AudioDevice *device) { - 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; - } + if (device && device->handle) { + SDL_IMMDevice_HandleData *handle = (SDL_IMMDevice_HandleData *) device->handle; + SDL_free(handle->immdevice_id); + SDL_free(handle); + device->handle = NULL; } } -static void SDL_IMMDevice_Add(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid, SDL_bool useguid) +static SDL_AudioDevice *SDL_IMMDevice_Add(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid) { - 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. */ + if (!devname) { + return NULL; + } + + // see if we already have this one first. + SDL_AudioDevice *device = SDL_IMMDevice_FindByDevID(devid); + if (!device) { + // handle is freed by SDL_IMMDevice_FreeDeviceHandle! + SDL_IMMDevice_HandleData *handle = SDL_malloc(sizeof(SDL_IMMDevice_HandleData)); + if (!handle) { + SDL_OutOfMemory(); + return NULL; } - } - - devidlist = (DevIdList *)SDL_malloc(sizeof(*devidlist)); - if (devidlist == NULL) { - 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. */ + handle->immdevice_id = SDL_wcsdup(devid); + if (!handle->immdevice_id) { + SDL_OutOfMemory(); + SDL_free(handle); + return NULL; } - SDL_memcpy(cpyguid, dsoundguid, sizeof(GUID)); - driverdata = cpyguid; - } else { - cpyguid = NULL; - driverdata = devidcopy; + SDL_memcpy(&handle->directsound_guid, dsoundguid, sizeof(GUID)); + + SDL_AudioSpec spec; + SDL_zero(spec); + spec.channels = (Uint8)fmt->Format.nChannels; + spec.freq = fmt->Format.nSamplesPerSec; + spec.format = SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)fmt); + + device = SDL_AddAudioDevice(iscapture, devname, &spec, handle); } - 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); + return device; } /* We need a COM subclass of IMMNotificationClient for hotplug support, which is @@ -181,14 +162,13 @@ typedef struct SDLMMNotificationClient { const IMMNotificationClientVtbl *lpVtbl; SDL_AtomicInt refcount; - SDL_bool useguid; } SDLMMNotificationClient; -static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface(IMMNotificationClient *this, REFIID iid, void **ppv) +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface(IMMNotificationClient *client, REFIID iid, void **ppv) { if ((WIN_IsEqualIID(iid, &IID_IUnknown)) || (WIN_IsEqualIID(iid, &SDL_IID_IMMNotificationClient))) { - *ppv = this; - this->lpVtbl->AddRef(this); + *ppv = client; + client->lpVtbl->AddRef(client); return S_OK; } @@ -196,55 +176,34 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface(IMMNotif return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE SDLMMNotificationClient_AddRef(IMMNotificationClient *ithis) +static ULONG STDMETHODCALLTYPE SDLMMNotificationClient_AddRef(IMMNotificationClient *iclient) { - SDLMMNotificationClient *this = (SDLMMNotificationClient *)ithis; - return (ULONG)(SDL_AtomicIncRef(&this->refcount) + 1); + SDLMMNotificationClient *client = (SDLMMNotificationClient *)iclient; + return (ULONG)(SDL_AtomicIncRef(&client->refcount) + 1); } -static ULONG STDMETHODCALLTYPE SDLMMNotificationClient_Release(IMMNotificationClient *ithis) +static ULONG STDMETHODCALLTYPE SDLMMNotificationClient_Release(IMMNotificationClient *iclient) { - /* this is a static object; we don't ever free it. */ - SDLMMNotificationClient *this = (SDLMMNotificationClient *)ithis; - const ULONG retval = SDL_AtomicDecRef(&this->refcount); + /* client is a static object; we don't ever free it. */ + SDLMMNotificationClient *client = (SDLMMNotificationClient *)iclient; + const ULONG retval = SDL_AtomicDecRef(&client->refcount); if (retval == 0) { - SDL_AtomicSet(&this->refcount, 0); /* uhh... */ + SDL_AtomicSet(&client->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) +// These are the entry points called when WASAPI device endpoints change. +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDefaultDeviceChanged(IMMNotificationClient *iclient, EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) { - if (role != SDL_IMMDevice_role) { - return S_OK; /* ignore it. */ + if (role == SDL_IMMDevice_role) { + SDL_DefaultAudioDeviceChanged(SDL_IMMDevice_FindByDevID(pwstrDeviceId)); } - - /* 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) +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceAdded(IMMNotificationClient *iclient, 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 @@ -254,13 +213,12 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceAdded(IMMNotifi return S_OK; } -static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceRemoved(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId) +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceRemoved(IMMNotificationClient *iclient, LPCWSTR pwstrDeviceId) { - /* See notes in OnDeviceAdded handler about why we ignore this. */ - return S_OK; + return S_OK; // See notes in OnDeviceAdded handler about why we ignore this. } -static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId, DWORD dwNewState) +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *iclient, LPCWSTR pwstrDeviceId, DWORD dwNewState) { IMMDevice *device = NULL; @@ -270,18 +228,17 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IM 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_IMMDevice_Add(iscapture, utf8dev, &fmt, pwstrDeviceId, &dsoundguid); SDL_free(utf8dev); } } else { - SDL_IMMDevice_Remove(iscapture, pwstrDeviceId, client->useguid); + SDL_AudioDeviceDisconnected(SDL_IMMDevice_FindByDevID(pwstrDeviceId)); } } IMMEndpoint_Release(endpoint); @@ -292,9 +249,9 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IM return S_OK; } -static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnPropertyValueChanged(IMMNotificationClient *this, LPCWSTR pwstrDeviceId, const PROPERTYKEY key) +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnPropertyValueChanged(IMMNotificationClient *client, LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { - return S_OK; /* we don't care about these. */ + return S_OK; // we don't care about these. } static const IMMNotificationClientVtbl notification_client_vtbl = { @@ -314,31 +271,25 @@ 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"); + return SDL_SetError("IMMDevice support requires Windows Vista or later"); } if (FAILED(WIN_CoInitialize())) { - return SDL_SetError("WASAPI: CoInitialize() failed"); + return SDL_SetError("IMMDevice: 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 WIN_SetErrorFromHRESULT("IMMDevice 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); @@ -346,197 +297,99 @@ void SDL_IMMDevice_Quit(void) } 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) +int SDL_IMMDevice_Get(SDL_AudioDevice *device, IMMDevice **immdevice, SDL_bool iscapture) { const Uint64 timeout = SDL_GetTicks() + 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); + SDL_assert(immdevice != NULL); - while (SDL_TRUE) { - if (devid == NULL) { - const EDataFlow dataflow = iscapture ? eCapture : eRender; - ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_IMMDevice_role, device); - } else { - ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, device); + LPCWSTR devid = SDL_IMMDevice_GetDevID(device); + SDL_assert(devid != NULL); + + HRESULT ret; + while ((ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, immdevice)) == E_NOTFOUND) { + const Uint64 now = SDL_GetTicks(); + if (timeout > now) { + const Uint64 ticksleft = timeout - now; + SDL_Delay((Uint32)SDL_min(ticksleft, 300)); /* wait awhile and try again. */ + continue; } - - if (SUCCEEDED(ret)) { - break; - } - - if (ret == E_NOTFOUND) { - const Uint64 now = SDL_GetTicks(); - 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); + break; } - return 0; + + return SUCCEEDED(ret) ? 0 : WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret); + } -typedef struct +static void EnumerateEndpointsForFlow(const SDL_bool iscapture, SDL_AudioDevice **default_device) { - 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"). */ + IMMDeviceCollection *collection = NULL; if (FAILED(IMMDeviceEnumerator_EnumAudioEndpoints(enumerator, iscapture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &collection))) { return; } + UINT total = 0; if (FAILED(IMMDeviceCollection_GetCount(collection, &total))) { IMMDeviceCollection_Release(collection); return; } - items = (EndpointItem *)SDL_calloc(total, sizeof(EndpointItem)); - if (items == NULL) { - 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); + LPWSTR default_devid = NULL; + if (default_device) { + IMMDevice *default_immdevice = NULL; + const EDataFlow dataflow = iscapture ? eCapture : eRender; + if (SUCCEEDED(IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_IMMDevice_role, &default_immdevice))) { + LPWSTR devid = NULL; + if (SUCCEEDED(IMMDevice_GetId(default_immdevice, &devid))) { + default_devid = SDL_wcsdup(devid); // if this fails, oh well. + CoTaskMemFree(devid); } - IMMDevice_Release(device); + IMMDevice_Release(default_immdevice); } } - /* 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); + for (UINT i = 0; i < total; i++) { + IMMDevice *immdevice = NULL; + if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &immdevice))) { + LPWSTR devid = NULL; + if (SUCCEEDED(IMMDevice_GetId(immdevice, &devid))) { + char *devname = NULL; + WAVEFORMATEXTENSIBLE fmt; + GUID dsoundguid; + SDL_zero(fmt); + SDL_zero(dsoundguid); + GetMMDeviceInfo(immdevice, &devname, &fmt, &dsoundguid); + if (devname) { + SDL_AudioDevice *sdldevice = SDL_IMMDevice_Add(iscapture, devname, &fmt, devid, &dsoundguid); + if (default_device && default_devid && SDL_wcscmp(default_devid, devid) == 0) { + *default_device = sdldevice; + } + SDL_free(devname); + } + CoTaskMemFree(devid); + } + IMMDevice_Release(immdevice); } - SDL_free(item->devname); - CoTaskMemFree(item->devid); } - SDL_free(items); + SDL_free(default_devid); + IMMDeviceCollection_Release(collection); } -void SDL_IMMDevice_EnumerateEndpoints(SDL_bool useguid) +void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture) { - notification_client.useguid = useguid; - - EnumerateEndpointsForFlow(SDL_FALSE); /* playback */ - EnumerateEndpointsForFlow(SDL_TRUE); /* capture */ + EnumerateEndpointsForFlow(SDL_FALSE, default_output); /* playback */ + EnumerateEndpointsForFlow(SDL_TRUE, default_capture); /* 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 == NULL) { - 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 SDL_AUDIO_F32SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { - return SDL_AUDIO_S16SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { - return SDL_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 SDL_AUDIO_F32SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { - return SDL_AUDIO_S16SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { - return SDL_AUDIO_S32SYS; - } - } - return 0; -} - #endif /* (defined(__WIN32__) || defined(__GDK__)) && defined(HAVE_MMDEVICEAPI_H) */ diff --git a/src/core/windows/SDL_immdevice.h b/src/core/windows/SDL_immdevice.h index c97402fd..a190a7cf 100644 --- a/src/core/windows/SDL_immdevice.h +++ b/src/core/windows/SDL_immdevice.h @@ -26,16 +26,14 @@ #include #include +typedef struct SDL_AudioDevice SDL_AudioDevice; // this is defined in src/audio/SDL_sysaudio.h + 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_AtomicInt SDL_IMMDevice_DefaultPlaybackGeneration; -extern SDL_AtomicInt SDL_IMMDevice_DefaultCaptureGeneration; +int SDL_IMMDevice_Get(SDL_AudioDevice *device, IMMDevice **immdevice, SDL_bool iscapture); +void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture); +LPGUID SDL_IMMDevice_GetDirectSoundGUID(SDL_AudioDevice *device); +LPCWSTR SDL_IMMDevice_GetDevID(SDL_AudioDevice *device); +void SDL_IMMDevice_FreeDeviceHandle(SDL_AudioDevice *device); #endif /* SDL_IMMDEVICE_H */ diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index c18bd642..467d4bb7 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -335,6 +335,33 @@ BOOL WIN_IsRectEmpty(const RECT *rect) return (rect->right <= rect->left) || (rect->bottom <= rect->top); } +/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ +/* *INDENT-OFF* */ /* clang-format off */ +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 */ + +SDL_AudioFormat SDL_WaveFormatExToSDLFormat(WAVEFORMATEX *waveformat) +{ + if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) { + return SDL_AUDIO_F32SYS; + } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { + return SDL_AUDIO_S16SYS; + } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { + return SDL_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 SDL_AUDIO_F32SYS; + } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { + return SDL_AUDIO_S16SYS; + } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { + return SDL_AUDIO_S32SYS; + } + } + return 0; +} + /* Win32-specific SDL_RunApp(), which does most of the SDL_main work, based on SDL_windows_main.c, placed in the public domain by Sam Lantinga 4/13/98 */ #ifdef __WIN32__ @@ -348,7 +375,7 @@ static int OutOfMemory(void) return -1; } -DECLSPEC int SDL_RunApp(int _argc, char* _argv[], SDL_main_func mainFunction, void * reserved) +DECLSPEC int MINGW32_FORCEALIGN SDL_RunApp(int _argc, char* _argv[], SDL_main_func mainFunction, void * reserved) { /* Gets the arguments with GetCommandLine, converts them to argc and argv diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index f6d87b18..89289383 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -76,8 +76,22 @@ #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 /* Older Visual C++ headers don't have the Win64-compatible typedefs... */ #if defined(_MSC_VER) && (_MSC_VER <= 1200) @@ -154,6 +168,8 @@ 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); +extern SDL_AudioFormat SDL_WaveFormatExToSDLFormat(WAVEFORMATEX *waveformat); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 751abf72..800e2d15 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -35,22 +35,17 @@ SDL3_0.0.0 { SDL_BroadcastCondition; SDL_CaptureMouse; SDL_CleanupTLS; - SDL_ClearAudioStream; SDL_ClearComposition; SDL_ClearError; SDL_ClearHints; - SDL_ClearQueuedAudio; - SDL_CloseAudioDevice; SDL_CloseGamepad; SDL_CloseJoystick; SDL_CloseSensor; SDL_ComposeCustomBlendMode; - SDL_ConvertAudioSamples; SDL_ConvertEventToRenderCoordinates; SDL_ConvertPixels; SDL_ConvertSurface; SDL_ConvertSurfaceFormat; - SDL_CreateAudioStream; SDL_CreateColorCursor; SDL_CreateCondition; SDL_CreateCursor; @@ -82,8 +77,6 @@ SDL3_0.0.0 { SDL_DelHintCallback; SDL_Delay; SDL_DelayNS; - SDL_DequeueAudio; - SDL_DestroyAudioStream; SDL_DestroyCondition; SDL_DestroyCursor; SDL_DestroyMutex; @@ -114,7 +107,6 @@ SDL3_0.0.0 { SDL_FillSurfaceRects; SDL_FilterEvents; SDL_FlashWindow; - SDL_FlushAudioStream; SDL_FlushEvent; SDL_FlushEvents; SDL_GDKGetTaskQueue; @@ -150,27 +142,18 @@ SDL3_0.0.0 { SDL_GetAndroidSDKVersion; SDL_GetAssertionHandler; SDL_GetAssertionReport; - SDL_GetAudioDeviceName; - SDL_GetAudioDeviceSpec; - SDL_GetAudioDeviceStatus; - SDL_GetAudioDriver; - SDL_GetAudioStreamAvailable; - SDL_GetAudioStreamData; - SDL_GetAudioStreamFormat; SDL_GetBasePath; SDL_GetCPUCacheLineSize; SDL_GetCPUCount; SDL_GetClipboardData; SDL_GetClipboardText; SDL_GetClosestFullscreenDisplayMode; - SDL_GetCurrentAudioDriver; SDL_GetCurrentDisplayMode; SDL_GetCurrentDisplayOrientation; SDL_GetCurrentRenderOutputSize; SDL_GetCurrentVideoDriver; SDL_GetCursor; SDL_GetDefaultAssertionHandler; - SDL_GetDefaultAudioInfo; SDL_GetDefaultCursor; SDL_GetDesktopDisplayMode; SDL_GetDisplayBounds; @@ -267,8 +250,6 @@ SDL3_0.0.0 { SDL_GetMouseState; SDL_GetNaturalDisplayOrientation; SDL_GetNumAllocations; - SDL_GetNumAudioDevices; - SDL_GetNumAudioDrivers; SDL_GetNumGamepadMappings; SDL_GetNumGamepadTouchpadFingers; SDL_GetNumGamepadTouchpads; @@ -280,7 +261,7 @@ SDL3_0.0.0 { SDL_GetNumTouchFingers; SDL_GetNumVideoDrivers; SDL_GetOriginalMemoryFunctions; - SDL_GetPath; + SDL_GetUserFolder; SDL_GetPerformanceCounter; SDL_GetPerformanceFrequency; SDL_GetPixelFormatEnumForMasks; @@ -291,7 +272,6 @@ SDL3_0.0.0 { SDL_GetPreferredLocales; SDL_GetPrimaryDisplay; SDL_GetPrimarySelectionText; - SDL_GetQueuedAudioSize; SDL_GetRGB; SDL_GetRGBA; SDL_GetRectAndLineIntersection; @@ -461,8 +441,6 @@ SDL3_0.0.0 { SDL_LoadFile_RW; SDL_LoadFunction; SDL_LoadObject; - SDL_LoadWAV_RW; - SDL_LockAudioDevice; SDL_LockJoysticks; SDL_LockMutex; SDL_LockRWLockForReading; @@ -494,7 +472,6 @@ SDL3_0.0.0 { SDL_Metal_DestroyView; SDL_Metal_GetLayer; SDL_MinimizeWindow; - SDL_MixAudioFormat; SDL_MouseIsHaptic; SDL_NumHaptics; SDL_OnApplicationDidBecomeActive; @@ -504,22 +481,17 @@ SDL3_0.0.0 { SDL_OnApplicationWillEnterForeground; SDL_OnApplicationWillResignActive; SDL_OnApplicationWillTerminate; - SDL_OpenAudioDevice; SDL_OpenGamepad; SDL_OpenJoystick; SDL_OpenSensor; SDL_OpenURL; - SDL_PauseAudioDevice; SDL_PeepEvents; - SDL_PlayAudioDevice; SDL_PollEvent; SDL_PostSemaphore; SDL_PremultiplyAlpha; SDL_PumpEvents; SDL_PushEvent; - SDL_PutAudioStreamData; SDL_QueryTexture; - SDL_QueueAudio; SDL_Quit; SDL_QuitSubSystem; SDL_RWFromConstMem; @@ -532,12 +504,12 @@ SDL3_0.0.0 { SDL_RWtell; SDL_RWwrite; SDL_RaiseWindow; - SDL_ReadBE16; - SDL_ReadBE32; - SDL_ReadBE64; - SDL_ReadLE16; - SDL_ReadLE32; - SDL_ReadLE64; + SDL_ReadU16BE; + SDL_ReadU32BE; + SDL_ReadU64BE; + SDL_ReadU16LE; + SDL_ReadU32LE; + SDL_ReadU64LE; SDL_ReadU8; SDL_RegisterApp; SDL_RegisterEvents; @@ -672,7 +644,6 @@ SDL3_0.0.0 { SDL_TryLockRWLockForWriting; SDL_TryWaitSemaphore; SDL_UnloadObject; - SDL_UnlockAudioDevice; SDL_UnlockJoysticks; SDL_UnlockMutex; SDL_UnlockRWLock; @@ -705,12 +676,12 @@ SDL3_0.0.0 { SDL_WinRTGetDeviceFamily; SDL_WinRTGetFSPathUNICODE; SDL_WinRTGetFSPathUTF8; - SDL_WriteBE16; - SDL_WriteBE32; - SDL_WriteBE64; - SDL_WriteLE16; - SDL_WriteLE32; - SDL_WriteLE64; + SDL_WriteU16BE; + SDL_WriteU32BE; + SDL_WriteU64BE; + SDL_WriteU16LE; + SDL_WriteU32LE; + SDL_WriteU64LE; SDL_WriteU8; SDL_abs; SDL_acos; @@ -879,6 +850,55 @@ SDL3_0.0.0 { SDL_strnlen; SDL_AddGamepadMappingsFromFile; SDL_ReloadGamepadMappings; + SDL_GetNumAudioDrivers; + SDL_GetAudioDriver; + SDL_GetCurrentAudioDriver; + SDL_GetAudioOutputDevices; + SDL_GetAudioCaptureDevices; + SDL_GetAudioDeviceName; + SDL_GetAudioDeviceFormat; + SDL_OpenAudioDevice; + SDL_CloseAudioDevice; + SDL_BindAudioStreams; + SDL_BindAudioStream; + SDL_UnbindAudioStreams; + SDL_UnbindAudioStream; + SDL_CreateAudioStream; + SDL_GetAudioStreamFormat; + SDL_SetAudioStreamFormat; + SDL_PutAudioStreamData; + SDL_GetAudioStreamData; + SDL_GetAudioStreamAvailable; + SDL_FlushAudioStream; + SDL_ClearAudioStream; + SDL_LockAudioStream; + SDL_UnlockAudioStream; + SDL_SetAudioStreamGetCallback; + SDL_SetAudioStreamPutCallback; + SDL_DestroyAudioStream; + SDL_CreateAndBindAudioStream; + SDL_LoadWAV_RW; + SDL_LoadWAV; + SDL_MixAudioFormat; + SDL_ConvertAudioSamples; + SDL_GetSilenceValueForFormat; + SDL_LoadWAV; + SDL_PauseAudioDevice; + SDL_ResumeAudioDevice; + SDL_IsAudioDevicePaused; + SDL_GetAudioStreamBinding; + SDL_ShowWindowSystemMenu; + SDL_ReadS16LE; + SDL_ReadS16BE; + SDL_ReadS32LE; + SDL_ReadS32BE; + SDL_ReadS64LE; + SDL_ReadS64BE; + SDL_WriteS16LE; + SDL_WriteS16BE; + SDL_WriteS32LE; + SDL_WriteS32BE; + SDL_WriteS64LE; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 3fefcb19..4d3d2510 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -59,22 +59,17 @@ #define SDL_BroadcastCondition SDL_BroadcastCondition_REAL #define SDL_CaptureMouse SDL_CaptureMouse_REAL #define SDL_CleanupTLS SDL_CleanupTLS_REAL -#define SDL_ClearAudioStream SDL_ClearAudioStream_REAL #define SDL_ClearComposition SDL_ClearComposition_REAL #define SDL_ClearError SDL_ClearError_REAL #define SDL_ClearHints SDL_ClearHints_REAL -#define SDL_ClearQueuedAudio SDL_ClearQueuedAudio_REAL -#define SDL_CloseAudioDevice SDL_CloseAudioDevice_REAL #define SDL_CloseGamepad SDL_CloseGamepad_REAL #define SDL_CloseJoystick SDL_CloseJoystick_REAL #define SDL_CloseSensor SDL_CloseSensor_REAL #define SDL_ComposeCustomBlendMode SDL_ComposeCustomBlendMode_REAL -#define SDL_ConvertAudioSamples SDL_ConvertAudioSamples_REAL #define SDL_ConvertEventToRenderCoordinates SDL_ConvertEventToRenderCoordinates_REAL #define SDL_ConvertPixels SDL_ConvertPixels_REAL #define SDL_ConvertSurface SDL_ConvertSurface_REAL #define SDL_ConvertSurfaceFormat SDL_ConvertSurfaceFormat_REAL -#define SDL_CreateAudioStream SDL_CreateAudioStream_REAL #define SDL_CreateColorCursor SDL_CreateColorCursor_REAL #define SDL_CreateCondition SDL_CreateCondition_REAL #define SDL_CreateCursor SDL_CreateCursor_REAL @@ -106,8 +101,6 @@ #define SDL_DelHintCallback SDL_DelHintCallback_REAL #define SDL_Delay SDL_Delay_REAL #define SDL_DelayNS SDL_DelayNS_REAL -#define SDL_DequeueAudio SDL_DequeueAudio_REAL -#define SDL_DestroyAudioStream SDL_DestroyAudioStream_REAL #define SDL_DestroyCondition SDL_DestroyCondition_REAL #define SDL_DestroyCursor SDL_DestroyCursor_REAL #define SDL_DestroyMutex SDL_DestroyMutex_REAL @@ -138,7 +131,6 @@ #define SDL_FillSurfaceRects SDL_FillSurfaceRects_REAL #define SDL_FilterEvents SDL_FilterEvents_REAL #define SDL_FlashWindow SDL_FlashWindow_REAL -#define SDL_FlushAudioStream SDL_FlushAudioStream_REAL #define SDL_FlushEvent SDL_FlushEvent_REAL #define SDL_FlushEvents SDL_FlushEvents_REAL #define SDL_GDKGetTaskQueue SDL_GDKGetTaskQueue_REAL @@ -174,27 +166,18 @@ #define SDL_GetAndroidSDKVersion SDL_GetAndroidSDKVersion_REAL #define SDL_GetAssertionHandler SDL_GetAssertionHandler_REAL #define SDL_GetAssertionReport SDL_GetAssertionReport_REAL -#define SDL_GetAudioDeviceName SDL_GetAudioDeviceName_REAL -#define SDL_GetAudioDeviceSpec SDL_GetAudioDeviceSpec_REAL -#define SDL_GetAudioDeviceStatus SDL_GetAudioDeviceStatus_REAL -#define SDL_GetAudioDriver SDL_GetAudioDriver_REAL -#define SDL_GetAudioStreamAvailable SDL_GetAudioStreamAvailable_REAL -#define SDL_GetAudioStreamData SDL_GetAudioStreamData_REAL -#define SDL_GetAudioStreamFormat SDL_GetAudioStreamFormat_REAL #define SDL_GetBasePath SDL_GetBasePath_REAL #define SDL_GetCPUCacheLineSize SDL_GetCPUCacheLineSize_REAL #define SDL_GetCPUCount SDL_GetCPUCount_REAL #define SDL_GetClipboardData SDL_GetClipboardData_REAL #define SDL_GetClipboardText SDL_GetClipboardText_REAL #define SDL_GetClosestFullscreenDisplayMode SDL_GetClosestFullscreenDisplayMode_REAL -#define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL #define SDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode_REAL #define SDL_GetCurrentDisplayOrientation SDL_GetCurrentDisplayOrientation_REAL #define SDL_GetCurrentRenderOutputSize SDL_GetCurrentRenderOutputSize_REAL #define SDL_GetCurrentVideoDriver SDL_GetCurrentVideoDriver_REAL #define SDL_GetCursor SDL_GetCursor_REAL #define SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler_REAL -#define SDL_GetDefaultAudioInfo SDL_GetDefaultAudioInfo_REAL #define SDL_GetDefaultCursor SDL_GetDefaultCursor_REAL #define SDL_GetDesktopDisplayMode SDL_GetDesktopDisplayMode_REAL #define SDL_GetDisplayBounds SDL_GetDisplayBounds_REAL @@ -291,8 +274,6 @@ #define SDL_GetMouseState SDL_GetMouseState_REAL #define SDL_GetNaturalDisplayOrientation SDL_GetNaturalDisplayOrientation_REAL #define SDL_GetNumAllocations SDL_GetNumAllocations_REAL -#define SDL_GetNumAudioDevices SDL_GetNumAudioDevices_REAL -#define SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers_REAL #define SDL_GetNumGamepadMappings SDL_GetNumGamepadMappings_REAL #define SDL_GetNumGamepadTouchpadFingers SDL_GetNumGamepadTouchpadFingers_REAL #define SDL_GetNumGamepadTouchpads SDL_GetNumGamepadTouchpads_REAL @@ -304,7 +285,7 @@ #define SDL_GetNumTouchFingers SDL_GetNumTouchFingers_REAL #define SDL_GetNumVideoDrivers SDL_GetNumVideoDrivers_REAL #define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL -#define SDL_GetPath SDL_GetPath_REAL +#define SDL_GetUserFolder SDL_GetUserFolder_REAL #define SDL_GetPerformanceCounter SDL_GetPerformanceCounter_REAL #define SDL_GetPerformanceFrequency SDL_GetPerformanceFrequency_REAL #define SDL_GetPixelFormatEnumForMasks SDL_GetPixelFormatEnumForMasks_REAL @@ -315,7 +296,6 @@ #define SDL_GetPreferredLocales SDL_GetPreferredLocales_REAL #define SDL_GetPrimaryDisplay SDL_GetPrimaryDisplay_REAL #define SDL_GetPrimarySelectionText SDL_GetPrimarySelectionText_REAL -#define SDL_GetQueuedAudioSize SDL_GetQueuedAudioSize_REAL #define SDL_GetRGB SDL_GetRGB_REAL #define SDL_GetRGBA SDL_GetRGBA_REAL #define SDL_GetRectAndLineIntersection SDL_GetRectAndLineIntersection_REAL @@ -485,8 +465,6 @@ #define SDL_LoadFile_RW SDL_LoadFile_RW_REAL #define SDL_LoadFunction SDL_LoadFunction_REAL #define SDL_LoadObject SDL_LoadObject_REAL -#define SDL_LoadWAV_RW SDL_LoadWAV_RW_REAL -#define SDL_LockAudioDevice SDL_LockAudioDevice_REAL #define SDL_LockJoysticks SDL_LockJoysticks_REAL #define SDL_LockMutex SDL_LockMutex_REAL #define SDL_LockRWLockForReading SDL_LockRWLockForReading_REAL @@ -518,7 +496,6 @@ #define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL #define SDL_Metal_GetLayer SDL_Metal_GetLayer_REAL #define SDL_MinimizeWindow SDL_MinimizeWindow_REAL -#define SDL_MixAudioFormat SDL_MixAudioFormat_REAL #define SDL_MouseIsHaptic SDL_MouseIsHaptic_REAL #define SDL_NumHaptics SDL_NumHaptics_REAL #define SDL_OnApplicationDidBecomeActive SDL_OnApplicationDidBecomeActive_REAL @@ -528,22 +505,17 @@ #define SDL_OnApplicationWillEnterForeground SDL_OnApplicationWillEnterForeground_REAL #define SDL_OnApplicationWillResignActive SDL_OnApplicationWillResignActive_REAL #define SDL_OnApplicationWillTerminate SDL_OnApplicationWillTerminate_REAL -#define SDL_OpenAudioDevice SDL_OpenAudioDevice_REAL #define SDL_OpenGamepad SDL_OpenGamepad_REAL #define SDL_OpenJoystick SDL_OpenJoystick_REAL #define SDL_OpenSensor SDL_OpenSensor_REAL #define SDL_OpenURL SDL_OpenURL_REAL -#define SDL_PauseAudioDevice SDL_PauseAudioDevice_REAL #define SDL_PeepEvents SDL_PeepEvents_REAL -#define SDL_PlayAudioDevice SDL_PlayAudioDevice_REAL #define SDL_PollEvent SDL_PollEvent_REAL #define SDL_PostSemaphore SDL_PostSemaphore_REAL #define SDL_PremultiplyAlpha SDL_PremultiplyAlpha_REAL #define SDL_PumpEvents SDL_PumpEvents_REAL #define SDL_PushEvent SDL_PushEvent_REAL -#define SDL_PutAudioStreamData SDL_PutAudioStreamData_REAL #define SDL_QueryTexture SDL_QueryTexture_REAL -#define SDL_QueueAudio SDL_QueueAudio_REAL #define SDL_Quit SDL_Quit_REAL #define SDL_QuitSubSystem SDL_QuitSubSystem_REAL #define SDL_RWFromConstMem SDL_RWFromConstMem_REAL @@ -556,12 +528,12 @@ #define SDL_RWtell SDL_RWtell_REAL #define SDL_RWwrite SDL_RWwrite_REAL #define SDL_RaiseWindow SDL_RaiseWindow_REAL -#define SDL_ReadBE16 SDL_ReadBE16_REAL -#define SDL_ReadBE32 SDL_ReadBE32_REAL -#define SDL_ReadBE64 SDL_ReadBE64_REAL -#define SDL_ReadLE16 SDL_ReadLE16_REAL -#define SDL_ReadLE32 SDL_ReadLE32_REAL -#define SDL_ReadLE64 SDL_ReadLE64_REAL +#define SDL_ReadU16BE SDL_ReadU16BE_REAL +#define SDL_ReadU32BE SDL_ReadU32BE_REAL +#define SDL_ReadU64BE SDL_ReadU64BE_REAL +#define SDL_ReadU16LE SDL_ReadU16LE_REAL +#define SDL_ReadU32LE SDL_ReadU32LE_REAL +#define SDL_ReadU64LE SDL_ReadU64LE_REAL #define SDL_ReadU8 SDL_ReadU8_REAL #define SDL_RegisterApp SDL_RegisterApp_REAL #define SDL_RegisterEvents SDL_RegisterEvents_REAL @@ -605,7 +577,6 @@ #define SDL_SendGamepadEffect SDL_SendGamepadEffect_REAL #define SDL_SendJoystickEffect SDL_SendJoystickEffect_REAL #define SDL_SetAssertionHandler SDL_SetAssertionHandler_REAL -#define SDL_SetAudioStreamFormat SDL_SetAudioStreamFormat_REAL #define SDL_SetClipboardData SDL_SetClipboardData_REAL #define SDL_SetClipboardText SDL_SetClipboardText_REAL #define SDL_SetCursor SDL_SetCursor_REAL @@ -696,7 +667,6 @@ #define SDL_TryLockRWLockForWriting SDL_TryLockRWLockForWriting_REAL #define SDL_TryWaitSemaphore SDL_TryWaitSemaphore_REAL #define SDL_UnloadObject SDL_UnloadObject_REAL -#define SDL_UnlockAudioDevice SDL_UnlockAudioDevice_REAL #define SDL_UnlockJoysticks SDL_UnlockJoysticks_REAL #define SDL_UnlockMutex SDL_UnlockMutex_REAL #define SDL_UnlockRWLock SDL_UnlockRWLock_REAL @@ -729,12 +699,12 @@ #define SDL_WinRTGetDeviceFamily SDL_WinRTGetDeviceFamily_REAL #define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL #define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL -#define SDL_WriteBE16 SDL_WriteBE16_REAL -#define SDL_WriteBE32 SDL_WriteBE32_REAL -#define SDL_WriteBE64 SDL_WriteBE64_REAL -#define SDL_WriteLE16 SDL_WriteLE16_REAL -#define SDL_WriteLE32 SDL_WriteLE32_REAL -#define SDL_WriteLE64 SDL_WriteLE64_REAL +#define SDL_WriteU16BE SDL_WriteU16BE_REAL +#define SDL_WriteU32BE SDL_WriteU32BE_REAL +#define SDL_WriteU64BE SDL_WriteU64BE_REAL +#define SDL_WriteU16LE SDL_WriteU16LE_REAL +#define SDL_WriteU32LE SDL_WriteU32LE_REAL +#define SDL_WriteU64LE SDL_WriteU64LE_REAL #define SDL_WriteU8 SDL_WriteU8_REAL #define SDL_abs SDL_abs_REAL #define SDL_acos SDL_acos_REAL @@ -905,3 +875,52 @@ #define SDL_strnlen SDL_strnlen_REAL #define SDL_AddGamepadMappingsFromFile SDL_AddGamepadMappingsFromFile_REAL #define SDL_ReloadGamepadMappings SDL_ReloadGamepadMappings_REAL +#define SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers_REAL +#define SDL_GetAudioDriver SDL_GetAudioDriver_REAL +#define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL +#define SDL_GetAudioOutputDevices SDL_GetAudioOutputDevices_REAL +#define SDL_GetAudioCaptureDevices SDL_GetAudioCaptureDevices_REAL +#define SDL_GetAudioDeviceName SDL_GetAudioDeviceName_REAL +#define SDL_GetAudioDeviceFormat SDL_GetAudioDeviceFormat_REAL +#define SDL_OpenAudioDevice SDL_OpenAudioDevice_REAL +#define SDL_CloseAudioDevice SDL_CloseAudioDevice_REAL +#define SDL_BindAudioStreams SDL_BindAudioStreams_REAL +#define SDL_BindAudioStream SDL_BindAudioStream_REAL +#define SDL_UnbindAudioStreams SDL_UnbindAudioStreams_REAL +#define SDL_UnbindAudioStream SDL_UnbindAudioStream_REAL +#define SDL_CreateAudioStream SDL_CreateAudioStream_REAL +#define SDL_GetAudioStreamFormat SDL_GetAudioStreamFormat_REAL +#define SDL_SetAudioStreamFormat SDL_SetAudioStreamFormat_REAL +#define SDL_PutAudioStreamData SDL_PutAudioStreamData_REAL +#define SDL_GetAudioStreamData SDL_GetAudioStreamData_REAL +#define SDL_GetAudioStreamAvailable SDL_GetAudioStreamAvailable_REAL +#define SDL_FlushAudioStream SDL_FlushAudioStream_REAL +#define SDL_ClearAudioStream SDL_ClearAudioStream_REAL +#define SDL_LockAudioStream SDL_LockAudioStream_REAL +#define SDL_UnlockAudioStream SDL_UnlockAudioStream_REAL +#define SDL_SetAudioStreamGetCallback SDL_SetAudioStreamGetCallback_REAL +#define SDL_SetAudioStreamPutCallback SDL_SetAudioStreamPutCallback_REAL +#define SDL_DestroyAudioStream SDL_DestroyAudioStream_REAL +#define SDL_CreateAndBindAudioStream SDL_CreateAndBindAudioStream_REAL +#define SDL_LoadWAV_RW SDL_LoadWAV_RW_REAL +#define SDL_LoadWAV SDL_LoadWAV_REAL +#define SDL_MixAudioFormat SDL_MixAudioFormat_REAL +#define SDL_ConvertAudioSamples SDL_ConvertAudioSamples_REAL +#define SDL_GetSilenceValueForFormat SDL_GetSilenceValueForFormat_REAL +#define SDL_LoadWAV SDL_LoadWAV_REAL +#define SDL_PauseAudioDevice SDL_PauseAudioDevice_REAL +#define SDL_ResumeAudioDevice SDL_ResumeAudioDevice_REAL +#define SDL_IsAudioDevicePaused SDL_IsAudioDevicePaused_REAL +#define SDL_GetAudioStreamBinding SDL_GetAudioStreamBinding_REAL +#define SDL_ShowWindowSystemMenu SDL_ShowWindowSystemMenu_REAL +#define SDL_ReadS16LE SDL_ReadS16LE_REAL +#define SDL_ReadS16BE SDL_ReadS16BE_REAL +#define SDL_ReadS32LE SDL_ReadS32LE_REAL +#define SDL_ReadS32BE SDL_ReadS32BE_REAL +#define SDL_ReadS64LE SDL_ReadS64LE_REAL +#define SDL_ReadS64BE SDL_ReadS64BE_REAL +#define SDL_WriteS16LE SDL_WriteS16LE_REAL +#define SDL_WriteS16BE SDL_WriteS16BE_REAL +#define SDL_WriteS32LE SDL_WriteS32LE_REAL +#define SDL_WriteS32BE SDL_WriteS32BE_REAL +#define SDL_WriteS64LE SDL_WriteS64LE_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 7b93149f..a8a4c1e4 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -119,7 +119,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_IsDeXMode,(void),(),return) SDL_DYNAPI_PROC(void,SDL_AddEventWatch,(SDL_EventFilter a, void *b),(a,b),) SDL_DYNAPI_PROC(int,SDL_AddGamepadMapping,(const char *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromRW,(SDL_RWops *a, int b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromRW,(SDL_RWops *a, SDL_bool b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_AddHintCallback,(const char *a, SDL_HintCallback b, void *c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_TimerID,SDL_AddTimer,(Uint32 a, SDL_TimerCallback b, void *c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_AtomicAdd,(SDL_AtomicInt *a, int b),(a,b),return) @@ -141,22 +141,17 @@ SDL_DYNAPI_PROC(int,SDL_BlitSurfaceUncheckedScaled,(SDL_Surface *a, const SDL_Re SDL_DYNAPI_PROC(int,SDL_BroadcastCondition,(SDL_Condition *a),(a),return) SDL_DYNAPI_PROC(int,SDL_CaptureMouse,(SDL_bool a),(a),return) SDL_DYNAPI_PROC(void,SDL_CleanupTLS,(void),(),) -SDL_DYNAPI_PROC(int,SDL_ClearAudioStream,(SDL_AudioStream *a),(a),return) SDL_DYNAPI_PROC(void,SDL_ClearComposition,(void),(),) SDL_DYNAPI_PROC(void,SDL_ClearError,(void),(),) SDL_DYNAPI_PROC(void,SDL_ClearHints,(void),(),) -SDL_DYNAPI_PROC(int,SDL_ClearQueuedAudio,(SDL_AudioDeviceID a),(a),return) -SDL_DYNAPI_PROC(void,SDL_CloseAudioDevice,(SDL_AudioDeviceID a),(a),) SDL_DYNAPI_PROC(void,SDL_CloseGamepad,(SDL_Gamepad *a),(a),) SDL_DYNAPI_PROC(void,SDL_CloseJoystick,(SDL_Joystick *a),(a),) SDL_DYNAPI_PROC(void,SDL_CloseSensor,(SDL_Sensor *a),(a),) SDL_DYNAPI_PROC(SDL_BlendMode,SDL_ComposeCustomBlendMode,(SDL_BlendFactor a, SDL_BlendFactor b, SDL_BlendOperation c, SDL_BlendFactor d, SDL_BlendFactor e, SDL_BlendOperation f),(a,b,c,d,e,f),return) -SDL_DYNAPI_PROC(int,SDL_ConvertAudioSamples,(SDL_AudioFormat a, Uint8 b, int c, const Uint8 *d, int e, SDL_AudioFormat f, Uint8 g, int h, Uint8 **i, int *j),(a,b,c,d,e,f,g,h,i,j),return) SDL_DYNAPI_PROC(int,SDL_ConvertEventToRenderCoordinates,(SDL_Renderer *a, SDL_Event *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_ConvertPixels,(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) SDL_DYNAPI_PROC(SDL_Surface*,SDL_ConvertSurface,(SDL_Surface *a, const SDL_PixelFormat *b),(a,b),return) SDL_DYNAPI_PROC(SDL_Surface*,SDL_ConvertSurfaceFormat,(SDL_Surface *a, Uint32 b),(a,b),return) -SDL_DYNAPI_PROC(SDL_AudioStream*,SDL_CreateAudioStream,(SDL_AudioFormat a, int b, int c, SDL_AudioFormat d, int e, int f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateColorCursor,(SDL_Surface *a, int b, int c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_Condition*,SDL_CreateCondition,(void),(),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateCursor,(const Uint8 *a, const Uint8 *b, int c, int d, int e, int f),(a,b,c,d,e,f),return) @@ -185,8 +180,6 @@ SDL_DYNAPI_PROC(void,SDL_DelEventWatch,(SDL_EventFilter a, void *b),(a,b),) SDL_DYNAPI_PROC(void,SDL_DelHintCallback,(const char *a, SDL_HintCallback b, void *c),(a,b,c),) SDL_DYNAPI_PROC(void,SDL_Delay,(Uint32 a),(a),) SDL_DYNAPI_PROC(void,SDL_DelayNS,(Uint64 a),(a),) -SDL_DYNAPI_PROC(Uint32,SDL_DequeueAudio,(SDL_AudioDeviceID a, void *b, Uint32 c),(a,b,c),return) -SDL_DYNAPI_PROC(void,SDL_DestroyAudioStream,(SDL_AudioStream *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyCondition,(SDL_Condition *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyCursor,(SDL_Cursor *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyMutex,(SDL_Mutex *a),(a),) @@ -216,7 +209,6 @@ SDL_DYNAPI_PROC(int,SDL_FillSurfaceRect,(SDL_Surface *a, const SDL_Rect *b, Uint SDL_DYNAPI_PROC(int,SDL_FillSurfaceRects,(SDL_Surface *a, const SDL_Rect *b, int c, Uint32 d),(a,b,c,d),return) SDL_DYNAPI_PROC(void,SDL_FilterEvents,(SDL_EventFilter a, void *b),(a,b),) SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a, SDL_FlashOperation b),(a,b),return) -SDL_DYNAPI_PROC(int,SDL_FlushAudioStream,(SDL_AudioStream *a),(a),return) SDL_DYNAPI_PROC(void,SDL_FlushEvent,(Uint32 a),(a),) SDL_DYNAPI_PROC(void,SDL_FlushEvents,(Uint32 a, Uint32 b),(a,b),) SDL_DYNAPI_PROC(int,SDL_GL_BindTexture,(SDL_Texture *a, float *b, float *c),(a,b,c),return) @@ -249,27 +241,18 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_GamepadHasSensor,(SDL_Gamepad *a, SDL_SensorType b) SDL_DYNAPI_PROC(SDL_bool,SDL_GamepadSensorEnabled,(SDL_Gamepad *a, SDL_SensorType b),(a,b),return) SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetAssertionHandler,(void **a),(a),return) SDL_DYNAPI_PROC(const SDL_AssertData*,SDL_GetAssertionReport,(void),(),return) -SDL_DYNAPI_PROC(const char*,SDL_GetAudioDeviceName,(int a, int b),(a,b),return) -SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceSpec,(int a, int b, SDL_AudioSpec *c),(a,b,c),return) -SDL_DYNAPI_PROC(SDL_AudioStatus,SDL_GetAudioDeviceStatus,(SDL_AudioDeviceID a),(a),return) -SDL_DYNAPI_PROC(const char*,SDL_GetAudioDriver,(int a),(a),return) -SDL_DYNAPI_PROC(int,SDL_GetAudioStreamAvailable,(SDL_AudioStream *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_GetAudioStreamData,(SDL_AudioStream *a, void *b, int c),(a,b,c),return) -SDL_DYNAPI_PROC(int,SDL_GetAudioStreamFormat,(SDL_AudioStream *a, SDL_AudioFormat *b, int *c, int *d, SDL_AudioFormat *e, int *f, int *g),(a,b,c,d,e,f,g),return) SDL_DYNAPI_PROC(char*,SDL_GetBasePath,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetCPUCacheLineSize,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetCPUCount,(void),(),return) SDL_DYNAPI_PROC(void*,SDL_GetClipboardData,(const char *a, size_t *b),(a,b),return) SDL_DYNAPI_PROC(char*,SDL_GetClipboardText,(void),(),return) SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetClosestFullscreenDisplayMode,(SDL_DisplayID a, int b, int c, float d, SDL_bool e),(a,b,c,d,e),return) -SDL_DYNAPI_PROC(const char*,SDL_GetCurrentAudioDriver,(void),(),return) SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetCurrentDisplayMode,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetCurrentDisplayOrientation,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetCurrentRenderOutputSize,(SDL_Renderer *a, int *b, int *c),(a,b,c),return) SDL_DYNAPI_PROC(const char*,SDL_GetCurrentVideoDriver,(void),(),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_GetCursor,(void),(),return) SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetDefaultAssertionHandler,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetDefaultAudioInfo,(char **a, SDL_AudioSpec *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_GetDefaultCursor,(void),(),return) SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetDesktopDisplayMode,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetDisplayBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return) @@ -366,8 +349,6 @@ SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),return) SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return) SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetNaturalDisplayOrientation,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetNumAudioDevices,(int a),(a),return) -SDL_DYNAPI_PROC(int,SDL_GetNumAudioDrivers,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetNumGamepadMappings,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetNumGamepadTouchpadFingers,(SDL_Gamepad *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetNumGamepadTouchpads,(SDL_Gamepad *a),(a),return) @@ -379,7 +360,7 @@ SDL_DYNAPI_PROC(int,SDL_GetNumTouchDevices,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetNumTouchFingers,(SDL_TouchID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumVideoDrivers,(void),(),return) 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(char*,SDL_GetPath,(SDL_Folder a),(a),return) +SDL_DYNAPI_PROC(char*,SDL_GetUserFolder,(SDL_Folder a),(a),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return) SDL_DYNAPI_PROC(Uint32,SDL_GetPixelFormatEnumForMasks,(int a, Uint32 b, Uint32 c, Uint32 d, Uint32 e),(a,b,c,d,e),return) @@ -390,7 +371,6 @@ SDL_DYNAPI_PROC(char*,SDL_GetPrefPath,(const char *a, const char *b),(a,b),retur SDL_DYNAPI_PROC(SDL_Locale*,SDL_GetPreferredLocales,(void),(),return) SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetPrimaryDisplay,(void),(),return) SDL_DYNAPI_PROC(char*,SDL_GetPrimarySelectionText,(void),(),return) -SDL_DYNAPI_PROC(Uint32,SDL_GetQueuedAudioSize,(SDL_AudioDeviceID a),(a),return) SDL_DYNAPI_PROC(void,SDL_GetRGB,(Uint32 a, const SDL_PixelFormat *b, Uint8 *c, Uint8 *d, Uint8 *e),(a,b,c,d,e),) SDL_DYNAPI_PROC(void,SDL_GetRGBA,(Uint32 a, const SDL_PixelFormat *b, Uint8 *c, Uint8 *d, Uint8 *e, Uint8 *f),(a,b,c,d,e,f),) SDL_DYNAPI_PROC(SDL_bool,SDL_GetRectAndLineIntersection,(const SDL_Rect *a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return) @@ -553,8 +533,6 @@ SDL_DYNAPI_PROC(void*,SDL_LoadFile,(const char *a, size_t *b),(a,b),return) SDL_DYNAPI_PROC(void*,SDL_LoadFile_RW,(SDL_RWops *a, size_t *b, SDL_bool c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_LoadFunction,(void *a, const char *b),(a,b),return) SDL_DYNAPI_PROC(void*,SDL_LoadObject,(const char *a),(a),return) -SDL_DYNAPI_PROC(SDL_AudioSpec*,SDL_LoadWAV_RW,(SDL_RWops *a, SDL_bool b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return) -SDL_DYNAPI_PROC(int,SDL_LockAudioDevice,(SDL_AudioDeviceID a),(a),return) SDL_DYNAPI_PROC(void,SDL_LockJoysticks,(void),(),) SDL_DYNAPI_PROC(int,SDL_LockMutex,(SDL_Mutex *a),(a),return) SDL_DYNAPI_PROC(int,SDL_LockRWLockForReading,(SDL_RWLock *a),(a),return) @@ -578,7 +556,6 @@ SDL_DYNAPI_PROC(SDL_MetalView,SDL_Metal_CreateView,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(void,SDL_Metal_DestroyView,(SDL_MetalView a),(a),) SDL_DYNAPI_PROC(void*,SDL_Metal_GetLayer,(SDL_MetalView a),(a),return) SDL_DYNAPI_PROC(int,SDL_MinimizeWindow,(SDL_Window *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_MixAudioFormat,(Uint8 *a, const Uint8 *b, SDL_AudioFormat c, Uint32 d, int e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(int,SDL_MouseIsHaptic,(void),(),return) SDL_DYNAPI_PROC(int,SDL_NumHaptics,(void),(),return) SDL_DYNAPI_PROC(void,SDL_OnApplicationDidBecomeActive,(void),(),) @@ -587,41 +564,36 @@ SDL_DYNAPI_PROC(void,SDL_OnApplicationDidReceiveMemoryWarning,(void),(),) SDL_DYNAPI_PROC(void,SDL_OnApplicationWillEnterForeground,(void),(),) SDL_DYNAPI_PROC(void,SDL_OnApplicationWillResignActive,(void),(),) SDL_DYNAPI_PROC(void,SDL_OnApplicationWillTerminate,(void),(),) -SDL_DYNAPI_PROC(SDL_AudioDeviceID,SDL_OpenAudioDevice,(const char *a, int b, const SDL_AudioSpec *c, SDL_AudioSpec *d, int e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(SDL_Gamepad*,SDL_OpenGamepad,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(SDL_Joystick*,SDL_OpenJoystick,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(SDL_Sensor*,SDL_OpenSensor,(SDL_SensorID a),(a),return) SDL_DYNAPI_PROC(int,SDL_OpenURL,(const char *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_PauseAudioDevice,(SDL_AudioDeviceID a),(a),return) SDL_DYNAPI_PROC(int,SDL_PeepEvents,(SDL_Event *a, int b, SDL_eventaction c, Uint32 d, Uint32 e),(a,b,c,d,e),return) -SDL_DYNAPI_PROC(int,SDL_PlayAudioDevice,(SDL_AudioDeviceID a),(a),return) SDL_DYNAPI_PROC(int,SDL_PollEvent,(SDL_Event *a),(a),return) SDL_DYNAPI_PROC(int,SDL_PostSemaphore,(SDL_Semaphore *a),(a),return) 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) SDL_DYNAPI_PROC(void,SDL_PumpEvents,(void),(),) SDL_DYNAPI_PROC(int,SDL_PushEvent,(SDL_Event *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_PutAudioStreamData,(SDL_AudioStream *a, const void *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_QueryTexture,(SDL_Texture *a, Uint32 *b, int *c, int *d, int *e),(a,b,c,d,e),return) -SDL_DYNAPI_PROC(int,SDL_QueueAudio,(SDL_AudioDeviceID a, const void *b, Uint32 c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_Quit,(void),(),) SDL_DYNAPI_PROC(void,SDL_QuitSubSystem,(Uint32 a),(a),) SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromConstMem,(const void *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromFile,(const char *a, const char *b),(a,b),return) SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromMem,(void *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_RWclose,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Sint64,SDL_RWread,(SDL_RWops *a, void *b, Sint64 c),(a,b,c),return) +SDL_DYNAPI_PROC(size_t,SDL_RWread,(SDL_RWops *a, void *b, size_t c),(a,b,c),return) SDL_DYNAPI_PROC(Sint64,SDL_RWseek,(SDL_RWops *a, Sint64 b, int c),(a,b,c),return) SDL_DYNAPI_PROC(Sint64,SDL_RWsize,(SDL_RWops *a),(a),return) SDL_DYNAPI_PROC(Sint64,SDL_RWtell,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Sint64,SDL_RWwrite,(SDL_RWops *a, const void *b, Sint64 c),(a,b,c),return) +SDL_DYNAPI_PROC(size_t,SDL_RWwrite,(SDL_RWops *a, const void *b, size_t c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_RaiseWindow,(SDL_Window *a),(a),return) -SDL_DYNAPI_PROC(Uint16,SDL_ReadBE16,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Uint32,SDL_ReadBE32,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Uint64,SDL_ReadBE64,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Uint16,SDL_ReadLE16,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Uint32,SDL_ReadLE32,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Uint64,SDL_ReadLE64,(SDL_RWops *a),(a),return) -SDL_DYNAPI_PROC(Uint8,SDL_ReadU8,(SDL_RWops *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU16BE,(SDL_RWops *a, Uint16 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU32BE,(SDL_RWops *a, Uint32 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU64BE,(SDL_RWops *a, Uint64 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU16LE,(SDL_RWops *a, Uint16 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU32LE,(SDL_RWops *a, Uint32 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU64LE,(SDL_RWops *a, Uint64 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadU8,(SDL_RWops *a, Uint8 *b),(a,b),return) SDL_DYNAPI_PROC(Uint32,SDL_RegisterEvents,(int a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_RemoveTimer,(SDL_TimerID a),(a),return) SDL_DYNAPI_PROC(int,SDL_RenderClear,(SDL_Renderer *a),(a),return) @@ -656,13 +628,12 @@ SDL_DYNAPI_PROC(int,SDL_RumbleJoystickTriggers,(SDL_Joystick *a, Uint16 b, Uint1 SDL_DYNAPI_PROC(int,SDL_RunApp,(int a, char *b[], SDL_main_func c, void *d),(a,b,c,d),return) SDL_DYNAPI_PROC(size_t,SDL_SIMDGetAlignment,(void),(),return) SDL_DYNAPI_PROC(int,SDL_SaveBMP,(SDL_Surface *a, const char *b),(a,b),return) -SDL_DYNAPI_PROC(int,SDL_SaveBMP_RW,(SDL_Surface *a, SDL_RWops *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SaveBMP_RW,(SDL_Surface *a, SDL_RWops *b, SDL_bool c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenKeyboardShown,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenSaverEnabled,(void),(),return) SDL_DYNAPI_PROC(int,SDL_SendGamepadEffect,(SDL_Gamepad *a, const void *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_SendJoystickEffect,(SDL_Joystick *a, const void *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_SetAssertionHandler,(SDL_AssertionHandler a, void *b),(a,b),) -SDL_DYNAPI_PROC(int,SDL_SetAudioStreamFormat,(SDL_AudioStream *a, SDL_AudioFormat b, int c, int d, SDL_AudioFormat e, int f, int g),(a,b,c,d,e,f,g),return) SDL_DYNAPI_PROC(int,SDL_SetClipboardData,(SDL_ClipboardDataCallback a, SDL_ClipboardCleanupCallback b, void *c, const char **d, size_t e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(int,SDL_SetClipboardText,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SetCursor,(SDL_Cursor *a),(a),return) @@ -751,7 +722,6 @@ SDL_DYNAPI_PROC(int,SDL_TryLockRWLockForReading,(SDL_RWLock *a),(a),return) SDL_DYNAPI_PROC(int,SDL_TryLockRWLockForWriting,(SDL_RWLock *a),(a),return) SDL_DYNAPI_PROC(int,SDL_TryWaitSemaphore,(SDL_Semaphore *a),(a),return) SDL_DYNAPI_PROC(void,SDL_UnloadObject,(void *a),(a),) -SDL_DYNAPI_PROC(void,SDL_UnlockAudioDevice,(SDL_AudioDeviceID a),(a),) SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),) SDL_DYNAPI_PROC(int,SDL_UnlockMutex,(SDL_Mutex *a),(a),return) SDL_DYNAPI_PROC(int,SDL_UnlockRWLock,(SDL_RWLock *a),(a),return) @@ -780,13 +750,13 @@ SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),) SDL_DYNAPI_PROC(int,SDL_WarpMouseGlobal,(float a, float b),(a,b),return) SDL_DYNAPI_PROC(void,SDL_WarpMouseInWindow,(SDL_Window *a, float b, float c),(a,b,c),) SDL_DYNAPI_PROC(Uint32,SDL_WasInit,(Uint32 a),(a),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteBE16,(SDL_RWops *a, Uint16 b),(a,b),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteBE32,(SDL_RWops *a, Uint32 b),(a,b),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteBE64,(SDL_RWops *a, Uint64 b),(a,b),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteLE16,(SDL_RWops *a, Uint16 b),(a,b),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteLE32,(SDL_RWops *a, Uint32 b),(a,b),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteLE64,(SDL_RWops *a, Uint64 b),(a,b),return) -SDL_DYNAPI_PROC(size_t,SDL_WriteU8,(SDL_RWops *a, Uint8 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16BE,(SDL_RWops *a, Uint16 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32BE,(SDL_RWops *a, Uint32 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU64BE,(SDL_RWops *a, Uint64 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU16LE,(SDL_RWops *a, Uint16 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU32LE,(SDL_RWops *a, Uint32 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU64LE,(SDL_RWops *a, Uint64 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteU8,(SDL_RWops *a, Uint8 b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return) SDL_DYNAPI_PROC(double,SDL_acos,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_acosf,(float a),(a),return) @@ -950,3 +920,51 @@ SDL_DYNAPI_PROC(size_t,SDL_wcsnlen,(const wchar_t *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(size_t,SDL_strnlen,(const char *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromFile,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_ReloadGamepadMappings,(void),(),return) +SDL_DYNAPI_PROC(int,SDL_GetNumAudioDrivers,(void),(),return) +SDL_DYNAPI_PROC(const char*,SDL_GetAudioDriver,(int a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_GetCurrentAudioDriver,(void),(),return) +SDL_DYNAPI_PROC(SDL_AudioDeviceID*,SDL_GetAudioOutputDevices,(int *a),(a),return) +SDL_DYNAPI_PROC(SDL_AudioDeviceID*,SDL_GetAudioCaptureDevices,(int *a),(a),return) +SDL_DYNAPI_PROC(char*,SDL_GetAudioDeviceName,(SDL_AudioDeviceID a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceFormat,(SDL_AudioDeviceID a, SDL_AudioSpec *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_AudioDeviceID,SDL_OpenAudioDevice,(SDL_AudioDeviceID a, const SDL_AudioSpec *b),(a,b),return) +SDL_DYNAPI_PROC(void,SDL_CloseAudioDevice,(SDL_AudioDeviceID a),(a),) +SDL_DYNAPI_PROC(int,SDL_BindAudioStreams,(SDL_AudioDeviceID a, SDL_AudioStream **b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_BindAudioStream,(SDL_AudioDeviceID a, SDL_AudioStream *b),(a,b),return) +SDL_DYNAPI_PROC(void,SDL_UnbindAudioStreams,(SDL_AudioStream **a, int b),(a,b),) +SDL_DYNAPI_PROC(void,SDL_UnbindAudioStream,(SDL_AudioStream *a),(a),) +SDL_DYNAPI_PROC(SDL_AudioStream*,SDL_CreateAudioStream,(const SDL_AudioSpec *a, const SDL_AudioSpec *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GetAudioStreamFormat,(SDL_AudioStream *a, SDL_AudioSpec *b, SDL_AudioSpec *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SetAudioStreamFormat,(SDL_AudioStream *a, const SDL_AudioSpec *b, const SDL_AudioSpec *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_PutAudioStreamData,(SDL_AudioStream *a, const void *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_GetAudioStreamData,(SDL_AudioStream *a, void *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_GetAudioStreamAvailable,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_FlushAudioStream,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_ClearAudioStream,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_LockAudioStream,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_UnlockAudioStream,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_SetAudioStreamGetCallback,(SDL_AudioStream *a, SDL_AudioStreamRequestCallback b, void *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SetAudioStreamPutCallback,(SDL_AudioStream *a, SDL_AudioStreamRequestCallback b, void *c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_DestroyAudioStream,(SDL_AudioStream *a),(a),) +SDL_DYNAPI_PROC(SDL_AudioStream*,SDL_CreateAndBindAudioStream,(SDL_AudioDeviceID a, const SDL_AudioSpec *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_LoadWAV_RW,(SDL_RWops *a, SDL_bool b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(int,SDL_MixAudioFormat,(Uint8 *a, const Uint8 *b, SDL_AudioFormat c, Uint32 d, int e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(int,SDL_ConvertAudioSamples,(const SDL_AudioSpec *a, const Uint8 *b, int c, const SDL_AudioSpec *d, Uint8 **e, int *f),(a,b,c,d,e,f),return) +SDL_DYNAPI_PROC(int,SDL_GetSilenceValueForFormat,(SDL_AudioFormat a),(a),return) +SDL_DYNAPI_PROC(int,SDL_LoadWAV,(const char *a, SDL_AudioSpec *b, Uint8 **c, Uint32 *d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_PauseAudioDevice,(SDL_AudioDeviceID a),(a),return) +SDL_DYNAPI_PROC(int,SDL_ResumeAudioDevice,(SDL_AudioDeviceID a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_IsAudioDevicePaused,(SDL_AudioDeviceID a),(a),return) +SDL_DYNAPI_PROC(SDL_AudioDeviceID,SDL_GetAudioStreamBinding,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_ShowWindowSystemMenu,(SDL_Window *a, int b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS16LE,(SDL_RWops *a, Sint16 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS16BE,(SDL_RWops *a, Sint16 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS32LE,(SDL_RWops *a, Sint32 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS32BE,(SDL_RWops *a, Sint32 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS64LE,(SDL_RWops *a, Sint64 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ReadS64BE,(SDL_RWops *a, Sint64 *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS16LE,(SDL_RWops *a, Sint16 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS16BE,(SDL_RWops *a, Sint16 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS32LE,(SDL_RWops *a, Sint32 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS32BE,(SDL_RWops *a, Sint32 b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_WriteS64LE,(SDL_RWops *a, Sint64 b),(a,b),return) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 7f4b8928..ac692faa 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -580,8 +580,6 @@ int SDL_StartEventLoop(void) SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, SDL_FALSE); SDL_SetEventEnabled(SDL_EVENT_DROP_TEXT, SDL_FALSE); #endif - SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, SDL_FALSE); - SDL_SetEventEnabled(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, SDL_FALSE); SDL_EventQ.active = SDL_TRUE; SDL_UnlockMutex(SDL_EventQ.lock); diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index eb439ef3..59968b55 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -33,8 +33,9 @@ typedef enum { KEYBOARD_HARDWARE = 0x01, - KEYBOARD_AUTORELEASE = 0x02, - KEYBOARD_IGNOREMODIFIERS = 0x04 + KEYBOARD_VIRTUAL = 0x02, + KEYBOARD_AUTORELEASE = 0x04, + KEYBOARD_IGNOREMODIFIERS = 0x08 } SDL_KeyboardFlags; #define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE) @@ -50,6 +51,7 @@ struct SDL_Keyboard Uint8 keystate[SDL_NUM_SCANCODES]; SDL_Keycode keymap[SDL_NUM_SCANCODES]; SDL_bool autorelease_pending; + Uint64 hardware_timestamp; }; static SDL_Keyboard SDL_keyboard; @@ -875,7 +877,9 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, SDL_KeyboardFlags flags keycode = keyboard->keymap[scancode]; } - if (source == KEYBOARD_AUTORELEASE) { + if (source == KEYBOARD_HARDWARE) { + keyboard->hardware_timestamp = SDL_GetTicks(); + } else if (source == KEYBOARD_AUTORELEASE) { keyboard->autorelease_pending = SDL_TRUE; } @@ -978,20 +982,25 @@ int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch) if (mod & SDL_KMOD_SHIFT) { /* If the character uses shift, press shift down */ - SDL_SendKeyboardKey(timestamp, SDL_PRESSED, SDL_SCANCODE_LSHIFT); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN); } /* Send a keydown and keyup for the character */ - SDL_SendKeyboardKey(timestamp, SDL_PRESSED, code); - SDL_SendKeyboardKey(timestamp, SDL_RELEASED, code); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN); if (mod & SDL_KMOD_SHIFT) { /* If the character uses shift, release shift */ - SDL_SendKeyboardKey(timestamp, SDL_RELEASED, SDL_SCANCODE_LSHIFT); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN); } return 0; } +int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode) +{ + return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, state, scancode, SDLK_UNKNOWN); +} + int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode) { return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN); @@ -1025,6 +1034,13 @@ void SDL_ReleaseAutoReleaseKeys(void) } keyboard->autorelease_pending = SDL_FALSE; } + + if (keyboard->hardware_timestamp) { + /* Keep hardware keyboard "active" for 250 ms */ + if (SDL_GetTicks() >= keyboard->hardware_timestamp + 250) { + keyboard->hardware_timestamp = 0; + } + } } SDL_bool SDL_HardwareKeyboardKeyPressed(void) @@ -1037,7 +1053,8 @@ SDL_bool SDL_HardwareKeyboardKeyPressed(void) return SDL_TRUE; } } - return SDL_FALSE; + + return keyboard->hardware_timestamp ? SDL_TRUE : SDL_FALSE; } int SDL_SendKeyboardText(const char *text) diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index 9381932c..b8e76df6 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -49,6 +49,9 @@ extern int SDL_SetKeyboardFocus(SDL_Window *window); */ extern int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch); +/* Send a key from a virtual key source, like an on-screen keyboard */ +extern int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode); + /* Send a keyboard key event */ extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode); extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode); diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 6591f327..fd8b62ce 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -162,7 +162,7 @@ static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const cha } /* Public functions */ -int SDL_InitMouse(void) +int SDL_PreInitMouse(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -203,8 +203,17 @@ int SDL_InitMouse(void) mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */ mouse->cursor_shown = SDL_TRUE; + return 0; +} - if (!mouse->CreateCursor) { +void SDL_PostInitMouse(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_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888); if (surface) { SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch); @@ -212,14 +221,29 @@ int SDL_InitMouse(void) SDL_DestroySurface(surface); } } - return 0; } 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; + + if (mouse->cur_cursor == mouse->def_cursor) { + mouse->cur_cursor = NULL; + } + mouse->def_cursor = NULL; + + SDL_DestroyCursor(default_cursor); + } + mouse->def_cursor = cursor; + if (!mouse->cur_cursor) { SDL_SetCursor(cursor); } @@ -845,6 +869,10 @@ void SDL_QuitMouse(void) SDL_SetRelativeMouseMode(SDL_FALSE); SDL_ShowCursor(); + if (mouse->def_cursor) { + SDL_SetDefaultCursor(NULL); + } + cursor = mouse->cursors; while (cursor) { next = cursor->next; @@ -854,15 +882,6 @@ void SDL_QuitMouse(void) mouse->cursors = NULL; mouse->cur_cursor = NULL; - if (mouse->def_cursor) { - if (mouse->FreeCursor) { - mouse->FreeCursor(mouse->def_cursor); - } else { - SDL_free(mouse->def_cursor); - } - mouse->def_cursor = NULL; - } - if (mouse->sources) { SDL_free(mouse->sources); mouse->sources = NULL; @@ -1377,7 +1396,7 @@ void SDL_DestroyCursor(SDL_Cursor *cursor) mouse->cursors = curr->next; } - if (mouse->FreeCursor) { + if (mouse->FreeCursor && curr->driverdata) { mouse->FreeCursor(curr); } else { SDL_free(curr); diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index f1613b5a..0887b562 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -122,8 +122,11 @@ typedef struct void *driverdata; } SDL_Mouse; -/* Initialize the mouse subsystem */ -extern int SDL_InitMouse(void); +/* Initialize the mouse subsystem, called before the main video driver is initialized */ +extern int SDL_PreInitMouse(void); + +/* Finish initializing the mouse subsystem, called after the main video driver was initialized */ +extern void SDL_PostInitMouse(void); /* Get the mouse state structure */ SDL_Mouse *SDL_GetMouse(void); diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 2f9cef06..cdd5b361 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -20,7 +20,7 @@ */ #include "SDL_internal.h" -#if defined(__WIN32__) || defined(__GDK__) +#if defined(__WIN32__) || defined(__GDK__) || defined(__WINRT__) #include "../core/windows/SDL_windows.h" #endif @@ -47,10 +47,9 @@ #include "../core/android/SDL_android.h" #endif -#if defined(__WIN32__) || defined(__GDK__) +#if defined(__WIN32__) || defined(__GDK__) || defined(__WINRT__) /* Functions to read/write Win32 API file pointers */ - #ifndef INVALID_SET_FILE_POINTER #define INVALID_SET_FILE_POINTER 0xFFFFFFFF #endif @@ -59,7 +58,7 @@ static int SDLCALL windows_file_open(SDL_RWops *context, const char *filename, const char *mode) { -#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) && !defined(__WINRT__) UINT old_error_mode; #endif HANDLE h; @@ -67,10 +66,6 @@ static int SDLCALL windows_file_open(SDL_RWops *context, const char *filename, c DWORD must_exist, truncate; int a_mode; - if (context == NULL) { - return -1; /* failed (invalid call) */ - } - context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ context->hidden.windowsio.buffer.data = NULL; context->hidden.windowsio.buffer.size = 0; @@ -99,7 +94,7 @@ static int SDLCALL windows_file_open(SDL_RWops *context, const char *filename, c if (!context->hidden.windowsio.buffer.data) { return SDL_OutOfMemory(); } -#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) && !defined(__WINRT__) /* Do not open a dialog box if failure */ old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); @@ -107,14 +102,29 @@ static int SDLCALL windows_file_open(SDL_RWops *context, const char *filename, c { LPTSTR tstr = WIN_UTF8ToString(filename); - h = CreateFile(tstr, (w_right | r_right), - (w_right) ? 0 : FILE_SHARE_READ, NULL, +#if defined(__WINRT__) + CREATEFILE2_EXTENDED_PARAMETERS extparams; + SDL_zero(extparams); + extparams.dwSize = sizeof(extparams); + extparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + h = CreateFile2(tstr, + (w_right | r_right), + (w_right) ? 0 : FILE_SHARE_READ, + (must_exist | truncate | a_mode), + &extparams); +#else + h = CreateFile(tstr, + (w_right | r_right), + (w_right) ? 0 : FILE_SHARE_READ, + NULL, (must_exist | truncate | a_mode), - FILE_ATTRIBUTE_NORMAL, NULL); + FILE_ATTRIBUTE_NORMAL, + NULL); +#endif SDL_free(tstr); } -#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) && !defined(__WINRT__) /* restore old behavior */ SetErrorMode(old_error_mode); #endif @@ -135,10 +145,6 @@ static Sint64 SDLCALL windows_file_size(SDL_RWops *context) { LARGE_INTEGER size; - if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { - return SDL_SetError("windows_file_size: invalid context/file not opened"); - } - if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) { return WIN_SetError("windows_file_size"); } @@ -151,13 +157,9 @@ static Sint64 SDLCALL windows_file_seek(SDL_RWops *context, Sint64 offset, int w DWORD windowswhence; LARGE_INTEGER windowsoffset; - if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { - return SDL_SetError("windows_file_seek: invalid context/file not opened"); - } - /* FIXME: We may be able to satisfy the seek within buffered data */ if (whence == SDL_RW_SEEK_CUR && context->hidden.windowsio.buffer.left) { - offset -= (long)context->hidden.windowsio.buffer.left; + offset -= context->hidden.windowsio.buffer.left; } context->hidden.windowsio.buffer.left = 0; @@ -182,27 +184,18 @@ static Sint64 SDLCALL windows_file_seek(SDL_RWops *context, Sint64 offset, int w return windowsoffset.QuadPart; } -static Sint64 SDLCALL -windows_file_read(SDL_RWops *context, void *ptr, Sint64 size) +static size_t SDLCALL windows_file_read(SDL_RWops *context, void *ptr, size_t size) { - size_t total_need = (size_t) size; + size_t total_need = size; size_t total_read = 0; size_t read_ahead; - DWORD byte_read; - - if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { - return SDL_SetError("Invalid file handle"); - } else if (!total_need) { - return 0; - } - + DWORD bytes; 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; - read_ahead = - SDL_min(total_need, context->hidden.windowsio.buffer.left); + read_ahead = SDL_min(total_need, context->hidden.windowsio.buffer.left); SDL_memcpy(ptr, data, read_ahead); context->hidden.windowsio.buffer.left -= read_ahead; @@ -216,39 +209,37 @@ windows_file_read(SDL_RWops *context, void *ptr, Sint64 size) if (total_need < READAHEAD_BUFFER_SIZE) { if (!ReadFile(context->hidden.windowsio.h, context->hidden.windowsio.buffer.data, - READAHEAD_BUFFER_SIZE, &byte_read, NULL)) { - return SDL_Error(SDL_EFREAD); + READAHEAD_BUFFER_SIZE, &bytes, NULL)) { + SDL_Error(SDL_EFREAD); + return 0; } - read_ahead = SDL_min(total_need, (int)byte_read); + read_ahead = SDL_min(total_need, bytes); 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; + context->hidden.windowsio.buffer.size = bytes; + context->hidden.windowsio.buffer.left = bytes - read_ahead; total_read += read_ahead; } else { - if (!ReadFile(context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) { - return SDL_Error(SDL_EFREAD); + if (!ReadFile(context->hidden.windowsio.h, ptr, (DWORD)total_need, &bytes, NULL)) { + SDL_Error(SDL_EFREAD); + return 0; } - total_read += byte_read; + total_read += bytes; } return total_read; } -static Sint64 SDLCALL -windows_file_write(SDL_RWops *context, const void *ptr, Sint64 size) +static size_t SDLCALL windows_file_write(SDL_RWops *context, const void *ptr, size_t size) { - const size_t total_bytes = (size_t) size; - DWORD byte_written; - - if (context == NULL || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { - return SDL_SetError("Invalid file handle"); - } else if (!total_bytes) { - return 0; - } + const size_t total_bytes = size; + DWORD bytes; if (context->hidden.windowsio.buffer.left) { - SetFilePointer(context->hidden.windowsio.h, + if (!SetFilePointer(context->hidden.windowsio.h, -(LONG)context->hidden.windowsio.buffer.left, NULL, - FILE_CURRENT); + FILE_CURRENT)) { + SDL_Error(SDL_EFSEEK); + return 0; + } context->hidden.windowsio.buffer.left = 0; } @@ -257,28 +248,30 @@ windows_file_write(SDL_RWops *context, const void *ptr, Sint64 size) LARGE_INTEGER windowsoffset; windowsoffset.QuadPart = 0; if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, FILE_END)) { - return SDL_Error(SDL_EFWRITE); + SDL_Error(SDL_EFSEEK); + return 0; } } - if (!WriteFile(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) { - return SDL_Error(SDL_EFWRITE); + if (!WriteFile(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &bytes, NULL)) { + SDL_Error(SDL_EFWRITE); + return 0; } - return (Sint64) byte_written; + return bytes; } 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 */ - } + if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) { + CloseHandle(context->hidden.windowsio.h); + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */ + } + if (context->hidden.windowsio.buffer.data) { SDL_free(context->hidden.windowsio.buffer.data); context->hidden.windowsio.buffer.data = NULL; - SDL_DestroyRW(context); } + SDL_DestroyRW(context); return 0; } #endif /* defined(__WIN32__) || defined(__GDK__) */ @@ -323,20 +316,6 @@ static int SDLCALL windows_file_close(SDL_RWops *context) #define fseek_off_t long #endif -static Sint64 SDLCALL stdio_size(SDL_RWops *context) -{ - Sint64 pos, size; - - pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR); - if (pos < 0) { - return -1; - } - size = SDL_RWseek(context, 0, SDL_RW_SEEK_END); - - SDL_RWseek(context, pos, SDL_RW_SEEK_SET); - return size; -} - static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence) { int stdiowhence; @@ -371,41 +350,37 @@ static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence) return SDL_Error(SDL_EFSEEK); } -static Sint64 SDLCALL -stdio_read(SDL_RWops *context, void *ptr, Sint64 size) +static size_t SDLCALL stdio_read(SDL_RWops *context, void *ptr, size_t size) { - size_t nread; + size_t bytes; - nread = fread(ptr, 1, (size_t)size, (FILE *)context->hidden.stdio.fp); - if (nread == 0 && ferror((FILE *)context->hidden.stdio.fp)) { - return SDL_Error(SDL_EFREAD); + bytes = fread(ptr, 1, size, (FILE *)context->hidden.stdio.fp); + if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) { + SDL_Error(SDL_EFREAD); } - return (Sint64) nread; + return bytes; } -static Sint64 SDLCALL -stdio_write(SDL_RWops *context, const void *ptr, Sint64 size) +static size_t SDLCALL stdio_write(SDL_RWops *context, const void *ptr, size_t size) { - size_t nwrote; + size_t bytes; - nwrote = fwrite(ptr, 1, (size_t)size, (FILE *)context->hidden.stdio.fp); - if (nwrote == 0 && ferror((FILE *)context->hidden.stdio.fp)) { - return SDL_Error(SDL_EFWRITE); + bytes = fwrite(ptr, 1, size, (FILE *)context->hidden.stdio.fp); + if (bytes == 0 && ferror((FILE *)context->hidden.stdio.fp)) { + SDL_Error(SDL_EFWRITE); } - return (Sint64) nwrote; + return bytes; } static int SDLCALL stdio_close(SDL_RWops *context) { int status = 0; - if (context) { - if (context->hidden.stdio.autoclose) { - if (fclose((FILE *)context->hidden.stdio.fp) != 0) { - status = SDL_Error(SDL_EFWRITE); - } + if (context->hidden.stdio.autoclose) { + if (fclose((FILE *)context->hidden.stdio.fp) != 0) { + status = SDL_Error(SDL_EFWRITE); } - SDL_DestroyRW(context); } + SDL_DestroyRW(context); return status; } @@ -415,7 +390,6 @@ static SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose) rwops = SDL_CreateRW(); if (rwops != NULL) { - rwops->size = stdio_size; rwops->seek = stdio_seek; rwops->read = stdio_read; rwops->write = stdio_write; @@ -432,7 +406,7 @@ static SDL_RWops *SDL_RWFromFP(void *fp, SDL_bool autoclose) static Sint64 SDLCALL mem_size(SDL_RWops *context) { - return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base); + return (context->hidden.mem.stop - context->hidden.mem.base); } static Sint64 SDLCALL mem_seek(SDL_RWops *context, Sint64 offset, int whence) @@ -462,43 +436,27 @@ static Sint64 SDLCALL mem_seek(SDL_RWops *context, Sint64 offset, int whence) return (Sint64)(context->hidden.mem.here - context->hidden.mem.base); } -static Sint64 mem_io(SDL_RWops *context, void *dst, const void *src, Sint64 size) +static size_t mem_io(SDL_RWops *context, void *dst, const void *src, size_t size) { - const Sint64 mem_available = (Sint64) (context->hidden.mem.stop - context->hidden.mem.here); + const size_t mem_available = (context->hidden.mem.stop - context->hidden.mem.here); if (size > mem_available) { size = mem_available; } - SDL_memcpy(dst, src, (size_t) size); + SDL_memcpy(dst, src, size); context->hidden.mem.here += size; return size; } -static Sint64 SDLCALL -mem_read(SDL_RWops *context, void *ptr, Sint64 size) +static size_t SDLCALL mem_read(SDL_RWops *context, void *ptr, size_t size) { return mem_io(context, ptr, context->hidden.mem.here, size); } -static Sint64 SDLCALL -mem_write(SDL_RWops *context, const void *ptr, Sint64 size) +static size_t SDLCALL mem_write(SDL_RWops *context, const void *ptr, size_t size) { return mem_io(context, context->hidden.mem.here, ptr, size); } -static Sint64 SDLCALL -mem_writeconst(SDL_RWops *context, const void *ptr, Sint64 size) -{ - return SDL_SetError("Can't write to read-only memory"); -} - -static int SDLCALL mem_close(SDL_RWops *context) -{ - if (context) { - SDL_DestroyRW(context); - } - return 0; -} - /* Functions to create SDL_RWops structures from various data sources */ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) @@ -552,7 +510,7 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) rwops->close = Android_JNI_FileClose; rwops->type = SDL_RWOPS_JNIFILE; -#elif defined(__WIN32__) || defined(__GDK__) +#elif defined(__WIN32__) || defined(__GDK__) || defined(__WINRT__) rwops = SDL_CreateRW(); if (rwops == NULL) { return NULL; /* SDL_SetError already setup by SDL_CreateRW() */ @@ -596,13 +554,14 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) SDL_RWops *SDL_RWFromMem(void *mem, size_t size) { SDL_RWops *rwops = NULL; + if (mem == NULL) { SDL_InvalidParamError("mem"); - return rwops; + return NULL; } if (!size) { SDL_InvalidParamError("size"); - return rwops; + return NULL; } rwops = SDL_CreateRW(); @@ -611,7 +570,6 @@ SDL_RWops *SDL_RWFromMem(void *mem, size_t 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.here = rwops->hidden.mem.base; rwops->hidden.mem.stop = rwops->hidden.mem.base + size; @@ -623,13 +581,14 @@ SDL_RWops *SDL_RWFromMem(void *mem, size_t size) SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size) { SDL_RWops *rwops = NULL; + if (mem == NULL) { SDL_InvalidParamError("mem"); - return rwops; + return NULL; } if (!size) { SDL_InvalidParamError("size"); - return rwops; + return NULL; } rwops = SDL_CreateRW(); @@ -637,8 +596,6 @@ SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size) 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.here = rwops->hidden.mem.base; rwops->hidden.mem.stop = rwops->hidden.mem.base + size; @@ -649,29 +606,30 @@ SDL_RWops *SDL_RWFromConstMem(const void *mem, size_t size) SDL_RWops *SDL_CreateRW(void) { - SDL_RWops *area; + SDL_RWops *context; - area = (SDL_RWops *)SDL_malloc(sizeof(*area)); - if (area == NULL) { + context = (SDL_RWops *)SDL_calloc(1, sizeof(*context)); + if (context == NULL) { SDL_OutOfMemory(); } else { - area->type = SDL_RWOPS_UNKNOWN; + context->type = SDL_RWOPS_UNKNOWN; } - return area; + return context; } -void SDL_DestroyRW(SDL_RWops *area) +void SDL_DestroyRW(SDL_RWops *context) { - SDL_free(area); + SDL_free(context); } /* Load all the data from an SDL data stream */ void *SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc) { - static const Sint64 FILE_CHUNK_SIZE = 1024; - Sint64 size; - Sint64 size_read, size_total; - void *data = NULL, *newdata; + const int FILE_CHUNK_SIZE = 1024; + Sint64 size, size_total; + size_t size_read; + char *data = NULL, *newdata; + SDL_bool loading_chunks = SDL_FALSE; if (src == NULL) { SDL_InvalidParamError("src"); @@ -681,46 +639,52 @@ void *SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, SDL_bool freesrc) size = SDL_RWsize(src); if (size < 0) { size = FILE_CHUNK_SIZE; + loading_chunks = SDL_TRUE; + } + if (size >= SDL_SIZE_MAX) { + SDL_OutOfMemory(); + goto done; + } + data = (char *)SDL_malloc((size_t)(size + 1)); + if (!data) { + SDL_OutOfMemory(); + goto done; } - data = SDL_malloc((size_t)(size + 1)); size_total = 0; for (;;) { - if ((size_total + FILE_CHUNK_SIZE) > size) { - size = (size_total + FILE_CHUNK_SIZE); - newdata = SDL_realloc(data, (size_t)(size + 1)); - if (newdata == NULL) { - SDL_free(data); - data = NULL; - SDL_OutOfMemory(); - goto done; + if (loading_chunks) { + if ((size_total + FILE_CHUNK_SIZE) > size) { + size = (size_total + FILE_CHUNK_SIZE); + if (size >= SDL_SIZE_MAX) { + newdata = NULL; + } else { + newdata = SDL_realloc(data, (size_t)(size + 1)); + } + if (newdata == NULL) { + SDL_free(data); + data = NULL; + SDL_OutOfMemory(); + goto done; + } + data = newdata; } - data = newdata; } - size_read = SDL_RWread(src, (char *)data + size_total, size - size_total); + size_read = SDL_RWread(src, data + size_total, (size_t)(size - size_total)); if (size_read > 0) { size_total += size_read; continue; } - if (size_read == 0) { - /* End of file */ - break; - } - if (size_read == -2) { - /* Non-blocking I/O, should we wait here? */ - } - /* Read error */ - SDL_free(data); - data = NULL; - goto done; + /* The stream status will remain set for the caller to check */ + break; } if (datasize) { - *datasize = (size_t) size_total; + *datasize = (size_t)size_total; } - ((char *)data)[size_total] = '\0'; + data[size_total] = '\0'; done: if (freesrc && src) { @@ -731,134 +695,314 @@ done: 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, SDL_TRUE); } Sint64 SDL_RWsize(SDL_RWops *context) { + if (!context) { + return SDL_InvalidParamError("context"); + } + if (!context->size) { + Sint64 pos, size; + + pos = SDL_RWseek(context, 0, SDL_RW_SEEK_CUR); + if (pos < 0) { + return -1; + } + size = SDL_RWseek(context, 0, SDL_RW_SEEK_END); + + SDL_RWseek(context, pos, SDL_RW_SEEK_SET); + return size; + } return context->size(context); } Sint64 SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence) { + if (!context) { + return SDL_InvalidParamError("context"); + } + if (!context->seek) { + return SDL_Unsupported(); + } return context->seek(context, offset, whence); } Sint64 SDL_RWtell(SDL_RWops *context) { - return context->seek(context, 0, SDL_RW_SEEK_CUR); + return SDL_RWseek(context, 0, SDL_RW_SEEK_CUR); } -Sint64 SDL_RWread(SDL_RWops *context, void *ptr, Sint64 size) +size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size) { - return context->read(context, ptr, size); + size_t bytes; + + if (!context) { + SDL_InvalidParamError("context"); + return 0; + } + if (!context->read) { + context->status = SDL_RWOPS_STATUS_WRITEONLY; + SDL_Unsupported(); + return 0; + } + + context->status = SDL_RWOPS_STATUS_READY; + SDL_ClearError(); + + if (size == 0) { + return 0; + } + + bytes = context->read(context, ptr, size); + if (bytes == 0 && context->status == SDL_RWOPS_STATUS_READY) { + if (*SDL_GetError()) { + context->status = SDL_RWOPS_STATUS_ERROR; + } else { + context->status = SDL_RWOPS_STATUS_EOF; + } + } + return bytes; } -Sint64 SDL_RWwrite(SDL_RWops *context, const void *ptr, Sint64 size) +size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size) { - return context->write(context, ptr, size); + size_t bytes; + + if (!context) { + SDL_InvalidParamError("context"); + return 0; + } + if (!context->write) { + context->status = SDL_RWOPS_STATUS_READONLY; + SDL_Unsupported(); + return 0; + } + + context->status = SDL_RWOPS_STATUS_READY; + SDL_ClearError(); + + if (size == 0) { + return 0; + } + + bytes = context->write(context, ptr, size); + if (bytes == 0 && context->status == SDL_RWOPS_STATUS_READY) { + context->status = SDL_RWOPS_STATUS_ERROR; + } + return bytes; } int SDL_RWclose(SDL_RWops *context) { + if (!context) { + return SDL_InvalidParamError("context"); + } + if (!context->close) { + SDL_DestroyRW(context); + return 0; + } return context->close(context); } /* Functions for dynamically reading and writing endian-specific values */ -Uint8 SDL_ReadU8(SDL_RWops *src) +SDL_bool SDL_ReadU8(SDL_RWops *src, Uint8 *value) { - Uint8 value = 0; + Uint8 data = 0; + SDL_bool result = SDL_FALSE; - SDL_RWread(src, &value, sizeof(value)); - return value; + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = data; + } + return result; } -Uint16 SDL_ReadLE16(SDL_RWops *src) +SDL_bool SDL_ReadU16LE(SDL_RWops *src, Uint16 *value) { - Uint16 value = 0; + Uint16 data = 0; + SDL_bool result = SDL_FALSE; - SDL_RWread(src, &value, sizeof(value)); - return SDL_SwapLE16(value); + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = SDL_SwapLE16(data); + } + return result; } -Uint16 SDL_ReadBE16(SDL_RWops *src) +SDL_bool SDL_ReadS16LE(SDL_RWops *src, Sint16 *value) { - Uint16 value = 0; - - SDL_RWread(src, &value, sizeof(value)); - return SDL_SwapBE16(value); + return SDL_ReadU16LE(src, (Uint16 *)value); } -Uint32 SDL_ReadLE32(SDL_RWops *src) +SDL_bool SDL_ReadU16BE(SDL_RWops *src, Uint16 *value) { - Uint32 value = 0; + Uint16 data = 0; + SDL_bool result = SDL_FALSE; - SDL_RWread(src, &value, sizeof(value)); - return SDL_SwapLE32(value); + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = SDL_SwapBE16(data); + } + return result; } -Uint32 SDL_ReadBE32(SDL_RWops *src) +SDL_bool SDL_ReadS16BE(SDL_RWops *src, Sint16 *value) { - Uint32 value = 0; - - SDL_RWread(src, &value, sizeof(value)); - return SDL_SwapBE32(value); + return SDL_ReadU16BE(src, (Uint16 *)value); } -Uint64 SDL_ReadLE64(SDL_RWops *src) +SDL_bool SDL_ReadU32LE(SDL_RWops *src, Uint32 *value) { - Uint64 value = 0; + Uint32 data = 0; + SDL_bool result = SDL_FALSE; - SDL_RWread(src, &value, sizeof(value)); - return SDL_SwapLE64(value); + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = SDL_SwapLE32(data); + } + return result; } -Uint64 SDL_ReadBE64(SDL_RWops *src) +SDL_bool SDL_ReadS32LE(SDL_RWops *src, Sint32 *value) { - Uint64 value = 0; - - SDL_RWread(src, &value, sizeof(value)); - return SDL_SwapBE64(value); + return SDL_ReadU32LE(src, (Uint32 *)value); } -size_t SDL_WriteU8(SDL_RWops *dst, Uint8 value) +SDL_bool SDL_ReadU32BE(SDL_RWops *src, Uint32 *value) { - return (SDL_RWwrite(dst, &value, sizeof(value)) == sizeof(value)) ? 1 : 0; + Uint32 data = 0; + SDL_bool result = SDL_FALSE; + + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = SDL_SwapBE32(data); + } + return result; } -size_t SDL_WriteLE16(SDL_RWops *dst, Uint16 value) +SDL_bool SDL_ReadS32BE(SDL_RWops *src, Sint32 *value) +{ + return SDL_ReadU32BE(src, (Uint32 *)value); +} + +SDL_bool SDL_ReadU64LE(SDL_RWops *src, Uint64 *value) +{ + Uint64 data = 0; + SDL_bool result = SDL_FALSE; + + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = SDL_SwapLE64(data); + } + return result; +} + +SDL_bool SDL_ReadS64LE(SDL_RWops *src, Sint64 *value) +{ + return SDL_ReadU64LE(src, (Uint64 *)value); +} + +SDL_bool SDL_ReadU64BE(SDL_RWops *src, Uint64 *value) +{ + Uint64 data = 0; + SDL_bool result = SDL_FALSE; + + if (SDL_RWread(src, &data, sizeof(data)) == sizeof(data)) { + result = SDL_TRUE; + } + if (value) { + *value = SDL_SwapBE64(data); + } + return result; +} + +SDL_bool SDL_ReadS64BE(SDL_RWops *src, Sint64 *value) +{ + return SDL_ReadU64BE(src, (Uint64 *)value); +} + +SDL_bool SDL_WriteU8(SDL_RWops *dst, Uint8 value) +{ + return (SDL_RWwrite(dst, &value, sizeof(value)) == sizeof(value)) ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_WriteU16LE(SDL_RWops *dst, Uint16 value) { const Uint16 swapped = SDL_SwapLE16(value); - return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0; + return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE; } -size_t SDL_WriteBE16(SDL_RWops *dst, Uint16 value) +SDL_bool SDL_WriteS16LE(SDL_RWops *dst, Sint16 value) +{ + return SDL_WriteU16LE(dst, (Uint16)value); +} + +SDL_bool SDL_WriteU16BE(SDL_RWops *dst, Uint16 value) { const Uint16 swapped = SDL_SwapBE16(value); - return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0; + return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE; } -size_t SDL_WriteLE32(SDL_RWops *dst, Uint32 value) +SDL_bool SDL_WriteS16BE(SDL_RWops *dst, Sint16 value) +{ + return SDL_WriteU16BE(dst, (Uint16)value); +} + +SDL_bool SDL_WriteU32LE(SDL_RWops *dst, Uint32 value) { const Uint32 swapped = SDL_SwapLE32(value); - return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0; + return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE; } -size_t SDL_WriteBE32(SDL_RWops *dst, Uint32 value) +SDL_bool SDL_WriteS32LE(SDL_RWops *dst, Sint32 value) +{ + return SDL_WriteU32LE(dst, (Uint32)value); +} + +SDL_bool SDL_WriteU32BE(SDL_RWops *dst, Uint32 value) { const Uint32 swapped = SDL_SwapBE32(value); - return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0; + return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE; } -size_t SDL_WriteLE64(SDL_RWops *dst, Uint64 value) +SDL_bool SDL_WriteS32BE(SDL_RWops *dst, Sint32 value) +{ + return SDL_WriteU32BE(dst, (Uint32)value); +} + +SDL_bool SDL_WriteU64LE(SDL_RWops *dst, Uint64 value) { const Uint64 swapped = SDL_SwapLE64(value); - return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0; + return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE; } -size_t SDL_WriteBE64(SDL_RWops *dst, Uint64 value) +SDL_bool SDL_WriteS64LE(SDL_RWops *dst, Sint64 value) +{ + return SDL_WriteU64LE(dst, (Uint64)value); +} + +SDL_bool SDL_WriteU64BE(SDL_RWops *dst, Uint64 value) { const Uint64 swapped = SDL_SwapBE64(value); - return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? 1 : 0; + return (SDL_RWwrite(dst, &swapped, sizeof(swapped)) == sizeof(swapped)) ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_WriteS64BE(SDL_RWops *dst, Sint64 value) +{ + return SDL_WriteU64BE(dst, (Uint64)value); } diff --git a/src/filesystem/android/SDL_sysfilesystem.c b/src/filesystem/android/SDL_sysfilesystem.c index 2a5ed9e5..d14f7892 100644 --- a/src/filesystem/android/SDL_sysfilesystem.c +++ b/src/filesystem/android/SDL_sysfilesystem.c @@ -50,7 +50,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) return NULL; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { /* TODO: see https://developer.android.com/reference/android/os/Environment#lfields and https://stackoverflow.com/questions/39332085/get-path-to-pictures-directory */ diff --git a/src/filesystem/cocoa/SDL_sysfilesystem.m b/src/filesystem/cocoa/SDL_sysfilesystem.m index c644495c..0a78a2d9 100644 --- a/src/filesystem/cocoa/SDL_sysfilesystem.m +++ b/src/filesystem/cocoa/SDL_sysfilesystem.m @@ -130,7 +130,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) } } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { @autoreleasepool { #if TARGET_OS_TV diff --git a/src/filesystem/dummy/SDL_sysfilesystem.c b/src/filesystem/dummy/SDL_sysfilesystem.c index 58c91a37..197284cf 100644 --- a/src/filesystem/dummy/SDL_sysfilesystem.c +++ b/src/filesystem/dummy/SDL_sysfilesystem.c @@ -37,7 +37,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) return NULL; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/emscripten/SDL_sysfilesystem.c b/src/filesystem/emscripten/SDL_sysfilesystem.c index a3736374..389eff08 100644 --- a/src/filesystem/emscripten/SDL_sysfilesystem.c +++ b/src/filesystem/emscripten/SDL_sysfilesystem.c @@ -83,7 +83,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) return retval; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { const char *home = NULL; char *retval; diff --git a/src/filesystem/haiku/SDL_sysfilesystem.cc b/src/filesystem/haiku/SDL_sysfilesystem.cc index 07e53766..466a2576 100644 --- a/src/filesystem/haiku/SDL_sysfilesystem.cc +++ b/src/filesystem/haiku/SDL_sysfilesystem.cc @@ -97,7 +97,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) return retval; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { const char *home = NULL; char *retval; diff --git a/src/filesystem/n3ds/SDL_sysfilesystem.c b/src/filesystem/n3ds/SDL_sysfilesystem.c index 27fc16e7..7bde8310 100644 --- a/src/filesystem/n3ds/SDL_sysfilesystem.c +++ b/src/filesystem/n3ds/SDL_sysfilesystem.c @@ -60,7 +60,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) } /* TODO */ -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/ps2/SDL_sysfilesystem.c b/src/filesystem/ps2/SDL_sysfilesystem.c index 0636fce2..b52fdea3 100644 --- a/src/filesystem/ps2/SDL_sysfilesystem.c +++ b/src/filesystem/ps2/SDL_sysfilesystem.c @@ -103,7 +103,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) } /* TODO */ -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/psp/SDL_sysfilesystem.c b/src/filesystem/psp/SDL_sysfilesystem.c index 3fdd7192..239e6743 100644 --- a/src/filesystem/psp/SDL_sysfilesystem.c +++ b/src/filesystem/psp/SDL_sysfilesystem.c @@ -70,7 +70,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) } /* TODO */ -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/riscos/SDL_sysfilesystem.c b/src/filesystem/riscos/SDL_sysfilesystem.c index 37b19cbd..17d6625b 100644 --- a/src/filesystem/riscos/SDL_sysfilesystem.c +++ b/src/filesystem/riscos/SDL_sysfilesystem.c @@ -200,7 +200,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) } /* TODO */ -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/unix/SDL_sysfilesystem.c b/src/filesystem/unix/SDL_sysfilesystem.c index 145c0308..88a3a353 100644 --- a/src/filesystem/unix/SDL_sysfilesystem.c +++ b/src/filesystem/unix/SDL_sysfilesystem.c @@ -517,7 +517,7 @@ static char *xdg_user_dir_lookup (const char *type) return NULL; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { const char *param = NULL; char *retval; diff --git a/src/filesystem/vita/SDL_sysfilesystem.c b/src/filesystem/vita/SDL_sysfilesystem.c index a99a1747..836416ab 100644 --- a/src/filesystem/vita/SDL_sysfilesystem.c +++ b/src/filesystem/vita/SDL_sysfilesystem.c @@ -84,7 +84,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) } /* TODO */ -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/windows/SDL_sysfilesystem.c b/src/filesystem/windows/SDL_sysfilesystem.c index 59370d2c..2dffe4c2 100644 --- a/src/filesystem/windows/SDL_sysfilesystem.c +++ b/src/filesystem/windows/SDL_sysfilesystem.c @@ -177,7 +177,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) return retval; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { typedef HRESULT (WINAPI *pfnSHGetKnownFolderPath)(REFGUID /* REFKNOWNFOLDERID */, DWORD, HANDLE, PWSTR*); HMODULE lib = LoadLibrary(L"Shell32.dll"); @@ -346,7 +346,7 @@ char *SDL_GetPrefPath(const char *org, const char *app) return NULL; } -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/filesystem/winrt/SDL_sysfilesystem.cpp b/src/filesystem/winrt/SDL_sysfilesystem.cpp index 33218c60..a5e85b4a 100644 --- a/src/filesystem/winrt/SDL_sysfilesystem.cpp +++ b/src/filesystem/winrt/SDL_sysfilesystem.cpp @@ -233,7 +233,7 @@ SDL_GetPrefPath(const char *org, const char *app) } /* TODO */ -char *SDL_GetPath(SDL_Folder folder) +char *SDL_GetUserFolder(SDL_Folder folder) { SDL_Unsupported(); return NULL; diff --git a/src/hidapi/ios/hid.m b/src/hidapi/ios/hid.m index 024aabdc..eef4297a 100644 --- a/src/hidapi/ios/hid.m +++ b/src/hidapi/ios/hid.m @@ -20,6 +20,8 @@ */ #include "SDL_internal.h" +#if defined(__IOS__) || defined(__TVOS__) + #ifndef SDL_HIDAPI_DISABLED #include "../SDL_hidapi_c.h" @@ -1031,3 +1033,5 @@ HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev) } #endif /* !SDL_HIDAPI_DISABLED */ + +#endif /* __IOS__ || __TVOS__ */ diff --git a/src/hidapi/windows/hidapi_descriptor_reconstruct.h b/src/hidapi/windows/hidapi_descriptor_reconstruct.h index b19d53fc..5f0b54aa 100644 --- a/src/hidapi/windows/hidapi_descriptor_reconstruct.h +++ b/src/hidapi/windows/hidapi_descriptor_reconstruct.h @@ -31,6 +31,7 @@ #pragma warning(push) #pragma warning(disable: 4200) #pragma warning(disable: 4201) +#pragma warning(disable: 4214) #endif #include @@ -118,9 +119,9 @@ typedef struct hid_pp_link_collection_node_ { USHORT NumberOfChildren; USHORT NextSibling; USHORT FirstChild; - UINT CollectionType : 8; - UINT IsAlias : 1; - UINT Reserved : 23; + ULONG CollectionType : 8; + ULONG IsAlias : 1; + ULONG Reserved : 23; // Same as the public API structure HIDP_LINK_COLLECTION_NODE, but without PVOID UserContext at the end } hid_pp_link_collection_node, *phid_pp_link_collection_node; @@ -145,17 +146,17 @@ typedef struct hid_pp_cap_ { USAGE LinkUsage; // Start of 8 Flags in one byte - UINT IsMultipleItemsForArray:1; + BOOLEAN IsMultipleItemsForArray:1; - UINT IsPadding:1; - UINT IsButtonCap:1; - UINT IsAbsolute:1; - UINT IsRange:1; - UINT IsAlias:1; // IsAlias is set to TRUE in the first n-1 capability structures added to the capability array. IsAlias set to FALSE in the nth capability structure. - UINT IsStringRange:1; - UINT IsDesignatorRange:1; + BOOLEAN IsPadding:1; + BOOLEAN IsButtonCap:1; + BOOLEAN IsAbsolute:1; + BOOLEAN IsRange:1; + BOOLEAN IsAlias:1; // IsAlias is set to TRUE in the first n-1 capability structures added to the capability array. IsAlias set to FALSE in the nth capability structure. + BOOLEAN IsStringRange:1; + BOOLEAN IsDesignatorRange:1; // End of 8 Flags in one byte - //BOOLEAN Reserved1[3]; + BOOLEAN Reserved1[3]; hidp_unknown_token UnknownTokens[4]; // 4 x 8 Byte diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index a8dbec34..00b6e928 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -362,6 +362,8 @@ void SDL_PrivateGamepadRemoved(SDL_JoystickID instance_id) SDL_Event event; SDL_Gamepad *gamepad; + SDL_AssertJoysticksLocked(); + if (!SDL_gamepads_initialized) { return; } @@ -466,6 +468,8 @@ static void AdjustSensorOrientation(SDL_Joystick *joystick, float *src, float *d { unsigned int i, j; + SDL_AssertJoysticksLocked(); + for (i = 0; i < 3; ++i) { dst[i] = 0.0f; for (j = 0; j < 3; ++j) { @@ -559,6 +563,8 @@ static SDL_bool HasMappingChangeTracking(MappingChangeTracker *tracker, GamepadM { int i; + SDL_AssertJoysticksLocked(); + for (i = 0; i < tracker->num_changed_mappings; ++i) { if (tracker->changed_mappings[i] == mapping) { return SDL_TRUE; @@ -746,6 +752,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_JoystickGUID guid 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; @@ -1653,10 +1660,12 @@ static GamepadMapping_t *SDL_PrivateGenerateAutomaticGamepadMapping(const char * 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); + /* Keep using paddle1-4 in the generated mapping so that it can be + * reused with SDL2 */ + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle1", &raw_map->right_paddle1); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle2", &raw_map->left_paddle1); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle3", &raw_map->right_paddle2); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle4", &raw_map->left_paddle2); 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); @@ -1693,40 +1702,18 @@ static GamepadMapping_t *SDL_PrivateGetGamepadMapping(SDL_JoystickID instance_id /* * Add or update an entry into the Mappings Database */ -int SDL_AddGamepadMappingsFromRW(SDL_RWops *src, int freesrc) +int SDL_AddGamepadMappingsFromRW(SDL_RWops *src, SDL_bool freesrc) { const char *platform = SDL_GetPlatform(); int gamepads = 0; char *buf, *line, *line_end, *tmp, *comma, line_platform[64]; - Sint64 db_size; + size_t db_size; size_t platform_len; - if (src == NULL) { - return SDL_InvalidParamError("src"); - } - db_size = SDL_RWsize(src); - - buf = (char *)SDL_malloc((size_t)db_size + 1); + buf = (char *)SDL_LoadFile_RW(src, &db_size, freesrc); if (buf == NULL) { - if (freesrc) { - SDL_RWclose(src); - } return SDL_SetError("Could not allocate space to read DB into memory"); } - - if (SDL_RWread(src, buf, db_size) != db_size) { - if (freesrc) { - SDL_RWclose(src); - } - SDL_free(buf); - return SDL_SetError("Could not read DB"); - } - - if (freesrc) { - SDL_RWclose(src); - } - - buf[db_size] = '\0'; line = buf; PushMappingChangeTracking(); diff --git a/src/joystick/SDL_gamepad_db.h b/src/joystick/SDL_gamepad_db.h index 3f696fd9..00e6a244 100644 --- a/src/joystick/SDL_gamepad_db.h +++ b/src/joystick/SDL_gamepad_db.h @@ -134,6 +134,7 @@ static const char *s_GamepadMappings[] = { "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,", + "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,", @@ -815,6 +816,7 @@ static const char *s_GamepadMappings[] = { "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,", "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,", diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 9702a936..4b6ff4cf 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -150,26 +150,33 @@ void SDL_LockJoysticks(void) void SDL_UnlockJoysticks(void) { - SDL_Mutex *joystick_lock = SDL_joystick_lock; SDL_bool last_unlock = SDL_FALSE; --SDL_joysticks_locked; if (!SDL_joysticks_initialized) { + /* NOTE: There's a small window here where another thread could lock the mutex after we've checked for pending locks */ 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_Mutex *joystick_lock = SDL_joystick_lock; + + SDL_LockMutex(joystick_lock); + { + SDL_UnlockMutex(SDL_joystick_lock); + + SDL_joystick_lock = NULL; + } + SDL_UnlockMutex(joystick_lock); SDL_DestroyMutex(joystick_lock); + } else { + SDL_UnlockMutex(SDL_joystick_lock); } } @@ -560,6 +567,8 @@ static SDL_bool ShouldAttemptSensorFusion(SDL_Joystick *joystick, SDL_bool *inve const char *hint; int hint_value; + SDL_AssertJoysticksLocked(); + *invert_sensors = SDL_FALSE; /* The SDL controller sensor API is only available for gamepads (at the moment) */ @@ -620,6 +629,8 @@ static void AttemptSensorFusion(SDL_Joystick *joystick, SDL_bool invert_sensors) SDL_SensorID *sensors; unsigned int i, j; + SDL_AssertJoysticksLocked(); + if (SDL_InitSubSystem(SDL_INIT_SENSOR) < 0) { return; } @@ -686,6 +697,8 @@ static void AttemptSensorFusion(SDL_Joystick *joystick, SDL_bool invert_sensors) static void CleanupSensorFusion(SDL_Joystick *joystick) { + SDL_AssertJoysticksLocked(); + if (joystick->accel_sensor || joystick->gyro_sensor) { if (joystick->accel_sensor) { if (joystick->accel) { @@ -1782,6 +1795,7 @@ int SDL_SendJoystickAxis(Uint64 timestamp, SDL_Joystick *joystick, Uint8 axis, S } /* Update internal joystick state */ + SDL_assert(timestamp != 0); info->value = value; joystick->update_complete = timestamp; @@ -1825,6 +1839,7 @@ int SDL_SendJoystickHat(Uint64 timestamp, SDL_Joystick *joystick, Uint8 hat, Uin } /* Update internal joystick state */ + SDL_assert(timestamp != 0); joystick->hats[hat] = value; joystick->update_complete = timestamp; @@ -1884,6 +1899,7 @@ int SDL_SendJoystickButton(Uint64 timestamp, SDL_Joystick *joystick, Uint8 butto } /* Update internal joystick state */ + SDL_assert(timestamp != 0); joystick->buttons[button] = state; joystick->update_complete = timestamp; @@ -1953,7 +1969,7 @@ void SDL_UpdateJoysticks(void) event.type = SDL_EVENT_JOYSTICK_UPDATE_COMPLETE; event.common.timestamp = joystick->update_complete; - event.gdevice.which = joystick->instance_id; + event.jdevice.which = joystick->instance_id; SDL_PushEvent(&event); joystick->update_complete = 0; @@ -3225,6 +3241,7 @@ int SDL_SendJoystickTouchpad(Uint64 timestamp, SDL_Joystick *joystick, int touch } /* Update internal joystick state */ + SDL_assert(timestamp != 0); finger_info->state = state; finger_info->x = x; finger_info->y = y; diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 6a4afaea..685fbebe 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -196,10 +196,10 @@ typedef struct SDL_GamepadMapping SDL_InputMapping dpleft; SDL_InputMapping dpright; SDL_InputMapping misc1; - SDL_InputMapping paddle1; - SDL_InputMapping paddle2; - SDL_InputMapping paddle3; - SDL_InputMapping paddle4; + SDL_InputMapping right_paddle1; + SDL_InputMapping left_paddle1; + SDL_InputMapping right_paddle2; + SDL_InputMapping left_paddle2; SDL_InputMapping leftx; SDL_InputMapping lefty; SDL_InputMapping rightx; diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index e51fcd96..d8acacc3 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -198,15 +198,16 @@ static SDL_Scancode button_to_scancode(int button) int Android_OnPadDown(int device_id, int keycode) { + Uint64 timestamp = SDL_GetTicksNS(); SDL_joylist_item *item; int button = keycode_to_SDL(keycode); if (button >= 0) { SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); if (item && item->joystick) { - SDL_SendJoystickButton(0, item->joystick, button, SDL_PRESSED); + SDL_SendJoystickButton(timestamp, item->joystick, button, SDL_PRESSED); } else { - SDL_SendKeyboardKey(0, SDL_PRESSED, button_to_scancode(button)); + SDL_SendKeyboardKey(timestamp, SDL_PRESSED, button_to_scancode(button)); } SDL_UnlockJoysticks(); return 0; @@ -217,15 +218,16 @@ int Android_OnPadDown(int device_id, int keycode) int Android_OnPadUp(int device_id, int keycode) { + Uint64 timestamp = SDL_GetTicksNS(); SDL_joylist_item *item; int button = keycode_to_SDL(keycode); if (button >= 0) { SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); if (item && item->joystick) { - SDL_SendJoystickButton(0, item->joystick, button, SDL_RELEASED); + SDL_SendJoystickButton(timestamp, item->joystick, button, SDL_RELEASED); } else { - SDL_SendKeyboardKey(0, SDL_RELEASED, button_to_scancode(button)); + SDL_SendKeyboardKey(timestamp, SDL_RELEASED, button_to_scancode(button)); } SDL_UnlockJoysticks(); return 0; @@ -236,13 +238,14 @@ int Android_OnPadUp(int device_id, int keycode) int Android_OnJoy(int device_id, int axis, float value) { + Uint64 timestamp = SDL_GetTicksNS(); /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */ SDL_joylist_item *item; SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); if (item && item->joystick) { - SDL_SendJoystickAxis(0, item->joystick, axis, (Sint16)(32767. * value)); + SDL_SendJoystickAxis(timestamp, item->joystick, axis, (Sint16)(32767. * value)); } SDL_UnlockJoysticks(); @@ -251,6 +254,7 @@ int Android_OnJoy(int device_id, int axis, float value) int Android_OnHat(int device_id, int hat_id, int x, int y) { + Uint64 timestamp = SDL_GetTicksNS(); const int DPAD_UP_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_UP); const int DPAD_DOWN_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_DOWN); const int DPAD_LEFT_MASK = (1 << SDL_GAMEPAD_BUTTON_DPAD_LEFT); @@ -278,16 +282,16 @@ int Android_OnHat(int device_id, int hat_id, int x, int y) dpad_delta = (dpad_state ^ item->dpad_state); if (dpad_delta) { if (dpad_delta & DPAD_UP_MASK) { - SDL_SendJoystickButton(0, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, (dpad_state & DPAD_UP_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, (dpad_state & DPAD_UP_MASK) ? SDL_PRESSED : SDL_RELEASED); } if (dpad_delta & DPAD_DOWN_MASK) { - SDL_SendJoystickButton(0, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, (dpad_state & DPAD_DOWN_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, (dpad_state & DPAD_DOWN_MASK) ? SDL_PRESSED : SDL_RELEASED); } if (dpad_delta & DPAD_LEFT_MASK) { - SDL_SendJoystickButton(0, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, (dpad_state & DPAD_LEFT_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, (dpad_state & DPAD_LEFT_MASK) ? SDL_PRESSED : SDL_RELEASED); } if (dpad_delta & DPAD_RIGHT_MASK) { - SDL_SendJoystickButton(0, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, (dpad_state & DPAD_RIGHT_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, item->joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, (dpad_state & DPAD_RIGHT_MASK) ? SDL_PRESSED : SDL_RELEASED); } item->dpad_state = dpad_state; } diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m index 5ed136b8..32f6f7ca 100644 --- a/src/joystick/apple/SDL_mfijoystick.m +++ b/src/joystick/apple/SDL_mfijoystick.m @@ -349,22 +349,24 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle } if (controller.physicalInputProfile.buttons[GCInputXboxPaddleOne] != nil) { device->has_xbox_paddles = SDL_TRUE; - device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_PADDLE1); + device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1); ++nbuttons; } if (controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo] != nil) { + /* TODO: Is this right? SDL_gamepad.h says P2 is the lower right */ device->has_xbox_paddles = SDL_TRUE; - device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_PADDLE2); + device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_LEFT_PADDLE1); ++nbuttons; } if (controller.physicalInputProfile.buttons[GCInputXboxPaddleThree] != nil) { + /* TODO: Is this right? SDL_gamepad.h says P3 is the upper left */ device->has_xbox_paddles = SDL_TRUE; - device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_PADDLE3); + device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2); ++nbuttons; } if (controller.physicalInputProfile.buttons[GCInputXboxPaddleFour] != nil) { device->has_xbox_paddles = SDL_TRUE; - device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_PADDLE4); + device->button_mask |= (1 << SDL_GAMEPAD_BUTTON_LEFT_PADDLE2); ++nbuttons; } if (controller.physicalInputProfile.buttons[GCInputXboxShareButton] != nil) { @@ -1055,16 +1057,16 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } if (joystick->hwdata->has_xbox_paddles) { - if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE1)) { + if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1)) { buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleOne].isPressed; } - if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE2)) { + if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_PADDLE1)) { buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo].isPressed; } - if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE3)) { + if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2)) { buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleThree].isPressed; } - if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE4)) { + if (joystick->hwdata->button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_PADDLE2)) { buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed; } @@ -1826,16 +1828,18 @@ const char *IOS_GetAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_Gamepad case SDL_GAMEPAD_BUTTON_MISC1: GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName); break; - case SDL_GAMEPAD_BUTTON_PADDLE1: + case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1: GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleOne], elementName); break; - case SDL_GAMEPAD_BUTTON_PADDLE2: + case SDL_GAMEPAD_BUTTON_LEFT_PADDLE1: + /* TODO: Is this right? SDL_gamepad.h says P2 is the lower right */ GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleTwo], elementName); break; - case SDL_GAMEPAD_BUTTON_PADDLE3: + case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2: + /* TODO: Is this right? SDL_gamepad.h says P3 is the upper left */ GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleThree], elementName); break; - case SDL_GAMEPAD_BUTTON_PADDLE4: + case SDL_GAMEPAD_BUTTON_LEFT_PADDLE2: GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleFour], elementName); break; case SDL_GAMEPAD_BUTTON_TOUCHPAD: diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h index 4c6f0913..0f6a589e 100644 --- a/src/joystick/controller_list.h +++ b/src/joystick/controller_list.h @@ -97,6 +97,7 @@ static const ControllerDescription_t arrControllers[] = { { 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, 0x005e ), k_eControllerType_PS4Controller, NULL }, // HORI Fighting Commander 4 PS4 { MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS4Controller, NULL }, // HORIPAD 4 FPS Plus @@ -148,6 +149,7 @@ static const ControllerDescription_t arrControllers[] = { { 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( 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) diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index aa64d1c0..47ea2904 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -694,20 +694,21 @@ static void HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device) static void HIDAPI_DriverPS4_SetEnhancedModeAvailable(SDL_DriverPS4_Context *ctx) { - if (!ctx->effects_supported) { - /* We shouldn't be sending any packets to the controller */ - return; - } - ctx->enhanced_mode_available = SDL_TRUE; if (ctx->touchpad_supported) { SDL_PrivateJoystickAddTouchpad(ctx->joystick, 2); + ctx->report_touchpad = SDL_TRUE; } + if (ctx->sensors_supported) { SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, 250.0f); SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, 250.0f); } + + if (ctx->device->is_bluetooth && ctx->official_controller) { + ctx->report_battery = SDL_TRUE; + } } static void HIDAPI_DriverPS4_SetEnhancedMode(SDL_DriverPS4_Context *ctx) @@ -716,17 +717,10 @@ static void HIDAPI_DriverPS4_SetEnhancedMode(SDL_DriverPS4_Context *ctx) HIDAPI_DriverPS4_SetEnhancedModeAvailable(ctx); } - if (!ctx->enhanced_mode && ctx->enhanced_mode_available) { + if (!ctx->enhanced_mode) { ctx->enhanced_mode = SDL_TRUE; - if (ctx->touchpad_supported) { - ctx->report_touchpad = SDL_TRUE; - } - - if (ctx->device->is_bluetooth && ctx->official_controller) { - ctx->report_battery = SDL_TRUE; - } - + /* Switch into enhanced report mode */ HIDAPI_DriverPS4_UpdateEffects(ctx, SDL_FALSE); } } @@ -888,12 +882,20 @@ static int HIDAPI_DriverPS4_InternalSendJoystickEffect(SDL_DriverPS4_Context *ct Uint8 data[78]; int report_size, offset; - if (application_usage) { - HIDAPI_DriverPS4_UpdateEnhancedModeOnApplicationUsage(ctx); + if (!ctx->effects_supported) { + /* We shouldn't be sending packets to this controller */ + return SDL_Unsupported(); } - if (!ctx->enhanced_mode_available) { - return SDL_Unsupported(); + if (!ctx->enhanced_mode) { + if (application_usage) { + HIDAPI_DriverPS4_UpdateEnhancedModeOnApplicationUsage(ctx); + } + + if (!ctx->enhanced_mode) { + /* We're not in enhanced mode, effects aren't allowed */ + return SDL_Unsupported(); + } } SDL_zeroa(data); @@ -1059,7 +1061,7 @@ static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d axis = ((int)packet->ucRightJoystickY * 257) - 32768; SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis); - if (size > 9 && ctx->report_battery) { + if (size > 9 && ctx->report_battery && ctx->enhanced_reports) { /* Battery level ranges from 0 to 10 */ int level = (packet->ucBatteryLevel & 0xF); if (level == 0) { @@ -1073,7 +1075,7 @@ static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d } } - if (size > 9 && ctx->report_touchpad) { + if (size > 9 && ctx->report_touchpad && ctx->enhanced_reports) { 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); diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index 650d5f52..1f6df2a6 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -412,7 +412,7 @@ static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) /* Connected over Bluetooth, using simple reports (DirectInput enabled) */ } - if (ctx->enhanced_reports) { + if (device->vendor_id == USB_VENDOR_SONY && ctx->enhanced_reports) { /* Read the serial number (Bluetooth address in reverse byte order) This will also enable enhanced reports over Bluetooth */ @@ -774,16 +774,13 @@ static void HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device) static void HIDAPI_DriverPS5_SetEnhancedModeAvailable(SDL_DriverPS5_Context *ctx) { - if (!ctx->effects_supported) { - /* We shouldn't be sending any packets to the controller */ - return; - } - ctx->enhanced_mode_available = SDL_TRUE; if (ctx->touchpad_supported) { SDL_PrivateJoystickAddTouchpad(ctx->joystick, 2); + ctx->report_touchpad = SDL_TRUE; } + if (ctx->sensors_supported) { if (ctx->device->is_bluetooth) { /* Bluetooth sensor update rate appears to be 1000 Hz */ @@ -794,6 +791,10 @@ static void HIDAPI_DriverPS5_SetEnhancedModeAvailable(SDL_DriverPS5_Context *ctx SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, 250.0f); } } + + if (ctx->device->is_bluetooth) { + ctx->report_battery = SDL_TRUE; + } } static void HIDAPI_DriverPS5_SetEnhancedMode(SDL_DriverPS5_Context *ctx) @@ -805,14 +806,6 @@ static void HIDAPI_DriverPS5_SetEnhancedMode(SDL_DriverPS5_Context *ctx) if (!ctx->enhanced_mode && ctx->enhanced_mode_available) { ctx->enhanced_mode = SDL_TRUE; - if (ctx->touchpad_supported) { - ctx->report_touchpad = SDL_TRUE; - } - - if (ctx->device->is_bluetooth) { - ctx->report_battery = SDL_TRUE; - } - /* Switch into enhanced report mode */ HIDAPI_DriverPS5_UpdateEffects(ctx, 0, SDL_FALSE); @@ -1017,12 +1010,20 @@ static int HIDAPI_DriverPS5_InternalSendJoystickEffect(SDL_DriverPS5_Context *ct int *pending_size; int maximum_size; - if (application_usage) { - HIDAPI_DriverPS5_UpdateEnhancedModeOnApplicationUsage(ctx); + if (!ctx->effects_supported) { + /* We shouldn't be sending packets to this controller */ + return SDL_Unsupported(); } - if (!ctx->enhanced_mode_available) { - return SDL_Unsupported(); + if (!ctx->enhanced_mode) { + if (application_usage) { + HIDAPI_DriverPS5_UpdateEnhancedModeOnApplicationUsage(ctx); + } + + if (!ctx->enhanced_mode) { + /* We're not in enhanced mode, effects aren't allowed */ + return SDL_Unsupported(); + } } SDL_zeroa(data); diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c index edb476a4..d01d5642 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/src/joystick/hidapi/SDL_hidapi_steam.c @@ -1153,23 +1153,15 @@ static SDL_bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device) (ctx->m_state.ulButtons & STEAM_BUTTON_BACK_LEFT_MASK) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_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_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, - (ctx->m_state.sLeftPadY > kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); - + (ctx->m_state.ulButtons & STEAM_TOUCH_0_MASK) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, - (ctx->m_state.sLeftPadY < -kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); - + (ctx->m_state.ulButtons & STEAM_TOUCH_3_MASK) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, - (ctx->m_state.sLeftPadX < -kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); - + (ctx->m_state.ulButtons & STEAM_TOUCH_2_MASK) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, - (ctx->m_state.sLeftPadX > kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); + (ctx->m_state.ulButtons & STEAM_TOUCH_1_MASK) ? SDL_PRESSED : SDL_RELEASED); } SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, (int)ctx->m_state.sTriggerL * 2 - 32768); diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index ff4f4ea9..0da65eb7 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -1888,8 +1888,8 @@ static void HandleCombinedControllerStateL(Uint64 timestamp, SDL_Joystick *joyst SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE4, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE2, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); axis = (data & 0x80) ? 32767 : -32768; SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis); @@ -1923,8 +1923,8 @@ static void HandleMiniControllerStateL(Uint64 timestamp, SDL_Joystick *joystick, SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_B), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE2, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE4, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); } axis = packet->controllerState.rgucJoystickLeft[0] | ((packet->controllerState.rgucJoystickLeft[1] & 0xF) << 8); @@ -1946,8 +1946,8 @@ static void HandleCombinedControllerStateR(Uint64 timestamp, SDL_Joystick *joyst SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_X), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE1, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE3, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); axis = (data & 0x80) ? 32767 : -32768; SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis); @@ -1981,8 +1981,8 @@ static void HandleMiniControllerStateR(Uint64 timestamp, SDL_Joystick *joystick, SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_X), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); - SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_PADDLE3, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); } if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index c3d68e1f..cca2016e 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -1149,7 +1149,7 @@ static void ConfigJoystick(SDL_Joystick *joystick, int fd, int fd_sensor) } for (i = 0; i < ABS_MAX; ++i) { /* Skip digital hats */ - if (joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) { + if (i >= ABS_HAT0X && i <= ABS_HAT3Y && joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) { continue; } if (test_bit(i, absbit)) { @@ -1553,6 +1553,8 @@ static int LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, in static int LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { + SDL_AssertJoysticksLocked(); + if (!joystick->hwdata->has_accelerometer && !joystick->hwdata->has_gyro) { return SDL_Unsupported(); } @@ -1723,6 +1725,8 @@ static void PollAllSensors(Uint64 timestamp, SDL_Joystick *joystick) struct input_absinfo absinfo; int i; + SDL_AssertJoysticksLocked(); + SDL_assert(joystick->hwdata->fd_sensor >= 0); if (joystick->hwdata->has_gyro) { @@ -2513,19 +2517,19 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap 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]; + out->right_paddle1.kind = EMappingKind_Button; + out->right_paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY5]; + out->left_paddle1.kind = EMappingKind_Button; + out->left_paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY7]; + out->right_paddle2.kind = EMappingKind_Button; + out->right_paddle2.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY6]; + out->left_paddle2.kind = EMappingKind_Button; + out->left_paddle2.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); + SDL_Log("Mapped RIGHT_PADDLE1 to button %d (BTN_TRIGGER_HAPPY5)", out->right_paddle1.target); + SDL_Log("Mapped LEFT_PADDLE1 to button %d (BTN_TRIGGER_HAPPY7)", out->left_paddle1.target); + SDL_Log("Mapped RIGHT_PADDLE2 to button %d (BTN_TRIGGER_HAPPY6)", out->right_paddle2.target); + SDL_Log("Mapped LEFT_PADDLE2 to button %d (BTN_TRIGGER_HAPPY8)", out->left_paddle2.target); #endif } diff --git a/src/joystick/n3ds/SDL_sysjoystick.c b/src/joystick/n3ds/SDL_sysjoystick.c index db419412..5e17010f 100644 --- a/src/joystick/n3ds/SDL_sysjoystick.c +++ b/src/joystick/n3ds/SDL_sysjoystick.c @@ -198,10 +198,10 @@ static SDL_bool N3DS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapp .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 }, + .right_paddle1 = { EMappingKind_None, 255 }, + .left_paddle1 = { EMappingKind_None, 255 }, + .right_paddle2 = { EMappingKind_None, 255 }, + .left_paddle2 = { EMappingKind_None, 255 }, .leftx = { EMappingKind_Axis, 0 }, .lefty = { EMappingKind_Axis, 1 }, .rightx = { EMappingKind_Axis, 2 }, diff --git a/src/joystick/virtual/SDL_virtualjoystick.c b/src/joystick/virtual/SDL_virtualjoystick.c index 5fdca603..b22ae6ac 100644 --- a/src/joystick/virtual/SDL_virtualjoystick.c +++ b/src/joystick/virtual/SDL_virtualjoystick.c @@ -669,24 +669,24 @@ static SDL_bool VIRTUAL_JoystickGetGamepadMapping(int device_index, SDL_GamepadM out->misc1.target = current_button++; } - if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE1))) { - out->paddle1.kind = EMappingKind_Button; - out->paddle1.target = current_button++; + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1))) { + out->right_paddle1.kind = EMappingKind_Button; + out->right_paddle1.target = current_button++; } - if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE2))) { - out->paddle2.kind = EMappingKind_Button; - out->paddle2.target = current_button++; + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_PADDLE1))) { + out->left_paddle1.kind = EMappingKind_Button; + out->left_paddle1.target = current_button++; } - if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE3))) { - out->paddle3.kind = EMappingKind_Button; - out->paddle3.target = current_button++; + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2))) { + out->right_paddle2.kind = EMappingKind_Button; + out->right_paddle2.target = current_button++; } - if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_PADDLE4))) { - out->paddle4.kind = EMappingKind_Button; - out->paddle4.target = current_button++; + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_GAMEPAD_BUTTON_LEFT_PADDLE2))) { + out->left_paddle2.kind = EMappingKind_Button; + out->left_paddle2.target = current_button++; } if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_GAMEPAD_AXIS_LEFTX))) { diff --git a/src/misc/ios/SDL_sysurl.m b/src/misc/ios/SDL_sysurl.m index 243b3a57..7db7f48d 100644 --- a/src/misc/ios/SDL_sysurl.m +++ b/src/misc/ios/SDL_sysurl.m @@ -20,6 +20,8 @@ */ #include "SDL_internal.h" +#if defined(__IOS__) || defined(__TVOS__) + #include "../SDL_sysurl.h" #import @@ -28,8 +30,14 @@ int SDL_SYS_OpenURL(const char *url) { @autoreleasepool { +#if TARGET_OS_XR + return SDL_Unsupported(); // openURL is not suported on visionOS +#else NSString *nsstr = [NSString stringWithUTF8String:url]; NSURL *nsurl = [NSURL URLWithString:nsstr]; return [[UIApplication sharedApplication] openURL:nsurl] ? 0 : -1; +#endif } } + +#endif /* __IOS__ || __TVOS__ */ diff --git a/src/misc/macos/SDL_sysurl.m b/src/misc/macos/SDL_sysurl.m index 13cff521..b372cec4 100644 --- a/src/misc/macos/SDL_sysurl.m +++ b/src/misc/macos/SDL_sysurl.m @@ -20,6 +20,8 @@ */ #include "SDL_internal.h" +#if defined(__MACOS__) + #include "../SDL_sysurl.h" #import @@ -33,3 +35,5 @@ int SDL_SYS_OpenURL(const char *url) return status == noErr ? 0 : -1; } } + +#endif /* __MACOS__ */ diff --git a/src/sensor/SDL_sensor.c b/src/sensor/SDL_sensor.c index c9a5ab74..26eed898 100644 --- a/src/sensor/SDL_sensor.c +++ b/src/sensor/SDL_sensor.c @@ -49,18 +49,79 @@ static SDL_SensorDriver *SDL_sensor_drivers[] = { &SDL_DUMMY_SensorDriver #endif }; -static SDL_Mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */ + +#ifndef SDL_THREAD_SAFETY_ANALYSIS +static +#endif +SDL_Mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */ +static SDL_AtomicInt SDL_sensor_lock_pending; +static int SDL_sensors_locked; +static SDL_bool SDL_sensors_initialized; static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL; static SDL_AtomicInt SDL_last_sensor_instance_id SDL_GUARDED_BY(SDL_sensor_lock); +static char SDL_sensor_magic; -void SDL_LockSensors(void) SDL_ACQUIRE(SDL_sensor_lock) +#define CHECK_SENSOR_MAGIC(sensor, retval) \ + if (!sensor || sensor->magic != &SDL_sensor_magic) { \ + SDL_InvalidParamError("sensor"); \ + SDL_UnlockSensors(); \ + return retval; \ + } + +SDL_bool SDL_SensorsInitialized(void) { - SDL_LockMutex(SDL_sensor_lock); + return SDL_sensors_initialized; } -void SDL_UnlockSensors(void) SDL_RELEASE(SDL_sensor_lock) +void SDL_LockSensors(void) { - SDL_UnlockMutex(SDL_sensor_lock); + (void)SDL_AtomicIncRef(&SDL_sensor_lock_pending); + SDL_LockMutex(SDL_sensor_lock); + (void)SDL_AtomicDecRef(&SDL_sensor_lock_pending); + + ++SDL_sensors_locked; +} + +void SDL_UnlockSensors(void) +{ + SDL_bool last_unlock = SDL_FALSE; + + --SDL_sensors_locked; + + if (!SDL_sensors_initialized) { + /* NOTE: There's a small window here where another thread could lock the mutex after we've checked for pending locks */ + if (!SDL_sensors_locked && SDL_AtomicGet(&SDL_sensor_lock_pending) == 0) { + last_unlock = SDL_TRUE; + } + } + + /* The last unlock after sensors are uninitialized will cleanup the mutex, + * allowing applications to lock sensors while reinitializing the system. + */ + if (last_unlock) { + SDL_Mutex *sensor_lock = SDL_sensor_lock; + + SDL_LockMutex(sensor_lock); + { + SDL_UnlockMutex(SDL_sensor_lock); + + SDL_sensor_lock = NULL; + } + SDL_UnlockMutex(sensor_lock); + SDL_DestroyMutex(sensor_lock); + } else { + SDL_UnlockMutex(SDL_sensor_lock); + } +} + +SDL_bool SDL_SensorsLocked(void) +{ + return (SDL_sensors_locked > 0) ? SDL_TRUE : SDL_FALSE; +} + +void SDL_AssertSensorsLocked(void) +{ + SDL_assert(SDL_SensorsLocked()); } int SDL_InitSensors(void) @@ -78,12 +139,23 @@ int SDL_InitSensors(void) } #endif /* !SDL_EVENTS_DISABLED */ + SDL_LockSensors(); + + SDL_sensors_initialized = SDL_TRUE; + status = -1; for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) { if (SDL_sensor_drivers[i]->Init() >= 0) { status = 0; } } + + SDL_UnlockSensors(); + + if (status < 0) { + SDL_QuitSensors(); + } + return status; } @@ -272,6 +344,7 @@ SDL_Sensor *SDL_OpenSensor(SDL_SensorID instance_id) SDL_UnlockSensors(); return NULL; } + sensor->magic = &SDL_sensor_magic; sensor->driver = driver; sensor->instance_id = instance_id; sensor->type = driver->GetDeviceType(device_index); @@ -320,33 +393,22 @@ SDL_Sensor *SDL_GetSensorFromInstanceID(SDL_SensorID instance_id) return sensor; } -/* - * Checks to make sure the sensor is valid. - */ -static int SDL_IsSensorValid(SDL_Sensor *sensor) -{ - int valid; - - if (sensor == NULL) { - SDL_SetError("Sensor hasn't been opened yet"); - valid = 0; - } else { - valid = 1; - } - - return valid; -} - /* * Get the friendly name of this sensor */ const char *SDL_GetSensorName(SDL_Sensor *sensor) { - if (!SDL_IsSensorValid(sensor)) { - return NULL; - } + const char *retval; - return sensor->name; + SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor, NULL); + + retval = sensor->name; + } + SDL_UnlockSensors(); + + return retval; } /* @@ -354,11 +416,17 @@ const char *SDL_GetSensorName(SDL_Sensor *sensor) */ SDL_SensorType SDL_GetSensorType(SDL_Sensor *sensor) { - if (!SDL_IsSensorValid(sensor)) { - return SDL_SENSOR_INVALID; - } + SDL_SensorType retval; - return sensor->type; + SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor, SDL_SENSOR_INVALID); + + retval = sensor->type; + } + SDL_UnlockSensors(); + + return retval; } /* @@ -366,11 +434,17 @@ SDL_SensorType SDL_GetSensorType(SDL_Sensor *sensor) */ int SDL_GetSensorNonPortableType(SDL_Sensor *sensor) { - if (!SDL_IsSensorValid(sensor)) { - return -1; - } + int retval; - return sensor->non_portable_type; + SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor, -1); + + retval = sensor->non_portable_type; + } + SDL_UnlockSensors(); + + return retval; } /* @@ -378,11 +452,17 @@ int SDL_GetSensorNonPortableType(SDL_Sensor *sensor) */ SDL_SensorID SDL_GetSensorInstanceID(SDL_Sensor *sensor) { - if (!SDL_IsSensorValid(sensor)) { - return 0; - } + SDL_SensorID retval; - return sensor->instance_id; + SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor, 0); + + retval = sensor->instance_id; + } + SDL_UnlockSensors(); + + return retval; } /* @@ -390,12 +470,15 @@ SDL_SensorID SDL_GetSensorInstanceID(SDL_Sensor *sensor) */ int SDL_GetSensorData(SDL_Sensor *sensor, float *data, int num_values) { - if (!SDL_IsSensorValid(sensor)) { - return -1; - } + SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor, -1); + + num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); + SDL_memcpy(data, sensor->data, num_values * sizeof(*data)); + } + SDL_UnlockSensors(); - num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); - SDL_memcpy(data, sensor->data, num_values * sizeof(*data)); return 0; } @@ -407,42 +490,39 @@ void SDL_CloseSensor(SDL_Sensor *sensor) SDL_Sensor *sensorlist; SDL_Sensor *sensorlistprev; - if (!SDL_IsSensorValid(sensor)) { - return; - } - SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor,); - /* First decrement ref count */ - if (--sensor->ref_count > 0) { - SDL_UnlockSensors(); - return; - } - - sensor->driver->Close(sensor); - sensor->hwdata = NULL; - - sensorlist = SDL_sensors; - sensorlistprev = NULL; - while (sensorlist) { - if (sensor == sensorlist) { - if (sensorlistprev) { - /* unlink this entry */ - sensorlistprev->next = sensorlist->next; - } else { - SDL_sensors = sensor->next; - } - break; + /* First decrement ref count */ + if (--sensor->ref_count > 0) { + SDL_UnlockSensors(); + return; } - sensorlistprev = sensorlist; - sensorlist = sensorlist->next; + + sensor->driver->Close(sensor); + sensor->hwdata = NULL; + + sensorlist = SDL_sensors; + sensorlistprev = NULL; + while (sensorlist) { + if (sensor == sensorlist) { + if (sensorlistprev) { + /* unlink this entry */ + sensorlistprev->next = sensorlist->next; + } else { + SDL_sensors = sensor->next; + } + break; + } + sensorlistprev = sensorlist; + sensorlist = sensorlist->next; + } + + /* Free the data associated with this sensor */ + SDL_free(sensor->name); + SDL_free(sensor); } - - SDL_free(sensor->name); - - /* Free the data associated with this sensor */ - SDL_free(sensor); - SDL_UnlockSensors(); } @@ -463,16 +543,13 @@ void SDL_QuitSensors(void) SDL_sensor_drivers[i]->Quit(); } - SDL_UnlockSensors(); - #ifndef SDL_EVENTS_DISABLED SDL_QuitSubSystem(SDL_INIT_EVENTS); #endif - if (SDL_sensor_lock) { - SDL_DestroyMutex(SDL_sensor_lock); - SDL_sensor_lock = NULL; - } + SDL_sensors_initialized = SDL_FALSE; + + SDL_UnlockSensors(); } /* These are global for SDL_syssensor.c and SDL_events.c */ @@ -481,6 +558,8 @@ int SDL_SendSensorUpdate(Uint64 timestamp, SDL_Sensor *sensor, Uint64 sensor_tim { int posted; + SDL_AssertSensorsLocked(); + /* Allow duplicate events, for things like steps and heartbeats */ /* Update internal sensor state */ @@ -510,7 +589,13 @@ int SDL_SendSensorUpdate(Uint64 timestamp, SDL_Sensor *sensor, Uint64 sensor_tim void SDL_UpdateSensor(SDL_Sensor *sensor) { - sensor->driver->Update(sensor); + SDL_LockSensors(); + { + CHECK_SENSOR_MAGIC(sensor,); + + sensor->driver->Update(sensor); + } + SDL_UnlockSensors(); } void SDL_UpdateSensors(void) diff --git a/src/sensor/SDL_sensor_c.h b/src/sensor/SDL_sensor_c.h index 32845917..ece9ec50 100644 --- a/src/sensor/SDL_sensor_c.h +++ b/src/sensor/SDL_sensor_c.h @@ -23,6 +23,10 @@ #ifndef SDL_sensor_c_h_ #define SDL_sensor_c_h_ +#ifdef SDL_THREAD_SAFETY_ANALYSIS +extern SDL_Mutex *SDL_sensor_lock; +#endif + struct SDL_SensorDriver; /* Useful functions and variables from SDL_sensor.c */ @@ -34,8 +38,17 @@ extern SDL_SensorID SDL_GetNextSensorInstanceID(void); extern int SDL_InitSensors(void); extern void SDL_QuitSensors(void); -extern void SDL_LockSensors(void); -extern void SDL_UnlockSensors(void); +/* Return whether the sensor system is currently initialized */ +extern SDL_bool SDL_SensorsInitialized(void); + +/* Return whether the sensors are currently locked */ +extern SDL_bool SDL_SensorsLocked(void); + +/* Make sure we currently have the sensors locked */ +extern void SDL_AssertSensorsLocked(void) SDL_ASSERT_CAPABILITY(SDL_sensor_lock); + +extern void SDL_LockSensors(void) SDL_ACQUIRE(SDL_sensor_lock); +extern void SDL_UnlockSensors(void) SDL_RELEASE(SDL_sensor_lock); /* Function to return whether there are any sensors opened by the application */ extern SDL_bool SDL_SensorsOpened(void); diff --git a/src/sensor/SDL_syssensor.h b/src/sensor/SDL_syssensor.h index 73492cf6..9376be6b 100644 --- a/src/sensor/SDL_syssensor.h +++ b/src/sensor/SDL_syssensor.h @@ -27,25 +27,31 @@ #include "SDL_sensor_c.h" +#define _guarded SDL_GUARDED_BY(SDL_sensor_lock) + /* 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 */ + const void *magic _guarded; - float data[16]; /* The current state of the sensor */ + SDL_SensorID instance_id _guarded; /* Device instance, monotonically increasing from 0 */ + char *name _guarded; /* Sensor name - system dependent */ + SDL_SensorType type _guarded; /* Type of the sensor */ + int non_portable_type _guarded; /* Platform dependent type of the sensor */ - struct SDL_SensorDriver *driver; + float data[16] _guarded; /* The current state of the sensor */ - struct sensor_hwdata *hwdata; /* Driver dependent information */ + struct SDL_SensorDriver *driver _guarded; - int ref_count; /* Reference count for multiple opens */ + struct sensor_hwdata *hwdata _guarded; /* Driver dependent information */ - struct SDL_Sensor *next; /* pointer to next sensor we have allocated */ + int ref_count _guarded; /* Reference count for multiple opens */ + + struct SDL_Sensor *next _guarded; /* pointer to next sensor we have allocated */ }; +#undef _guarded + typedef struct SDL_SensorDriver { /* Function to scan the system for sensors. diff --git a/src/sensor/android/SDL_androidsensor.c b/src/sensor/android/SDL_androidsensor.c index 20186641..856f64b3 100644 --- a/src/sensor/android/SDL_androidsensor.c +++ b/src/sensor/android/SDL_androidsensor.c @@ -52,7 +52,6 @@ typedef struct static ASensorManager *SDL_sensor_manager; static ALooper *SDL_sensor_looper; static SDL_AndroidSensorThreadContext SDL_sensor_thread_context; -static SDL_Mutex *SDL_sensors_lock; static SDL_AndroidSensor *SDL_sensors SDL_GUARDED_BY(SDL_sensors_lock); static int SDL_sensors_count; @@ -72,7 +71,7 @@ static int SDLCALL SDL_ANDROID_SensorThread(void *data) Uint64 timestamp = SDL_GetTicksNS(); if (ALooper_pollAll(-1, NULL, &events, (void **)&source) == LOOPER_ID_USER) { - SDL_LockMutex(SDL_sensors_lock); + SDL_LockSensors(); for (i = 0; i < SDL_sensors_count; ++i) { if (!SDL_sensors[i].event_queue) { continue; @@ -83,7 +82,7 @@ static int SDLCALL SDL_ANDROID_SensorThread(void *data) SDL_SendSensorUpdate(timestamp, SDL_sensors[i].sensor, timestamp, event.data, SDL_arraysize(event.data)); } } - SDL_UnlockMutex(SDL_sensors_lock); + SDL_UnlockSensors(); } } @@ -138,11 +137,6 @@ static int SDL_ANDROID_SensorInit(void) int i, sensors_count; ASensorList sensors; - SDL_sensors_lock = SDL_CreateMutex(); - if (!SDL_sensors_lock) { - return SDL_SetError("Couldn't create sensor lock"); - } - SDL_sensor_manager = ASensorManager_getInstance(); if (SDL_sensor_manager == NULL) { return SDL_SetError("Couldn't create sensor manager"); @@ -209,19 +203,19 @@ static int SDL_ANDROID_SensorOpen(SDL_Sensor *sensor, int device_index) { int delay_us, min_delay_us; - SDL_LockMutex(SDL_sensors_lock); + SDL_LockSensors(); { SDL_sensors[device_index].sensor = sensor; SDL_sensors[device_index].event_queue = ASensorManager_createEventQueue(SDL_sensor_manager, SDL_sensor_looper, LOOPER_ID_USER, NULL, NULL); if (!SDL_sensors[device_index].event_queue) { - SDL_UnlockMutex(SDL_sensors_lock); + SDL_UnlockSensors(); return SDL_SetError("Couldn't create sensor event queue"); } if (ASensorEventQueue_enableSensor(SDL_sensors[device_index].event_queue, SDL_sensors[device_index].asensor) < 0) { ASensorManager_destroyEventQueue(SDL_sensor_manager, SDL_sensors[device_index].event_queue); SDL_sensors[device_index].event_queue = NULL; - SDL_UnlockMutex(SDL_sensors_lock); + SDL_UnlockSensors(); return SDL_SetError("Couldn't enable sensor"); } @@ -234,7 +228,7 @@ static int SDL_ANDROID_SensorOpen(SDL_Sensor *sensor, int device_index) } ASensorEventQueue_setEventRate(SDL_sensors[device_index].event_queue, SDL_sensors[device_index].asensor, delay_us); } - SDL_UnlockMutex(SDL_sensors_lock); + SDL_UnlockSensors(); return 0; } @@ -249,14 +243,14 @@ static void SDL_ANDROID_SensorClose(SDL_Sensor *sensor) for (i = 0; i < SDL_sensors_count; ++i) { if (SDL_sensors[i].sensor == sensor) { - SDL_LockMutex(SDL_sensors_lock); + SDL_LockSensors(); { ASensorEventQueue_disableSensor(SDL_sensors[i].event_queue, SDL_sensors[i].asensor); ASensorManager_destroyEventQueue(SDL_sensor_manager, SDL_sensors[i].event_queue); SDL_sensors[i].event_queue = NULL; SDL_sensors[i].sensor = NULL; } - SDL_UnlockMutex(SDL_sensors_lock); + SDL_UnlockSensors(); break; } } @@ -264,18 +258,17 @@ static void SDL_ANDROID_SensorClose(SDL_Sensor *sensor) static void SDL_ANDROID_SensorQuit(void) { + /* All sensors are closed, but we need to unblock the sensor thread */ + SDL_AssertSensorsLocked(); + SDL_UnlockSensors(); SDL_ANDROID_StopSensorThread(&SDL_sensor_thread_context); + SDL_LockSensors(); if (SDL_sensors) { SDL_free(SDL_sensors); SDL_sensors = NULL; SDL_sensors_count = 0; } - - if (SDL_sensors_lock) { - SDL_DestroyMutex(SDL_sensors_lock); - SDL_sensors_lock = NULL; - } } SDL_SensorDriver SDL_ANDROID_SensorDriver = { diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 0e4a7488..ca660013 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -1275,7 +1275,9 @@ int 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; @@ -1758,16 +1760,17 @@ static size_t SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, do } if (num[i] == '9') { num[i] = '0'; + if (i == 0 || num[i - 1] == '-' || num[i - 1] == '+') { + SDL_memmove(&num[i+1], &num[i], length - i); + num[i] = '1'; + ++length; + break; + } } else { ++num[i]; break; } } - if (i == 0 || num[i] == '-' || num[i] == '+') { - SDL_memmove(&num[i+1], &num[i], length - i); - num[i] = '1'; - ++length; - } SDL_assert(length < sizeof(num)); num[length++] = '0'; } else { diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index f621ef7a..4d09aabb 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -71,7 +71,7 @@ static const char *video_usage[] = { /* !!! FIXME: Float32? Sint32? */ static const char *audio_usage[] = { "[--audio driver]", "[--rate N]", "[--format U8|S8|S16|S16LE|S16BE]", - "[--channels N]", "[--samples N]" + "[--channels N]" }; static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) @@ -117,10 +117,9 @@ SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags) state->logical_presentation = SDL_LOGICAL_PRESENTATION_DISABLED; state->logical_scale_mode = SDL_SCALEMODE_LINEAR; state->num_windows = 1; - state->audiospec.freq = 22050; - state->audiospec.format = SDL_AUDIO_S16; - state->audiospec.channels = 2; - state->audiospec.samples = 2048; + state->audio_freq = 22050; + state->audio_format = SDL_AUDIO_S16; + state->audio_channels = 2; /* Set some very sane GL defaults */ state->gl_red_size = 8; @@ -604,7 +603,7 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index) if (!argv[index]) { return -1; } - state->audiospec.freq = SDL_atoi(argv[index]); + state->audio_freq = SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--format") == 0) { @@ -613,23 +612,23 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index) return -1; } if (SDL_strcasecmp(argv[index], "U8") == 0) { - state->audiospec.format = SDL_AUDIO_U8; + state->audio_format = SDL_AUDIO_U8; return 2; } if (SDL_strcasecmp(argv[index], "S8") == 0) { - state->audiospec.format = SDL_AUDIO_S8; + state->audio_format = SDL_AUDIO_S8; return 2; } if (SDL_strcasecmp(argv[index], "S16") == 0) { - state->audiospec.format = SDL_AUDIO_S16; + state->audio_format = SDL_AUDIO_S16; return 2; } if (SDL_strcasecmp(argv[index], "S16LE") == 0) { - state->audiospec.format = SDL_AUDIO_S16LSB; + state->audio_format = SDL_AUDIO_S16LSB; return 2; } if (SDL_strcasecmp(argv[index], "S16BE") == 0) { - state->audiospec.format = SDL_AUDIO_S16MSB; + state->audio_format = SDL_AUDIO_S16MSB; return 2; } @@ -642,15 +641,7 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index) if (!argv[index]) { return -1; } - state->audiospec.channels = (Uint8) SDL_atoi(argv[index]); - return 2; - } - if (SDL_strcasecmp(argv[index], "--samples") == 0) { - ++index; - if (!argv[index]) { - return -1; - } - state->audiospec.samples = (Uint16) SDL_atoi(argv[index]); + state->audio_channels = (Uint8) SDL_atoi(argv[index]); return 2; } } @@ -1452,7 +1443,8 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state) SDL_GetCurrentAudioDriver()); } - state->audio_id = SDL_OpenAudioDevice(NULL, 0, &state->audiospec, NULL, 0); + const SDL_AudioSpec spec = { state->audio_format, state->audio_channels, state->audio_freq }; + state->audio_id = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec); if (!state->audio_id) { SDL_Log("Couldn't open audio: %s\n", SDL_GetError()); return SDL_FALSE; diff --git a/src/thread/generic/SDL_sysrwlock.c b/src/thread/generic/SDL_sysrwlock.c index 37b13997..d88bee15 100644 --- a/src/thread/generic/SDL_sysrwlock.c +++ b/src/thread/generic/SDL_sysrwlock.c @@ -43,22 +43,27 @@ struct SDL_RWLock { +#ifdef SDL_THREADS_DISABLED + int unused; +#else SDL_Mutex *lock; SDL_Condition *condition; SDL_threadID writer_thread; SDL_AtomicInt reader_count; SDL_AtomicInt writer_count; +#endif }; SDL_RWLock *SDL_CreateRWLock_generic(void) { - SDL_RWLock *rwlock = (SDL_RWLock *) SDL_malloc(sizeof (*rwlock)); + SDL_RWLock *rwlock = (SDL_RWLock *) SDL_calloc(1, sizeof (*rwlock)); if (!rwlock) { SDL_OutOfMemory(); return NULL; } +#ifndef SDL_THREADS_DISABLED rwlock->lock = SDL_CreateMutex(); if (!rwlock->lock) { SDL_free(rwlock); @@ -74,6 +79,7 @@ SDL_RWLock *SDL_CreateRWLock_generic(void) SDL_AtomicSet(&rwlock->reader_count, 0); SDL_AtomicSet(&rwlock->writer_count, 0); +#endif return rwlock; } @@ -81,14 +87,17 @@ SDL_RWLock *SDL_CreateRWLock_generic(void) void SDL_DestroyRWLock_generic(SDL_RWLock *rwlock) { if (rwlock) { +#ifndef SDL_THREADS_DISABLED SDL_DestroyMutex(rwlock->lock); SDL_DestroyCondition(rwlock->condition); +#endif SDL_free(rwlock); } } int SDL_LockRWLockForReading_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { +#ifndef SDL_THREADS_DISABLED if (!rwlock) { return SDL_InvalidParamError("rwlock"); } else if (SDL_LockMutex(rwlock->lock) == -1) { @@ -99,11 +108,14 @@ int SDL_LockRWLockForReading_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_AN SDL_AtomicAdd(&rwlock->reader_count, 1); SDL_UnlockMutex(rwlock->lock); /* other readers can attempt to share the lock. */ +#endif + return 0; } int SDL_LockRWLockForWriting_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { +#ifndef SDL_THREADS_DISABLED if (!rwlock) { return SDL_InvalidParamError("rwlock"); } else if (SDL_LockMutex(rwlock->lock) == -1) { @@ -116,12 +128,14 @@ int SDL_LockRWLockForWriting_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_AN /* we hold the lock! */ SDL_AtomicAdd(&rwlock->writer_count, 1); /* we let these be recursive, but the API doesn't require this. It _does_ trust you unlock correctly! */ +#endif return 0; } int SDL_TryLockRWLockForReading_generic(SDL_RWLock *rwlock) { +#ifndef SDL_THREADS_DISABLED int rc; if (!rwlock) { @@ -138,11 +152,14 @@ int SDL_TryLockRWLockForReading_generic(SDL_RWLock *rwlock) SDL_AtomicAdd(&rwlock->reader_count, 1); SDL_UnlockMutex(rwlock->lock); /* other readers can attempt to share the lock. */ +#endif + return 0; } int SDL_TryLockRWLockForWriting_generic(SDL_RWLock *rwlock) { +#ifndef SDL_THREADS_DISABLED int rc; if (!rwlock) { @@ -158,12 +175,14 @@ int SDL_TryLockRWLockForWriting_generic(SDL_RWLock *rwlock) /* we hold the lock! */ SDL_AtomicAdd(&rwlock->writer_count, 1); /* we let these be recursive, but the API doesn't require this. It _does_ trust you unlock correctly! */ +#endif return 0; } int SDL_UnlockRWLock_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { +#ifndef SDL_THREADS_DISABLED if (!rwlock) { return SDL_InvalidParamError("rwlock"); } @@ -179,6 +198,7 @@ int SDL_UnlockRWLock_generic(SDL_RWLock *rwlock) SDL_NO_THREAD_SAFETY_ANALYSIS / } SDL_UnlockMutex(rwlock->lock); +#endif return 0; } diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index f111c627..8755f67c 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -53,12 +53,12 @@ static DWORD RunThread(void *data) return 0; } -static DWORD WINAPI RunThreadViaCreateThread(LPVOID data) +static DWORD WINAPI MINGW32_FORCEALIGN RunThreadViaCreateThread(LPVOID data) { return RunThread(data); } -static unsigned __stdcall RunThreadViaBeginThreadEx(void *data) +static unsigned __stdcall MINGW32_FORCEALIGN RunThreadViaBeginThreadEx(void *data) { return (unsigned)RunThread(data); } diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c index 126baefe..68e634fd 100644 --- a/src/video/SDL_bmp.c +++ b/src/video/SDL_bmp.c @@ -71,7 +71,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) /* !!! FIXME: for all these reads, handle error vs eof? handle -2 if non-blocking? */ for (;;) { - if (SDL_RWread(src, &ch, 1) <= 0) { + if (!SDL_ReadU8(src, &ch)) { return SDL_TRUE; } /* @@ -80,7 +80,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) */ if (ch) { Uint8 pixel; - if (SDL_RWread(src, &pixel, 1) <= 0) { + if (!SDL_ReadU8(src, &pixel)) { return SDL_TRUE; } if (isRle8) { /* 256-color bitmap, compressed */ @@ -107,7 +107,7 @@ static SDL_bool 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) <= 0) { + if (!SDL_ReadU8(src, &ch)) { return SDL_TRUE; } switch (ch) { @@ -118,11 +118,11 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) case 1: /* end of bitmap */ return SDL_FALSE; /* success! */ case 2: /* delta */ - if (SDL_RWread(src, &ch, 1) <= 0) { + if (!SDL_ReadU8(src, &ch)) { return SDL_TRUE; } ofs += ch; - if (SDL_RWread(src, &ch, 1) <= 0) { + if (!SDL_ReadU8(src, &ch)) { return SDL_TRUE; } bits -= (ch * pitch); @@ -132,7 +132,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) needsPad = (ch & 1); do { Uint8 pixel; - if (SDL_RWread(src, &pixel, 1) <= 0) { + if (!SDL_ReadU8(src, &pixel)) { return SDL_TRUE; } COPY_PIXEL(pixel); @@ -141,7 +141,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) needsPad = (((ch + 1) >> 1) & 1); /* (ch+1)>>1: bytes size */ for (;;) { Uint8 pixel; - if (SDL_RWread(src, &pixel, 1) <= 0) { + if (!SDL_ReadU8(src, &pixel)) { return SDL_TRUE; } COPY_PIXEL(pixel >> 4); @@ -155,7 +155,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) } } /* pad at even boundary */ - if (needsPad && (SDL_RWread(src, &ch, 1) <= 0)) { + if (needsPad && !SDL_ReadU8(src, &ch)) { return SDL_TRUE; } break; @@ -195,7 +195,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface) SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) { - SDL_bool was_error; + SDL_bool was_error = SDL_TRUE; Sint64 fp_offset = 0; int bmpPitch; int i, pad; @@ -235,42 +235,45 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) /* Make sure we are passed a valid data source */ surface = NULL; - was_error = SDL_FALSE; if (src == NULL) { 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, 2) != 2) { - SDL_Error(SDL_EFREAD); - was_error = SDL_TRUE; goto done; } if (SDL_strncmp(magic, "BM", 2) != 0) { SDL_SetError("File is not a Windows BMP file"); - was_error = SDL_TRUE; goto done; } - /* bfSize = */ SDL_ReadLE32(src); - /* bfReserved1 = */ SDL_ReadLE16(src); - /* bfReserved2 = */ SDL_ReadLE16(src); - bfOffBits = SDL_ReadLE32(src); + if (!SDL_ReadU32LE(src, NULL /* bfSize */) || + !SDL_ReadU16LE(src, NULL /* bfReserved1 */) || + !SDL_ReadU16LE(src, NULL /* bfReserved2 */) || + !SDL_ReadU32LE(src, &bfOffBits)) { + goto done; + } /* Read the Win32 BITMAPINFOHEADER */ - biSize = SDL_ReadLE32(src); + if (!SDL_ReadU32LE(src, &biSize)) { + goto done; + } if (biSize == 12) { /* really old BITMAPCOREHEADER */ - biWidth = (Uint32)SDL_ReadLE16(src); - biHeight = (Uint32)SDL_ReadLE16(src); - /* biPlanes = */ SDL_ReadLE16(src); - biBitCount = SDL_ReadLE16(src); + Uint16 biWidth16, biHeight16; + if (!SDL_ReadU16LE(src, &biWidth16) || + !SDL_ReadU16LE(src, &biHeight16) || + !SDL_ReadU16LE(src, NULL /* biPlanes */) || + !SDL_ReadU16LE(src, &biBitCount)) { + goto done; + } + biWidth = biWidth16; + biHeight = biHeight16; biCompression = BI_RGB; /* biSizeImage = 0; */ /* biXPelsPerMeter = 0; */ @@ -279,16 +282,18 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) /* biClrImportant = 0; */ } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */ Uint32 headerSize; - biWidth = SDL_ReadLE32(src); - biHeight = SDL_ReadLE32(src); - /* biPlanes = */ SDL_ReadLE16(src); - biBitCount = SDL_ReadLE16(src); - biCompression = SDL_ReadLE32(src); - /* biSizeImage = */ SDL_ReadLE32(src); - /* biXPelsPerMeter = */ SDL_ReadLE32(src); - /* biYPelsPerMeter = */ SDL_ReadLE32(src); - biClrUsed = SDL_ReadLE32(src); - /* biClrImportant = */ SDL_ReadLE32(src); + if (!SDL_ReadS32LE(src, &biWidth) || + !SDL_ReadS32LE(src, &biHeight) || + !SDL_ReadU16LE(src, NULL /* biPlanes */) || + !SDL_ReadU16LE(src, &biBitCount) || + !SDL_ReadU32LE(src, &biCompression) || + !SDL_ReadU32LE(src, NULL /* biSizeImage */) || + !SDL_ReadU32LE(src, NULL /* biXPelsPerMeter */) || + !SDL_ReadU32LE(src, NULL /* biYPelsPerMeter */) || + !SDL_ReadU32LE(src, &biClrUsed) || + !SDL_ReadU32LE(src, NULL /* biClrImportant */)) { + goto done; + } /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */ if (biSize != 64) { @@ -301,24 +306,32 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) following the legacy v1 info header, just past biSize. */ if (biCompression == BI_BITFIELDS) { haveRGBMasks = SDL_TRUE; - Rmask = SDL_ReadLE32(src); - Gmask = SDL_ReadLE32(src); - Bmask = SDL_ReadLE32(src); + if (!SDL_ReadU32LE(src, &Rmask) || + !SDL_ReadU32LE(src, &Gmask) || + !SDL_ReadU32LE(src, &Bmask)) { + goto done; + } /* ...v3 adds an alpha mask. */ if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ haveAlphaMask = SDL_TRUE; - Amask = SDL_ReadLE32(src); + if (!SDL_ReadU32LE(src, &Amask)) { + goto done; + } } } else { /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */ if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */ - /*Rmask = */ SDL_ReadLE32(src); - /*Gmask = */ SDL_ReadLE32(src); - /*Bmask = */ SDL_ReadLE32(src); + if (!SDL_ReadU32LE(src, NULL /* Rmask */) || + !SDL_ReadU32LE(src, NULL /* Gmask */) || + !SDL_ReadU32LE(src, NULL /* Bmask */)) { + goto done; + } } if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ - /*Amask = */ SDL_ReadLE32(src); + if (!SDL_ReadU32LE(src, NULL /* Amask */)) { + goto done; + } } } @@ -331,12 +344,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) /* skip any header bytes we didn't handle... */ headerSize = (Uint32)(SDL_RWtell(src) - (fp_offset + 14)); if (biSize > headerSize) { - SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR); + if (SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR) < 0) { + goto done; + } } } if (biWidth <= 0 || biHeight == 0) { SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight); - was_error = SDL_TRUE; goto done; } if (biHeight < 0) { @@ -348,7 +362,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) /* Check for read error */ if (SDL_strcmp(SDL_GetError(), "") != 0) { - was_error = SDL_TRUE; goto done; } @@ -366,7 +379,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) case 6: case 7: SDL_SetError("%d-bpp BMP images are not supported", biBitCount); - was_error = SDL_TRUE; goto done; default: ExpandBMP = 0; @@ -431,7 +443,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) surface = SDL_CreateSurface(biWidth, biHeight, format); if (surface == NULL) { - was_error = SDL_TRUE; goto done; } } @@ -441,13 +452,11 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) if (palette) { if (SDL_RWseek(src, fp_offset + 14 + biSize, SDL_RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); - was_error = SDL_TRUE; goto done; } if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */ SDL_SetError("Unsupported or incorrect biBitCount field"); - was_error = SDL_TRUE; goto done; } @@ -459,26 +468,27 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) 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) { - /* !!! FIXME: this should check for i/o errors! */ - SDL_RWread(src, &palette->colors[i].b, 1); - SDL_RWread(src, &palette->colors[i].g, 1); - SDL_RWread(src, &palette->colors[i].r, 1); + if (!SDL_ReadU8(src, &palette->colors[i].b) || + !SDL_ReadU8(src, &palette->colors[i].g) || + !SDL_ReadU8(src, &palette->colors[i].r)) { + goto done; + } palette->colors[i].a = SDL_ALPHA_OPAQUE; } } else { for (i = 0; i < (int)biClrUsed; ++i) { - /* !!! FIXME: this should check for i/o errors! */ - SDL_RWread(src, &palette->colors[i].b, 1); - SDL_RWread(src, &palette->colors[i].g, 1); - SDL_RWread(src, &palette->colors[i].r, 1); - SDL_RWread(src, &palette->colors[i].a, 1); + if (!SDL_ReadU8(src, &palette->colors[i].b) || + !SDL_ReadU8(src, &palette->colors[i].g) || + !SDL_ReadU8(src, &palette->colors[i].r) || + !SDL_ReadU8(src, &palette->colors[i].a)) { + goto done; + } /* According to Microsoft documentation, the fourth element is reserved and must be zero, so we shouldn't treat it as @@ -493,7 +503,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) /* Read the surface pixels. Note that the bmp image is upside down */ if (SDL_RWseek(src, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); - was_error = SDL_TRUE; goto done; } if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) { @@ -537,16 +546,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) 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; + if (!SDL_ReadU8(src, &pixel)) { 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"); - was_error = SDL_TRUE; goto done; } pixel <<= ExpandBMP; @@ -555,15 +561,12 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) default: if (SDL_RWread(src, bits, surface->pitch) != surface->pitch) { - SDL_Error(SDL_EFREAD); - was_error = SDL_TRUE; goto done; } if (biBitCount == 8 && palette && biClrUsed < (1u << biBitCount)) { for (i = 0; i < surface->w; ++i) { 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; } } @@ -598,7 +601,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) if (pad) { Uint8 padbyte; for (i = 0; i < pad; ++i) { - SDL_RWread(src, &padbyte, 1); + if (!SDL_ReadU8(src, &padbyte)) { + goto done; + } } } if (topDown) { @@ -610,6 +615,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc) if (correctAlpha) { CorrectAlphaChannel(surface); } + + was_error = SDL_FALSE; + done: if (was_error) { if (src) { @@ -629,15 +637,10 @@ SDL_Surface *SDL_LoadBMP(const char *file) return SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1); } -int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) +int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, SDL_bool freedst) { - /* !!! FIXME: this calls SDL_ClearError() and then checks if an error happened during this function to - !!! FIXME: decide if there was a problem, but there's risk of innocent things setting an error - !!! FIXME: string for innocent unrelated reasons, and also, an app supplying its own RWops - !!! FIXME: implementation may not set the error string on failure. We should check for i/o - !!! FIXME: failures as we go, and return early if one occurs. */ - - Sint64 fp_offset; + SDL_bool was_error = SDL_TRUE; + Sint64 fp_offset, new_offset; int i, pad; SDL_Surface *intermediate_surface; Uint8 *bits; @@ -678,6 +681,11 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) /* Make sure we have somewhere to save */ intermediate_surface = NULL; if (dst) { + if (!surface) { + SDL_InvalidParamError("surface"); + goto done; + } + #ifdef SAVE_32BIT_BMP /* We can save alpha information in a 32-bit BMP */ if (surface->format->BitsPerPixel >= 8 && @@ -693,6 +701,7 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) } else { SDL_SetError("%d bpp BMP files not supported", surface->format->BitsPerPixel); + goto done; } } else if ((surface->format->BitsPerPixel == 24) && !save32bit && #if SDL_BYTEORDER == SDL_LIL_ENDIAN @@ -707,32 +716,33 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) ) { intermediate_surface = surface; } else { - SDL_PixelFormat format; + Uint32 pixel_format; /* If the surface has a colorkey or alpha channel we'll save a 32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */ if (save32bit) { - SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32); + pixel_format = SDL_PIXELFORMAT_BGRA32; } else { - SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24); + pixel_format = SDL_PIXELFORMAT_BGR24; } - intermediate_surface = SDL_ConvertSurface(surface, &format); + intermediate_surface = SDL_ConvertSurfaceFormat(surface, pixel_format); if (intermediate_surface == NULL) { SDL_SetError("Couldn't convert image to %d bpp", - format.BitsPerPixel); + (int)SDL_BITSPERPIXEL(pixel_format)); + goto done; } } } else { /* Set no error here because it may overwrite a more useful message from SDL_RWFromFile() if SDL_SaveBMP_RW() is called from SDL_SaveBMP(). */ - return -1; + goto done; } if (save32bit) { saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE); } - if (intermediate_surface && (SDL_LockSurface(intermediate_surface) == 0)) { + if (SDL_LockSurface(intermediate_surface) == 0) { const int bw = intermediate_surface->w * intermediate_surface->format->BytesPerPixel; /* Set the BMP file header values */ @@ -743,12 +753,16 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) /* Write the BMP file header values */ fp_offset = SDL_RWtell(dst); - SDL_ClearError(); - SDL_RWwrite(dst, magic, 2); - SDL_WriteLE32(dst, bfSize); - SDL_WriteLE16(dst, bfReserved1); - SDL_WriteLE16(dst, bfReserved2); - SDL_WriteLE32(dst, bfOffBits); + if (fp_offset < 0) { + goto done; + } + if (SDL_RWwrite(dst, magic, 2) != 2 || + !SDL_WriteU32LE(dst, bfSize) || + !SDL_WriteU16LE(dst, bfReserved1) || + !SDL_WriteU16LE(dst, bfReserved2) || + !SDL_WriteU32LE(dst, bfOffBits)) { + goto done; + } /* Set the BMP info values */ biSize = 40; @@ -783,31 +797,39 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) } /* Write the BMP info values */ - SDL_WriteLE32(dst, biSize); - SDL_WriteLE32(dst, biWidth); - SDL_WriteLE32(dst, biHeight); - SDL_WriteLE16(dst, biPlanes); - SDL_WriteLE16(dst, biBitCount); - SDL_WriteLE32(dst, biCompression); - SDL_WriteLE32(dst, biSizeImage); - SDL_WriteLE32(dst, biXPelsPerMeter); - SDL_WriteLE32(dst, biYPelsPerMeter); - SDL_WriteLE32(dst, biClrUsed); - SDL_WriteLE32(dst, biClrImportant); + if (!SDL_WriteU32LE(dst, biSize) || + !SDL_WriteS32LE(dst, biWidth) || + !SDL_WriteS32LE(dst, biHeight) || + !SDL_WriteU16LE(dst, biPlanes) || + !SDL_WriteU16LE(dst, biBitCount) || + !SDL_WriteU32LE(dst, biCompression) || + !SDL_WriteU32LE(dst, biSizeImage) || + !SDL_WriteU32LE(dst, biXPelsPerMeter) || + !SDL_WriteU32LE(dst, biYPelsPerMeter) || + !SDL_WriteU32LE(dst, biClrUsed) || + !SDL_WriteU32LE(dst, biClrImportant)) { + goto done; + } /* Write the BMP info values for the version 4 header */ if (save32bit && !saveLegacyBMP) { - SDL_WriteLE32(dst, bV4RedMask); - SDL_WriteLE32(dst, bV4GreenMask); - SDL_WriteLE32(dst, bV4BlueMask); - SDL_WriteLE32(dst, bV4AlphaMask); - SDL_WriteLE32(dst, bV4CSType); - for (i = 0; i < 3 * 3; i++) { - SDL_WriteLE32(dst, bV4Endpoints[i]); + if (!SDL_WriteU32LE(dst, bV4RedMask) || + !SDL_WriteU32LE(dst, bV4GreenMask) || + !SDL_WriteU32LE(dst, bV4BlueMask) || + !SDL_WriteU32LE(dst, bV4AlphaMask) || + !SDL_WriteU32LE(dst, bV4CSType)) { + goto done; + } + for (i = 0; i < 3 * 3; i++) { + if (!SDL_WriteU32LE(dst, bV4Endpoints[i])) { + goto done; + } + } + if (!SDL_WriteU32LE(dst, bV4GammaRed) || + !SDL_WriteU32LE(dst, bV4GammaGreen) || + !SDL_WriteU32LE(dst, bV4GammaBlue)) { + goto done; } - SDL_WriteLE32(dst, bV4GammaRed); - SDL_WriteLE32(dst, bV4GammaGreen); - SDL_WriteLE32(dst, bV4GammaBlue); } /* Write the palette (in BGR color order) */ @@ -818,21 +840,25 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) 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); - SDL_RWwrite(dst, &colors[i].g, 1); - SDL_RWwrite(dst, &colors[i].r, 1); - SDL_RWwrite(dst, &colors[i].a, 1); + if (!SDL_WriteU8(dst, colors[i].b) || + !SDL_WriteU8(dst, colors[i].g) || + !SDL_WriteU8(dst, colors[i].r) || + !SDL_WriteU8(dst, colors[i].a)) { + goto done; + } } } /* Write the bitmap offset */ bfOffBits = (Uint32)(SDL_RWtell(dst) - fp_offset); if (SDL_RWseek(dst, fp_offset + 10, SDL_RW_SEEK_SET) < 0) { - SDL_Error(SDL_EFSEEK); + goto done; + } + if (!SDL_WriteU32LE(dst, bfOffBits)) { + goto done; } - SDL_WriteLE32(dst, bfOffBits); if (SDL_RWseek(dst, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) { - SDL_Error(SDL_EFSEEK); + goto done; } /* Write the bitmap image upside down */ @@ -841,38 +867,53 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) while (bits > (Uint8 *)intermediate_surface->pixels) { bits -= intermediate_surface->pitch; if (SDL_RWwrite(dst, bits, bw) != bw) { - SDL_Error(SDL_EFWRITE); - break; + goto done; } if (pad) { const Uint8 padbyte = 0; for (i = 0; i < pad; ++i) { - SDL_RWwrite(dst, &padbyte, 1); + if (!SDL_WriteU8(dst, padbyte)) { + goto done; + } } } } /* Write the BMP file size */ - bfSize = (Uint32)(SDL_RWtell(dst) - fp_offset); - if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) { - SDL_Error(SDL_EFSEEK); + new_offset = SDL_RWtell(dst); + if (new_offset < 0) { + goto done; + } + bfSize = (Uint32)(new_offset - fp_offset); + if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) { + goto done; + } + if (!SDL_WriteU32LE(dst, bfSize)) { + goto done; } - SDL_WriteLE32(dst, bfSize); if (SDL_RWseek(dst, fp_offset + bfSize, SDL_RW_SEEK_SET) < 0) { - SDL_Error(SDL_EFSEEK); + goto done; } /* Close it up.. */ SDL_UnlockSurface(intermediate_surface); - if (intermediate_surface != surface) { - SDL_DestroySurface(intermediate_surface); - } + + was_error = SDL_FALSE; } - if (freedst && dst) { - SDL_RWclose(dst); +done: + if (intermediate_surface && intermediate_surface != surface) { + SDL_DestroySurface(intermediate_surface); } - return (SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1; + if (freedst && dst) { + if (SDL_RWclose(dst) < 0) { + was_error = SDL_TRUE; + } + } + if (was_error) { + return -1; + } + return 0; } int SDL_SaveBMP(SDL_Surface *surface, const char *file) diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c index 90941fb6..7c31a24b 100644 --- a/src/video/SDL_pixels.c +++ b/src/video/SDL_pixels.c @@ -140,6 +140,12 @@ SDL_bool SDL_GetMasksForPixelFormatEnum(Uint32 format, int *bpp, Uint32 *Rmask, #if SDL_HAVE_YUV /* Partial support for SDL_Surface with FOURCC */ + if (SDL_ISPIXELFORMAT_FOURCC(format)) { + /* Not a format that uses masks */ + *bpp = 0; + *Rmask = *Gmask = *Bmask = *Amask = 0; + return SDL_TRUE; + } #else if (SDL_ISPIXELFORMAT_FOURCC(format)) { SDL_SetError("SDL not built with YUV support"); @@ -181,11 +187,6 @@ SDL_bool SDL_GetMasksForPixelFormatEnum(Uint32 format, int *bpp, Uint32 *Rmask, return SDL_TRUE; } - if (SDL_ISPIXELFORMAT_FOURCC(format)) { - /* Not a format that uses masks */ - return SDL_TRUE; - } - if (SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED8 && SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED16 && SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED32) { @@ -314,10 +315,8 @@ Uint32 SDL_GetPixelFormatEnumForMasks(int bpp, Uint32 Rmask, Uint32 Gmask, Uint3 Bmask == 0x03 && Amask == 0x00) { return SDL_PIXELFORMAT_RGB332; - } else { - return SDL_PIXELFORMAT_INDEX8; } - break; + return SDL_PIXELFORMAT_INDEX8; case 12: if (Rmask == 0) { return SDL_PIXELFORMAT_RGB444; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index d4eedd2a..26d39120 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -354,6 +354,9 @@ struct SDL_VideoDevice /* Tell window that app enabled drag'n'drop events */ void (*AcceptDragAndDrop)(SDL_Window *window, SDL_bool accept); + /* Display the system-level window menu */ + void (*ShowWindowSystemMenu)(SDL_Window *window, int x, int y); + /* * * */ /* Data common to all drivers */ SDL_threadID thread; @@ -363,7 +366,7 @@ struct SDL_VideoDevice SDL_Window *wakeup_window; SDL_Mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */ int num_displays; - SDL_VideoDisplay *displays; + SDL_VideoDisplay **displays; SDL_Window *windows; SDL_Window *grabbed_window; Uint8 window_magic; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 82bf6e8a..708cbc37 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -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 */ @@ -118,12 +119,12 @@ static VideoBootStrap *bootstrap[] = { #ifdef SDL_VIDEO_DRIVER_QNX &QNX_bootstrap, #endif -#ifdef SDL_VIDEO_DRIVER_OFFSCREEN - &OFFSCREEN_bootstrap, -#endif #ifdef SDL_VIDEO_DRIVER_NGAGE &NGAGE_bootstrap, #endif +#ifdef SDL_VIDEO_DRIVER_OFFSCREEN + &OFFSCREEN_bootstrap, +#endif #ifdef SDL_VIDEO_DRIVER_DUMMY &DUMMY_bootstrap, #ifdef SDL_INPUT_LINUXEV @@ -462,7 +463,7 @@ int SDL_VideoInit(const char *driver_name) goto pre_driver_error; } init_keyboard = SDL_TRUE; - if (SDL_InitMouse() < 0) { + if (SDL_PreInitMouse() < 0) { goto pre_driver_error; } init_mouse = SDL_TRUE; @@ -558,6 +559,8 @@ int SDL_VideoInit(const char *driver_name) SDL_StartTextInput(); } + SDL_PostInitMouse(); + /* We're ready to go! */ return 0; @@ -640,57 +643,51 @@ SDL_DisplayID SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode) SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event) { - SDL_VideoDisplay *displays, *new_display; - SDL_DisplayID id = 0; + SDL_VideoDisplay **displays, *new_display; + SDL_DisplayID id; + int i; - displays = (SDL_VideoDisplay *)SDL_malloc((_this->num_displays + 1) * sizeof(*displays)); - if (displays) { - int i; - - if (_this->displays) { - /* The display list may contain self-referential pointers to the desktop mode. */ - SDL_memcpy(displays, _this->displays, _this->num_displays * sizeof(*displays)); - for (i = 0; i < _this->num_displays; ++i) { - if (displays[i].current_mode == &_this->displays[i].desktop_mode) { - displays[i].current_mode = &displays[i].desktop_mode; - } - } - - SDL_free(_this->displays); - } - - _this->displays = displays; - id = _this->next_object_id++; - new_display = &displays[_this->num_displays++]; - - SDL_memcpy(new_display, display, sizeof(*new_display)); - new_display->id = id; - new_display->device = _this; - if (display->name) { - new_display->name = SDL_strdup(display->name); - } else { - char name[32]; - - SDL_itoa(id, name, 10); - new_display->name = SDL_strdup(name); - } - if (new_display->content_scale == 0.0f) { - new_display->content_scale = 1.0f; - } - - new_display->desktop_mode.displayID = id; - new_display->current_mode = &new_display->desktop_mode; - SDL_FinalizeDisplayMode(&new_display->desktop_mode); - - for (i = 0; i < new_display->num_fullscreen_modes; ++i) { - new_display->fullscreen_modes[i].displayID = id; - } - - if (send_event) { - SDL_SendDisplayEvent(new_display, SDL_EVENT_DISPLAY_CONNECTED, 0); - } - } else { + new_display = (SDL_VideoDisplay *)SDL_malloc(sizeof(*new_display)); + if (!new_display) { SDL_OutOfMemory(); + return 0; + } + + displays = (SDL_VideoDisplay **)SDL_realloc(_this->displays, (_this->num_displays + 1) * sizeof(*displays)); + if (!displays) { + SDL_OutOfMemory(); + SDL_free(new_display); + return 0; + } + _this->displays = displays; + _this->displays[_this->num_displays++] = new_display; + + id = _this->next_object_id++; + SDL_memcpy(new_display, display, sizeof(*new_display)); + new_display->id = id; + new_display->device = _this; + if (display->name) { + new_display->name = SDL_strdup(display->name); + } else { + char name[32]; + + SDL_itoa(id, name, 10); + new_display->name = SDL_strdup(name); + } + if (new_display->content_scale == 0.0f) { + new_display->content_scale = 1.0f; + } + + new_display->desktop_mode.displayID = id; + new_display->current_mode = &new_display->desktop_mode; + SDL_FinalizeDisplayMode(&new_display->desktop_mode); + + for (i = 0; i < new_display->num_fullscreen_modes; ++i) { + new_display->fullscreen_modes[i].displayID = id; + } + + if (send_event) { + SDL_SendDisplayEvent(new_display, SDL_EVENT_DISPLAY_CONNECTED, 0); } return id; } @@ -713,7 +710,7 @@ void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event) return; } - display = &_this->displays[display_index]; + display = _this->displays[display_index]; if (send_event) { SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_DISCONNECTED, 0); @@ -725,6 +722,7 @@ void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event) display->desktop_mode.driverdata = NULL; SDL_free(display->driverdata); display->driverdata = NULL; + SDL_free(display); if (display_index < (_this->num_displays - 1)) { SDL_memmove(&_this->displays[display_index], &_this->displays[display_index + 1], (_this->num_displays - display_index - 1) * sizeof(_this->displays[display_index])); @@ -753,7 +751,7 @@ SDL_DisplayID *SDL_GetDisplays(int *count) } for (i = 0; i < _this->num_displays; ++i) { - displays[i] = _this->displays[i].id; + displays[i] = _this->displays[i]->id; } displays[i] = 0; } else { @@ -774,7 +772,7 @@ SDL_VideoDisplay *SDL_GetVideoDisplay(SDL_DisplayID displayID) if (display_index < 0) { return NULL; } - return &_this->displays[display_index]; + return _this->displays[display_index]; } SDL_VideoDisplay *SDL_GetVideoDisplayForWindow(SDL_Window *window) @@ -788,7 +786,7 @@ SDL_DisplayID SDL_GetPrimaryDisplay(void) SDL_UninitializedVideo(); return 0; } - return _this->displays[0].id; + return _this->displays[0]->id; } int SDL_GetDisplayIndex(SDL_DisplayID displayID) @@ -800,7 +798,7 @@ int SDL_GetDisplayIndex(SDL_DisplayID displayID) } for (display_index = 0; display_index < _this->num_displays; ++display_index) { - if (displayID == _this->displays[display_index].id) { + if (displayID == _this->displays[display_index]->id) { return display_index; } } @@ -851,7 +849,7 @@ int SDL_GetDisplayBounds(SDL_DisplayID displayID, SDL_Rect *rect) rect->x = 0; rect->y = 0; } else { - SDL_GetDisplayBounds(_this->displays[SDL_GetDisplayIndex(displayID) - 1].id, rect); + SDL_GetDisplayBounds(_this->displays[SDL_GetDisplayIndex(displayID) - 1]->id, rect); rect->x += rect->w; } rect->w = display->current_mode->w; @@ -1254,7 +1252,7 @@ static SDL_DisplayID GetDisplayForRect(int x, int y, int w, int h) if (_this) { for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; SDL_Rect display_rect; SDL_GetDisplayBounds(display->id, &display_rect); @@ -1388,14 +1386,14 @@ static void SDL_CheckWindowDisplayChanged(SDL_Window *window) /* Sanity check our fullscreen windows */ display_index = SDL_GetDisplayIndex(displayID); for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; if (display->fullscreen_window == window) { if (display_index != i) { if (display_index < 0) { display_index = i; } else { - SDL_VideoDisplay *new_display = &_this->displays[display_index]; + SDL_VideoDisplay *new_display = _this->displays[display_index]; /* The window was moved to a different display */ if (new_display->fullscreen_window && @@ -1487,7 +1485,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) } } else { for (i = 0; i < _this->num_displays; ++i) { - display = &_this->displays[i]; + display = _this->displays[i]; if (display->fullscreen_window == window) { break; } @@ -1526,7 +1524,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) } } else if (fullscreen && window->last_fullscreen_exclusive_display && !window->fullscreen_exclusive) { for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *last_display = &_this->displays[i]; + SDL_VideoDisplay *last_display = _this->displays[i]; if (last_display->fullscreen_window == window) { SDL_SetDisplayModeForDisplay(last_display, NULL); if (_this->SetWindowFullscreen) { @@ -1582,7 +1580,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) /* Restore the video mode on other displays if needed */ for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *other = &_this->displays[i]; + SDL_VideoDisplay *other = _this->displays[i]; if (other != display && other->fullscreen_window == window) { SDL_SetDisplayModeForDisplay(other, NULL); if (_this->SetWindowFullscreen) { @@ -3731,7 +3729,7 @@ void SDL_VideoQuit(void) _this->VideoQuit(_this); for (i = _this->num_displays; i--; ) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; SDL_DelVideoDisplay(display->id, SDL_FALSE); } if (_this->displays) { @@ -5056,6 +5054,19 @@ SDL_bool SDL_ShouldAllowTopmost(void) return SDL_GetHintBoolean(SDL_HINT_ALLOW_TOPMOST, SDL_TRUE); } +int SDL_ShowWindowSystemMenu(SDL_Window *window, int x, int y) +{ + CHECK_WINDOW_MAGIC(window, -1) + CHECK_WINDOW_NOT_POPUP(window, -1) + + if (_this->ShowWindowSystemMenu) { + _this->ShowWindowSystemMenu(window, x, y); + return 0; + } + + return SDL_Unsupported(); +} + int SDL_SetWindowHitTest(SDL_Window *window, SDL_HitTest callback, void *callback_data) { CHECK_WINDOW_MAGIC(window, -1); diff --git a/src/video/android/SDL_androidevents.c b/src/video/android/SDL_androidevents.c index e6672552..8dbe13dd 100644 --- a/src/video/android/SDL_androidevents.c +++ b/src/video/android/SDL_androidevents.c @@ -108,7 +108,7 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this) ANDROIDAUDIO_PauseDevices(); openslES_PauseDevices(); - aaudio_PauseDevices(); + AAUDIO_PauseDevices(); if (SDL_WaitSemaphore(Android_ResumeSem) == 0) { @@ -119,7 +119,7 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this) ANDROIDAUDIO_ResumeDevices(); openslES_ResumeDevices(); - aaudio_ResumeDevices(); + AAUDIO_ResumeDevices(); /* Restore the GL Context from here, as this operation is thread dependent */ #ifdef SDL_VIDEO_OPENGL_EGL @@ -160,9 +160,9 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this) } } - if (aaudio_DetectBrokenPlayState()) { - aaudio_PauseDevices(); - aaudio_ResumeDevices(); + if (AAUDIO_DetectBrokenPlayState()) { + AAUDIO_PauseDevices(); + AAUDIO_ResumeDevices(); } } @@ -187,7 +187,7 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this) if (videodata->pauseAudio) { ANDROIDAUDIO_PauseDevices(); openslES_PauseDevices(); - aaudio_PauseDevices(); + AAUDIO_PauseDevices(); } backup_context = 0; @@ -203,7 +203,7 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this) if (videodata->pauseAudio) { ANDROIDAUDIO_ResumeDevices(); openslES_ResumeDevices(); - aaudio_ResumeDevices(); + AAUDIO_ResumeDevices(); } #ifdef SDL_VIDEO_OPENGL_EGL @@ -246,9 +246,9 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this) } } - if (aaudio_DetectBrokenPlayState()) { - aaudio_PauseDevices(); - aaudio_ResumeDevices(); + if (AAUDIO_DetectBrokenPlayState()) { + AAUDIO_PauseDevices(); + AAUDIO_ResumeDevices(); } } diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index 021607ce..ede5b1c9 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/src/video/android/SDL_androidvideo.c @@ -268,7 +268,7 @@ void Android_SendResize(SDL_Window *window) */ SDL_VideoDevice *device = SDL_GetVideoDevice(); if (device && device->num_displays > 0) { - SDL_VideoDisplay *display = &device->displays[0]; + SDL_VideoDisplay *display = device->displays[0]; SDL_DisplayMode desktop_mode; SDL_zero(desktop_mode); diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index 5e0c3e49..221a61d9 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -255,7 +255,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) SDL_Window *window = device->windows; int i; for (i = 0; i < device->num_displays; ++i) { - SDL_Window *fullscreen_window = device->displays[i].fullscreen_window; + SDL_Window *fullscreen_window = device->displays[i]->fullscreen_window; if (fullscreen_window) { if (fullscreen_window->flags & SDL_WINDOW_MINIMIZED) { SDL_RestoreWindow(fullscreen_window); diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m index e6b90b85..34e9c2d5 100644 --- a/src/video/cocoa/SDL_cocoamodes.m +++ b/src/video/cocoa/SDL_cocoamodes.m @@ -520,7 +520,7 @@ void Cocoa_QuitModes(SDL_VideoDevice *_this) int i, j; for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; SDL_DisplayModeData *mode; if (display->current_mode->driverdata != display->desktop_mode.driverdata) { diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 3bdcb22e..10071cdf 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -2467,9 +2467,9 @@ SDL_DisplayID Cocoa_GetDisplayForWindow(SDL_VideoDevice *_this, SDL_Window *wind displayid = [[screen.deviceDescription objectForKey:@"NSScreenNumber"] unsignedIntValue]; for (i = 0; i < _this->num_displays; i++) { - SDL_DisplayData *displaydata = _this->displays[i].driverdata; + SDL_DisplayData *displaydata = _this->displays[i]->driverdata; if (displaydata != NULL && displaydata->display == displayid) { - return _this->displays[i].id; + return _this->displays[i]->id; } } } diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index 9ca1b5da..e053f483 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -155,9 +155,12 @@ class SDL_BWin : public BWindow void UpdateCurrentView() { +#ifdef SDL_VIDEO_OPENGL if (_SDL_GLView != NULL) { SetCurrentView(_SDL_GLView); - } else if (_SDL_View != NULL) { + } else +#endif + if (_SDL_View != NULL) { SetCurrentView(_SDL_View); } else { SetCurrentView(NULL); @@ -454,10 +457,13 @@ class SDL_BWin : public BWindow 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) { +#ifdef SDL_VIDEO_OPENGL + if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) { _SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN); + } else +#endif + if (_SDL_View != NULL && _cur_view == _SDL_View) { + _SDL_View->Draw(Bounds()); } } break; diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 927af657..5312a584 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -188,7 +188,7 @@ static float CalculateRefreshRate(drmModeModeInfo *mode) den *= mode->vscan; } - return ((100 * num) / den) / 100.0f; + return ((100 * (Sint64)num) / den) / 100.0f; } static int KMSDRM_Available(void) diff --git a/src/video/n3ds/SDL_n3dsvideo.c b/src/video/n3ds/SDL_n3dsvideo.c index eb669fe0..74b52071 100644 --- a/src/video/n3ds/SDL_n3dsvideo.c +++ b/src/video/n3ds/SDL_n3dsvideo.c @@ -48,7 +48,6 @@ struct SDL_DisplayData static void N3DS_DeleteDevice(SDL_VideoDevice *device) { - SDL_free(device->displays); SDL_free(device->driverdata); SDL_free(device); } diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m index 4b93b8d2..e9d6ca33 100644 --- a/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/video/uikit/SDL_uikitappdelegate.m @@ -79,7 +79,7 @@ int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserv return exit_status; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR /* Load a launch image using the old UILaunchImageFile-era naming rules. */ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) { @@ -142,8 +142,10 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) self.storyboardViewController.view.frame = self.view.bounds; [self.storyboardViewController didMoveToParentViewController:self]; +#if !TARGET_OS_XR UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden; UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle; +#endif } - (BOOL)prefersStatusBarHidden @@ -210,11 +212,18 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"]; NSString *imagename = nil; UIImage *image = nil; - + +#if TARGET_OS_XR + int screenw = SDL_XR_SCREENWIDTH; + int screenh = SDL_XR_SCREENHEIGHT; +#else int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5); int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5); +#endif -#if !TARGET_OS_TV + + +#if !TARGET_OS_TV && !TARGET_OS_XR UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation; /* We always want portrait-oriented size, to match UILaunchImageSize. */ @@ -244,7 +253,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) } } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; NSString *orientstring = dict[@"UILaunchImageOrientation"]; @@ -273,7 +282,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) image = [UIImage imageNamed:imagename]; } } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR else { imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"]; @@ -288,10 +297,15 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) #endif if (image) { - UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; +#if TARGET_OS_XR + CGRect viewFrame = CGRectMake(0, 0, screenw, screenh); +#else + CGRect viewFrame = [UIScreen mainScreen].bounds; +#endif + UIImageView *view = [[UIImageView alloc] initWithFrame:viewFrame]; UIImageOrientation imageorient = UIImageOrientationUp; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR /* Bugs observed / workaround tested in iOS 8.3. */ if (UIInterfaceOrientationIsLandscape(curorient)) { if (image.size.width < image.size.height) { @@ -420,7 +434,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) NSString *screenname = nil; /* tvOS only uses a plain launch image. */ -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"]; if (screenname) { @@ -443,7 +457,12 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) } if (vc.view) { - launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; +#if TARGET_OS_XR + CGRect viewFrame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT); +#else + CGRect viewFrame = [UIScreen mainScreen].bounds; +#endif + launchWindow = [[UIWindow alloc] initWithFrame:viewFrame]; /* We don't want the launch window immediately hidden when a real SDL * window is shown - we fade it out ourselves when we're ready. */ diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index 4bec9685..8913c3da 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -57,7 +57,7 @@ static BOOL UIKit_EventPumpEnabled = YES; [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 +#if !TARGET_OS_TV && !TARGET_OS_XR [notificationCenter addObserver:self selector:@selector(applicationDidChangeStatusBarOrientation) name:UIApplicationDidChangeStatusBarOrientationNotification @@ -99,7 +99,7 @@ static BOOL UIKit_EventPumpEnabled = YES; SDL_OnApplicationDidReceiveMemoryWarning(); } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR - (void)applicationDidChangeStatusBarOrientation { SDL_OnApplicationDidChangeStatusBarOrientation(); diff --git a/src/video/uikit/SDL_uikitmessagebox.m b/src/video/uikit/SDL_uikitmessagebox.m index b0b612a1..e7d80ef7 100644 --- a/src/video/uikit/SDL_uikitmessagebox.m +++ b/src/video/uikit/SDL_uikitmessagebox.m @@ -98,7 +98,11 @@ static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messag } if (window == nil || window.rootViewController == nil) { +#if TARGET_OS_XR + alertwindow = [[UIWindow alloc] init]; +#else alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; +#endif alertwindow.rootViewController = [UIViewController new]; alertwindow.windowLevel = UIWindowLevelAlert; diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m index c82a4dce..c5317ebd 100644 --- a/src/video/uikit/SDL_uikitmetalview.m +++ b/src/video/uikit/SDL_uikitmetalview.m @@ -81,6 +81,7 @@ SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window) CGFloat scale = 1.0; SDL_uikitmetalview *metalview; +#if !TARGET_OS_XR if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { /* Set the scale to the natural scale factor of the screen - then * the backing dimensions of the Metal view will match the pixel @@ -89,6 +90,7 @@ SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window) */ scale = data.uiwindow.screen.nativeScale; } +#endif metalview = [[SDL_uikitmetalview alloc] initWithFrame:data.uiwindow.bounds scale:scale]; diff --git a/src/video/uikit/SDL_uikitmodes.h b/src/video/uikit/SDL_uikitmodes.h index a744febb..b92f1901 100644 --- a/src/video/uikit/SDL_uikitmodes.h +++ b/src/video/uikit/SDL_uikitmodes.h @@ -27,26 +27,39 @@ @interface SDL_UIKitDisplayData : NSObject +#if !TARGET_OS_XR - (instancetype)initWithScreen:(UIScreen *)screen; - @property(nonatomic, strong) UIScreen *uiscreen; +#endif @end @interface SDL_UIKitDisplayModeData : NSObject - +#if !TARGET_OS_XR @property(nonatomic, strong) UIScreenMode *uiscreenmode; +#endif @end +#if !TARGET_OS_XR extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen); +#endif extern int UIKit_InitModes(SDL_VideoDevice *_this); +#if !TARGET_OS_XR extern int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event); extern void UIKit_DelDisplay(UIScreen *uiscreen); +#endif extern int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display); extern int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); extern void UIKit_QuitModes(SDL_VideoDevice *_this); extern int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect); +// because visionOS does not have a screen +// we create a fake 1080p display to maintain compatibility. +#if TARGET_OS_XR +#define SDL_XR_SCREENWIDTH 1920 +#define SDL_XR_SCREENHEIGHT 1080 +#endif + #endif /* SDL_uikitmodes_h_ */ diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m index 06141034..e397e97a 100644 --- a/src/video/uikit/SDL_uikitmodes.m +++ b/src/video/uikit/SDL_uikitmodes.m @@ -30,6 +30,7 @@ @implementation SDL_UIKitDisplayData +#if !TARGET_OS_XR - (instancetype)initWithScreen:(UIScreen *)screen { if (self = [super init]) { @@ -37,20 +38,23 @@ } return self; } - @synthesize uiscreen; +#endif @end @implementation SDL_UIKitDisplayModeData +#if !TARGET_OS_XR @synthesize uiscreenmode; +#endif @end @interface SDL_DisplayWatch : NSObject @end +#if !TARGET_OS_XR @implementation SDL_DisplayWatch + (void)start @@ -92,7 +96,9 @@ } @end +#endif +#if !TARGET_OS_XR static int UIKit_AllocateDisplayModeData(SDL_DisplayMode *mode, UIScreenMode *uiscreenmode) { @@ -112,6 +118,7 @@ static int UIKit_AllocateDisplayModeData(SDL_DisplayMode *mode, return 0; } +#endif static void UIKit_FreeDisplayModeData(SDL_DisplayMode *mode) { @@ -121,6 +128,7 @@ static void UIKit_FreeDisplayModeData(SDL_DisplayMode *mode) } } +#if !TARGET_OS_XR static float UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen) { #ifdef __IPHONE_10_3 @@ -235,7 +243,11 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event) display.desktop_mode = mode; /* Allocate the display data */ +#if TARGET_OS_XR + SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init]; +#else SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] initWithScreen:uiscreen]; +#endif if (!data) { UIKit_FreeDisplayModeData(&display.desktop_mode); return SDL_OutOfMemory(); @@ -247,6 +259,41 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event) } return 0; } +#endif + +#if TARGET_OS_XR +int UIKit_AddDisplay(SDL_bool send_event){ + CGSize size = CGSizeMake(SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT); + SDL_VideoDisplay display; + SDL_DisplayMode mode; + + SDL_zero(mode); + mode.w = (int)size.width; + mode.h = (int)size.height; + mode.pixel_density = 1; + mode.format = SDL_PIXELFORMAT_ABGR8888; + mode.refresh_rate = 60; + + display.natural_orientation = SDL_ORIENTATION_LANDSCAPE; + + display.desktop_mode = mode; + + SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init]; + + if (!data) { + UIKit_FreeDisplayModeData(&display.desktop_mode); + return SDL_OutOfMemory(); + } + + display.driverdata = (SDL_DisplayData *)CFBridgingRetain(data); + if (SDL_AddVideoDisplay(&display, send_event) == 0) { + return -1; + } + return 0; +} +#endif + +#if !TARGET_OS_XR void UIKit_DelDisplay(UIScreen *uiscreen) { @@ -281,20 +328,27 @@ SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen) return (size.width > size.height); } } - +#endif int UIKit_InitModes(SDL_VideoDevice *_this) { @autoreleasepool { +#if TARGET_OS_XR + UIKit_AddDisplay(SDL_FALSE); +#else for (UIScreen *uiscreen in [UIScreen screens]) { if (UIKit_AddDisplay(uiscreen, SDL_FALSE) < 0) { return -1; } } -#if !TARGET_OS_TV +#endif + +#if !TARGET_OS_TV && !TARGET_OS_XR SDL_OnApplicationDidChangeStatusBarOrientation(); #endif +#if !TARGET_OS_XR [SDL_DisplayWatch start]; +#endif } return 0; @@ -302,6 +356,7 @@ int UIKit_InitModes(SDL_VideoDevice *_this) int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) { +#if !TARGET_OS_XR @autoreleasepool { SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata; @@ -331,11 +386,13 @@ int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) UIKit_AddDisplayMode(display, w, h, data.uiscreen, uimode, addRotation); } } +#endif return 0; } int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { +#if !TARGET_OS_XR @autoreleasepool { SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata; @@ -359,7 +416,7 @@ int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_ } } } - +#endif return 0; } @@ -367,7 +424,11 @@ int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *displ { @autoreleasepool { SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata; +#if TARGET_OS_XR + CGRect frame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT); +#else CGRect frame = data.uiscreen.bounds; +#endif /* the default function iterates displays to make a fake offset, as if all the displays were side-by-side, which is fine for iOS. */ @@ -386,13 +447,15 @@ int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *displ void UIKit_QuitModes(SDL_VideoDevice *_this) { +#if !TARGET_OS_XR [SDL_DisplayWatch stop]; +#endif /* Release Objective-C objects, so higher level doesn't free() them. */ int i, j; @autoreleasepool { for (i = 0; i < _this->num_displays; i++) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; UIKit_FreeDisplayModeData(&display->desktop_mode); for (j = 0; j < display->num_fullscreen_modes; j++) { @@ -408,7 +471,7 @@ void UIKit_QuitModes(SDL_VideoDevice *_this) } } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR void SDL_OnApplicationDidChangeStatusBarOrientation(void) { BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation); diff --git a/src/video/uikit/SDL_uikitvideo.h b/src/video/uikit/SDL_uikitvideo.h index 60ee2a9f..f1382229 100644 --- a/src/video/uikit/SDL_uikitvideo.h +++ b/src/video/uikit/SDL_uikitvideo.h @@ -33,7 +33,11 @@ @end +#if TARGET_OS_XR +CGRect UIKit_ComputeViewFrame(SDL_Window *window); +#else CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen); +#endif #endif /* __OBJC__ */ diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m index 51bef011..0b07afb0 100644 --- a/src/video/uikit/SDL_uikitvideo.m +++ b/src/video/uikit/SDL_uikitvideo.m @@ -52,7 +52,9 @@ static void UIKit_VideoQuit(SDL_VideoDevice *_this); static void UIKit_DeleteDevice(SDL_VideoDevice *device) { @autoreleasepool { - CFRelease(device->driverdata); + if (device->driverdata){ + CFRelease(device->driverdata); + } SDL_free(device); } } @@ -183,6 +185,7 @@ SDL_bool UIKit_IsSystemVersionAtLeast(double version) SDL_SystemTheme UIKit_GetSystemTheme(void) { +#if !TARGET_OS_XR if (@available(iOS 12.0, tvOS 10.0, *)) { switch ([UIScreen mainScreen].traitCollection.userInterfaceStyle) { case UIUserInterfaceStyleDark: @@ -193,9 +196,15 @@ SDL_SystemTheme UIKit_GetSystemTheme(void) break; } } +#endif return SDL_SYSTEM_THEME_UNKNOWN; } +#if TARGET_OS_XR +CGRect UIKit_ComputeViewFrame(SDL_Window *window){ + return CGRectMake(window->x, window->y, window->w, window->h); +} +#else CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) { SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata; @@ -234,6 +243,8 @@ CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) return frame; } +#endif + void UIKit_ForceUpdateHomeIndicator(void) { #if !TARGET_OS_TV diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m index 354b91e8..e3c92156 100644 --- a/src/video/uikit/SDL_uikitview.m +++ b/src/video/uikit/SDL_uikitview.m @@ -417,6 +417,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick; SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_PRESSED, scancode); } } + if (SDL_TextInputActive()) { + [super pressesBegan:presses withEvent:event]; + } } - (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event @@ -427,6 +430,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick; SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode); } } + if (SDL_TextInputActive()) { + [super pressesEnded:presses withEvent:event]; + } } - (void)pressesCancelled:(NSSet *)presses withEvent:(UIPressesEvent *)event @@ -437,11 +443,17 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick; SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode); } } + if (SDL_TextInputActive()) { + [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_TextInputActive()) { + [super pressesChanged:presses withEvent:event]; + } } #endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */ diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index 497c8245..dfebb086 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -63,11 +63,11 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char @implementation SDLUITextField : UITextField - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { - if (action == @selector(paste:)) { - return NO; - } + if (action == @selector(paste:)) { + return NO; + } - return [super canPerformAction:action withSender:sender]; + return [super canPerformAction:action withSender:sender]; } @end @@ -82,6 +82,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char SDLUITextField *textField; BOOL hardwareKeyboard; BOOL showingKeyboard; + BOOL hidingKeyboard; BOOL rotatingOrientation; NSString *committedText; NSString *obligateForBackspace; @@ -99,6 +100,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [self initKeyboard]; hardwareKeyboard = NO; showingKeyboard = NO; + hidingKeyboard = NO; rotatingOrientation = NO; #endif @@ -160,7 +162,9 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char { displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)]; -#ifdef __IPHONE_10_3 +#if TARGET_OS_XR + displayLink.preferredFramesPerSecond = 90 / animationInterval; //TODO: Get frame max frame rate on visionOS +#elif defined(__IPHONE_10_3) SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata; if ([displayLink respondsToSelector:@selector(preferredFramesPerSecond)] && data != nil && data.uiwindow != nil && [data.uiwindow.screen respondsToSelector:@selector(maximumFramesPerSecond)]) { @@ -292,7 +296,18 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; - [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification 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:) @@ -363,7 +378,15 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [center removeObserver:self name:UIKeyboardWillShowNotification object:nil]; - [center removeObserver:self name:UIKeyboardWillHideNotification 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 @@ -373,23 +396,40 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char /* 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_TextInputActive() && !hidingKeyboard && !rotatingOrientation) { + shouldStartTextInput = YES; + } + + showingKeyboard = YES; #if !TARGET_OS_TV CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; @@ -399,14 +439,36 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char [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_TextInputActive() && !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 @@ -425,8 +487,8 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]); while (deleteLength > 0) { /* Send distinct down and up events for each backspace action */ - SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_BACKSPACE); - SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_BACKSPACE); + SDL_SendVirtualKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_BACKSPACE); + SDL_SendVirtualKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_BACKSPACE); --deleteLength; } } @@ -451,7 +513,11 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char { CGAffineTransform t = self.view.transform; CGPoint offset = CGPointMake(0.0, 0.0); +#if TARGET_OS_XR + CGRect frame = UIKit_ComputeViewFrame(window); +#else CGRect frame = UIKit_ComputeViewFrame(window, self.view.window.screen); +#endif if (self.keyboardHeight) { int rectbottom = self.textInputRect.y + self.textInputRect.h; diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 13aa8646..ed8c6dcd 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -65,6 +65,7 @@ - (void)layoutSubviews { +#if !TARGET_OS_XR /* Workaround to fix window orientation issues in iOS 8. */ /* As of July 1 2019, I haven't been able to reproduce any orientation * issues with this disabled on iOS 12. The issue this is meant to fix might @@ -74,6 +75,7 @@ if (!UIKit_IsSystemVersionAtLeast(9.0)) { self.frame = self.screen.bounds; } +#endif [super layoutSubviews]; } @@ -84,8 +86,13 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->driverdata; SDL_uikitview *view; - + +#if TARGET_OS_XR + CGRect frame = UIKit_ComputeViewFrame(window); +#else CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen); +#endif + int width = (int)frame.size.width; int height = (int)frame.size.height; @@ -98,13 +105,15 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow data.uiwindow = uiwindow; +#if !TARGET_OS_XR if (displaydata.uiscreen != [UIScreen mainScreen]) { window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizable */ window->flags &= ~SDL_WINDOW_INPUT_FOCUS; /* never has input focus */ window->flags |= SDL_WINDOW_BORDERLESS; /* never has a status bar. */ } +#endif -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR 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 @@ -166,7 +175,7 @@ int UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the * user, so it's in standby), try to force the display to a resolution * that most closely matches the desired window size. */ -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR const CGSize origsize = data.uiscreen.currentMode.size; if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) { const SDL_DisplayMode *bestmode; @@ -197,12 +206,18 @@ int UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) /* ignore the size user requested, and make a fullscreen window */ /* !!! FIXME: can we have a smaller view? */ +#if TARGET_OS_XR + UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:CGRectMake(window->x, window->y, window->w, window->h)]; +#else UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds]; +#endif /* put the window on an external display if appropriate. */ +#if !TARGET_OS_XR if (data.uiscreen != [UIScreen mainScreen]) { [uiwindow setScreen:data.uiscreen]; } +#endif if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) { return -1; @@ -229,7 +244,10 @@ void UIKit_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) /* Make this window the current mouse focus for touch input */ SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->driverdata; - if (displaydata.uiscreen == [UIScreen mainScreen]) { +#if !TARGET_OS_XR + if (displaydata.uiscreen == [UIScreen mainScreen]) +#endif + { SDL_SetMouseFocus(window); SDL_SetKeyboardFocus(window); } @@ -258,7 +276,7 @@ static void UIKit_UpdateWindowBorder(SDL_VideoDevice *_this, SDL_Window *window) SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata; SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_XR if (data.uiwindow.screen == [UIScreen mainScreen]) { if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) { [UIApplication sharedApplication].statusBarHidden = YES; @@ -354,9 +372,11 @@ void UIKit_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int CGSize size = view.bounds.size; CGFloat scale = 1.0; +#if !TARGET_OS_XR if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { scale = windata.uiwindow.screen.nativeScale; } +#endif /* Integer truncation of fractional values matches SDL_uikitmetalview and * SDL_uikitopenglview. */ diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h index fa6b5003..76cfb295 100644 --- a/src/video/wayland/SDL_waylanddyn.h +++ b/src/video/wayland/SDL_waylanddyn.h @@ -158,6 +158,7 @@ void SDL_WAYLAND_UnloadSymbols(void); #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_show_window_menu (*WAYLAND_libdecor_frame_show_window_menu) #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_translate_coordinate (*WAYLAND_libdecor_frame_translate_coordinate) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 87b3c058..5a14655e 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -311,12 +311,25 @@ static SDL_bool keyboard_repeat_key_is_set(SDL_WaylandKeyboardRepeat *repeat_inf return repeat_info->is_initialized && repeat_info->is_key_down && key == repeat_info->key; } +static void sync_done_handler(void *data, struct wl_callback *callback, uint32_t callback_data) +{ + /* Nothing to do, just destroy the callback */ + wl_callback_destroy(callback); +} + +static struct wl_callback_listener sync_listener = { + sync_done_handler +}; + void Wayland_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window) { SDL_VideoData *d = _this->driverdata; - /* TODO: Maybe use a pipe to avoid the compositor roundtrip? */ - wl_display_sync(d->display); + /* Queue a sync event to unblock the event queue fd if it's empty and being waited on. + * TODO: Maybe use a pipe to avoid the compositor roundtrip? + */ + struct wl_callback *cb = wl_display_sync(d->display); + wl_callback_add_listener(cb, &sync_listener, NULL); WAYLAND_wl_display_flush(d->display); } @@ -541,6 +554,19 @@ static void pointer_handle_leave(void *data, struct wl_pointer *pointer, } if (input->pointer_focus) { + SDL_WindowData *wind = (SDL_WindowData *)wl_surface_get_user_data(surface); + + if (wind) { + /* Clear the capture flag and raise all buttons */ + wind->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + + SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_LEFT); + SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_RIGHT); + SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE); + SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_X1); + SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_X2); + } + SDL_SetMouseFocus(NULL); input->pointer_focus = NULL; } @@ -2705,6 +2731,9 @@ void Wayland_display_destroy_input(SDL_VideoData *d) if (input->primary_selection_device->selection_source != NULL) { Wayland_primary_selection_source_destroy(input->primary_selection_device->selection_source); } + if (input->primary_selection_device->primary_selection_device != NULL) { + zwp_primary_selection_device_v1_destroy(input->primary_selection_device->primary_selection_device); + } SDL_free(input->primary_selection_device); } diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h index 2d0eb735..494104b1 100644 --- a/src/video/wayland/SDL_waylandsym.h +++ b/src/video/wayland/SDL_waylandsym.h @@ -204,6 +204,7 @@ 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(void, libdecor_frame_show_window_menu, (struct libdecor_frame *, struct wl_seat *, uint32_t, int, int)) 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_translate_coordinate, (struct libdecor_frame *, int, int, int *, int *)) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index cc95df21..a891b907 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -209,6 +209,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void) device->SetWindowHitTest = Wayland_SetWindowHitTest; device->FlashWindow = Wayland_FlashWindow; device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport; + device->ShowWindowSystemMenu = Wayland_ShowWindowSystemMenu; #ifdef SDL_USE_LIBDBUS if (SDL_SystemTheme_Init()) @@ -672,6 +673,10 @@ static void Wayland_free_display(SDL_VideoDisplay *display) SDL_DisplayData *display_data = display->driverdata; int i; + if (display_data->xdg_output) { + zxdg_output_v1_destroy(display_data->xdg_output); + } + if (wl_output_get_version(display_data->output) >= WL_OUTPUT_RELEASE_SINCE_VERSION) { wl_output_release(display_data->output); } else { @@ -931,7 +936,7 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this) Wayland_FiniMouse(data); for (i = _this->num_displays - 1; i >= 0; --i) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; Wayland_free_display(display); } diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 58650e65..4568ecb4 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -2154,7 +2154,7 @@ int Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { int i; for (i = 0; i < _this->num_displays; i++) { - float scale = _this->displays[i].driverdata->scale_factor; + float scale = _this->displays[i]->driverdata->scale_factor; data->windowed_scale_factor = SDL_max(data->windowed_scale_factor, scale); } } @@ -2357,6 +2357,23 @@ void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window) WAYLAND_wl_display_flush(viddata->display); } +void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y) +{ + SDL_WindowData *wind = window->driverdata; +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_show_window_menu(wind->shell_surface.libdecor.frame, wind->waylandData->input->seat, wind->waylandData->input->last_implicit_grab_serial, x, y); + } + } else +#endif + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) { + if (wind->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_show_window_menu(wind->shell_surface.xdg.roleobj.toplevel, wind->waylandData->input->seat, wind->waylandData->input->last_implicit_grab_serial, x, y); + } + } +} + int Wayland_SuspendScreenSaver(SDL_VideoDevice *_this) { SDL_VideoData *data = _this->driverdata; diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 25e42fb2..98dc8b75 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -150,6 +150,7 @@ extern void Wayland_SetWindowMaximumSize(SDL_VideoDevice *_this, SDL_Window *win extern void Wayland_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h); extern int Wayland_SetWindowModalFor(SDL_VideoDevice *_this, SDL_Window *modal_window, SDL_Window *parent_window); extern void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); +extern void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y); extern void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window); extern int Wayland_SuspendScreenSaver(SDL_VideoDevice *_this); diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index f6f8f105..df80ba3f 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -352,18 +352,27 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI // 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 = _this->displays[i].driverdata; + SDL_DisplayData *driverdata = _this->displays[i]->driverdata; if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) { SDL_bool moved = (index != i); SDL_bool changed_bounds = SDL_FALSE; - if (moved) { - SDL_VideoDisplay tmp; + if (driverdata->state != DisplayRemoved) { + /* We've already enumerated this display, don't move it */ + return; + } - SDL_assert(index < _this->num_displays); - 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)); + if (index >= _this->num_displays) { + /* This should never happen due to the check above, but just in case... */ + return; + } + + if (moved) { + SDL_VideoDisplay *tmp; + + tmp = _this->displays[index]; + _this->displays[index] = _this->displays[i]; + _this->displays[i] = tmp; i = index; } @@ -371,7 +380,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI driverdata->state = DisplayUnchanged; if (!_this->setting_display_mode) { - SDL_VideoDisplay *existing_display = &_this->displays[i]; + SDL_VideoDisplay *existing_display = _this->displays[i]; SDL_Rect bounds; SDL_ResetFullscreenDisplayModes(existing_display); @@ -645,7 +654,7 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this) // 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 = _this->displays[i].driverdata; + SDL_DisplayData *driverdata = _this->displays[i]->driverdata; driverdata->state = DisplayRemoved; } @@ -656,7 +665,7 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this) // 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_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; SDL_DisplayData *driverdata = display->driverdata; if (driverdata->state == DisplayRemoved) { SDL_DelVideoDisplay(display->id, SDL_TRUE); @@ -665,7 +674,7 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this) // Send events for any newly added displays for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; + SDL_VideoDisplay *display = _this->displays[i]; SDL_DisplayData *driverdata = display->driverdata; if (driverdata->state == DisplayAdded) { SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_CONNECTED, 0); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index bb7fe152..52bbb8e6 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -207,6 +207,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void) device->SetWindowHitTest = WIN_SetWindowHitTest; device->AcceptDragAndDrop = WIN_AcceptDragAndDrop; device->FlashWindow = WIN_FlashWindow; + device->ShowWindowSystemMenu = WIN_ShowWindowSystemMenu; device->shape_driver.CreateShaper = Win32_CreateShaper; device->shape_driver.SetWindowShape = Win32_SetWindowShape; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index c49bda24..6218078e 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -51,6 +51,14 @@ typedef HRESULT (WINAPI *DwmSetWindowAttribute_t)(HWND hwnd, DWORD dwAttribute, #define SWP_NOCOPYBITS 0 #endif +/* An undocumented message to create a popup system menu + * - wParam is always 0 + * - lParam = MAKELONG(x, y) where x and y are the screen coordinates where the menu should be displayed + */ +#ifndef WM_POPUPSYSTEMMENU +#define WM_POPUPSYSTEMMENU 0x313 +#endif + /* #define HIGHDPI_DEBUG */ /* Fake window to help with DirectInput events. */ @@ -845,7 +853,6 @@ void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) { DWORD style; HWND hwnd; - int nCmdShow; SDL_bool bActivate = SDL_GetHintBoolean(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, SDL_TRUE); @@ -855,13 +862,16 @@ void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) } hwnd = window->driverdata->hwnd; - nCmdShow = bActivate ? SW_SHOW : SW_SHOWNA; style = GetWindowLong(hwnd, GWL_EXSTYLE); if (style & WS_EX_NOACTIVATE) { - nCmdShow = SW_SHOWNOACTIVATE; bActivate = SDL_FALSE; } - ShowWindow(hwnd, nCmdShow); + if (bActivate) { + ShowWindow(hwnd, SW_SHOW); + } else { + /* Use SetWindowPos instead of ShowWindow to avoid activating the parent window if this is a child window */ + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, window->driverdata->copybits_flag | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); + } if (window->flags & SDL_WINDOW_POPUP_MENU && bActivate) { if (window->parent == SDL_GetKeyboardFocus()) { @@ -1483,6 +1493,17 @@ int WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperati return 0; } + +void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y) +{ + const SDL_WindowData *data = window->driverdata; + POINT pt; + + pt.x = x; + pt.y = y; + ClientToScreen(data->hwnd, &pt); + SendMessage(data->hwnd, WM_POPUPSYSTEMMENU, 0, MAKELPARAM(pt.x, pt.y)); +} #endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ void WIN_UpdateDarkModeForHWND(HWND hwnd) diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index 956c5ec3..f6f0331a 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -108,6 +108,7 @@ extern void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept); extern int WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation); extern void WIN_UpdateDarkModeForHWND(HWND hwnd); extern int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags); +extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index d2ce6640..cc197227 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -467,8 +467,8 @@ static int X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data) 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]; + if (dev && dev->displays && dev->num_displays > 0) { + const SDL_VideoDisplay *dpy = dev->displays[0]; const SDL_DisplayData *dpydata = dpy->driverdata; x = dpydata->x + ((dpy->current_mode->w - data->dialog_width) / 2); y = dpydata->y + ((dpy->current_mode->h - data->dialog_height) / 3); diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index dad39d81..e8c0ad33 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -99,7 +99,7 @@ static void UpdateDisplayContentScale(float scale) if (viddevice) { for (i = 0; i < viddevice->num_displays; ++i) { - SDL_SetDisplayContentScale(&viddevice->displays[i], scale); + SDL_SetDisplayContentScale(viddevice->displays[i], scale); } } } @@ -821,8 +821,9 @@ int X11_InitModes(SDL_VideoDevice *_this) 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))) { - return X11_InitModes_XRandR(_this); + (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3)) && + X11_InitModes_XRandR(_this) == 0) { + return 0; } } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 1016a7ab..70cc85a3 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -84,7 +84,7 @@ static int X11_SafetyNetErrHandler(Display *d, XErrorEvent *e) if (device != NULL) { int i; for (i = 0; i < device->num_displays; i++) { - SDL_VideoDisplay *display = &device->displays[i]; + SDL_VideoDisplay *display = device->displays[i]; if (SDL_GetCurrentDisplayMode(display->id) != SDL_GetDesktopDisplayMode(display->id)) { X11_SetDisplayMode(device, display, &display->desktop_mode); } @@ -213,6 +213,7 @@ static SDL_VideoDevice *X11_CreateDevice(void) device->SetWindowHitTest = X11_SetWindowHitTest; device->AcceptDragAndDrop = X11_AcceptDragAndDrop; device->FlashWindow = X11_FlashWindow; + device->ShowWindowSystemMenu = X11_ShowWindowSystemMenu; #ifdef SDL_VIDEO_DRIVER_X11_XFIXES device->SetWindowMouseRect = X11_SetWindowMouseRect; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 36e7c9f2..2eb231bc 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -423,7 +423,6 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) SDL_WindowData *windowdata; Display *display = data->display; int screen = displaydata->screen; - const int transparent = (window->flags & SDL_WINDOW_TRANSPARENT) ? SDL_TRUE : SDL_FALSE; Visual *visual; int depth; XSetWindowAttributes xattr; @@ -443,6 +442,7 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) SDL_bool undefined_position = SDL_FALSE; #if defined(SDL_VIDEO_OPENGL_GLX) || defined(SDL_VIDEO_OPENGL_EGL) + const int transparent = (window->flags & SDL_WINDOW_TRANSPARENT) ? SDL_TRUE : SDL_FALSE; const char *forced_visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_WINDOW_VISUALID); if (forced_visual_id != NULL && forced_visual_id[0] != '\0') { @@ -1957,4 +1957,29 @@ int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title) return 0; } +void X11_ShowWindowSystemMenu(SDL_Window *window, int x, int y) +{ + SDL_WindowData *data = window->driverdata; + SDL_DisplayData *displaydata = SDL_GetDisplayDriverDataForWindow(window); + Display *display = data->videodata->display; + Window root = RootWindow(display, displaydata->screen); + XClientMessageEvent e; + Window childReturn; + int wx, wy; + + SDL_zero(e); + X11_XTranslateCoordinates(display, data->xwindow, root, x, y, &wx, &wy, &childReturn); + + e.type = ClientMessage; + e.window = data->xwindow; + e.message_type = X11_XInternAtom(display, "_GTK_SHOW_WINDOW_MENU", 0); + e.data.l[0] = 0; /* GTK device ID (unused) */ + e.data.l[1] = wx; /* X coordinate relative to root */ + e.data.l[2] = wy; /* Y coordinate relative to root */ + e.format = 32; + + X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&e); + X11_XFlush(display); +} + #endif /* SDL_VIDEO_DRIVER_X11 */ diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index b5da61a4..ff6b98ba 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -115,6 +115,7 @@ extern int X11_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, struc extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); extern void X11_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept); extern int X11_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation); +extern void X11_ShowWindowSystemMenu(SDL_Window *window, int x, int y); int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title); void X11_UpdateWindowPosition(SDL_Window *window); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 679a602a..b762ffe9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,6 +15,12 @@ if(NOT (MSVC AND SDL_CPU_ARM64)) find_package(OpenGL) endif() +if(WINDOWS_STORE) + cmake_minimum_required(VERSION 3.19) + # CMP0112: Target file component generator expressions do not add target dependencies. + cmake_policy(SET CMP0112 NEW) +endif() + set(SDL_TEST_EXECUTABLES) add_library(sdltests_utils OBJECT @@ -24,7 +30,7 @@ target_link_libraries(sdltests_utils PRIVATE SDL3::Headers) file(GLOB RESOURCE_FILES *.bmp *.wav *.hex moose.dat utf8.txt) set(RESOURCE_FILE_NAMES) -foreach(RESOURCE_FILE ${RESOURCE_FILES}) +foreach(RESOURCE_FILE IN LISTS RESOURCE_FILES) get_filename_component(res_file_name ${RESOURCE_FILE} NAME) list(APPEND RESOURCE_FILE_NAMES "${res_file_name}") endforeach() @@ -33,6 +39,14 @@ define_property(TARGET PROPERTY SDL_NONINTERACTIVE BRIEF_DOCS "If true, target i define_property(TARGET PROPERTY SDL_NONINTERACTIVE_ARGUMENTS BRIEF_DOCS "Argument(s) to run executable in non-interactive mode." FULL_DOCS "Argument(s) to run executable in non-interactive mode.") define_property(TARGET PROPERTY SDL_NONINTERACTIVE_TIMEOUT BRIEF_DOCS "Timeout for noninteractive executable." FULL_DOCS "Timeout for noninteractive executable.") +if(WINDOWS_STORE) + add_library(sdl_test_main_uwp OBJECT main.cpp) + target_link_libraries(sdl_test_main_uwp PRIVATE SDL3::Headers) + target_compile_options(sdl_test_main_uwp PRIVATE "/ZW") + + set_source_files_properties(${RESOURCE_FILES} PROPERTIES VS_DEPLOYENT_LOCATION "Assets") +endif() + macro(add_sdl_test_executable TARGET) cmake_parse_arguments(AST "BUILD_DEPENDENT;NONINTERACTIVE;NEEDS_RESOURCES;TESTUTILS;NO_C90" "" "NONINTERACTIVE_TIMEOUT;NONINTERACTIVE_ARGS;SOURCES" ${ARGN}) if(AST_UNPARSED_ARGUMENTS) @@ -44,13 +58,34 @@ macro(add_sdl_test_executable TARGET) if(AST_TESTUTILS) list(APPEND AST_SOURCES $) endif() + set(EXTRA_SOURCES "") + if(WINDOWS_STORE) + set(uwp_bindir "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.dir") + if(NOT IS_DIRECTORY "${uwp_bindir}") + execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${uwp_bindir}") + endif() + string(REGEX REPLACE "[_]" "" SAFE_TARGET "${TARGET}") + file(GENERATE OUTPUT "${uwp_bindir}/${TARGET}.appxmanifest" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/uwp/Package.appxmanifest.in" + TARGET "${TARGET}" + ) + set_property(SOURCE "${uwp_bindir}/${TARGET}.appxmanifest" PROPERTY VS_DEPLOYMENT_CONTENT 1) + list(APPEND EXTRA_SOURCES + "$" + "${uwp_bindir}/${TARGET}.appxmanifest" + "uwp/logo-50x50.png" + "uwp/square-44x44.png" + "uwp/square-150x150.png" + "uwp/splash-620x300.png" + ) + endif() if(AST_NEEDS_RESOURCES) - list(APPEND AST_SOURCES ${RESOURCE_FILES}) + list(APPEND EXTRA_SOURCES ${RESOURCE_FILES}) endif() if(ANDROID) - add_library(${TARGET} SHARED ${AST_SOURCES}) + add_library(${TARGET} SHARED ${AST_SOURCES} ${EXTRA_SOURCES}) else() - add_executable(${TARGET} ${AST_SOURCES}) + add_executable(${TARGET} ${AST_SOURCES} ${EXTRA_SOURCES}) endif() SDL_AddCommonCompilerFlags(${TARGET}) target_link_libraries(${TARGET} PRIVATE SDL3::SDL3_test SDL3::${sdl_name_component}) @@ -74,6 +109,16 @@ macro(add_sdl_test_executable TARGET) add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E make_directory $/sdl-${TARGET} COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILES} $/sdl-${TARGET}) + elseif(WINDOWS_STORE) + # MSVC does build the dependent targets (or POST_BUILD commands) when building an application + # after starting to debug. By copying the resources in a custom target, the files can be copied afterwards. + # FIXME: find out proper way to add assets to UWP package + cmake_minimum_required(VERSION 3.19) + add_custom_target(zzz-resources-copy-${TARGET} + COMMAND ${CMAKE_COMMAND} -E make_directory "$/AppX" + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RESOURCE_FILES} "$/AppX" + ) + add_dependencies(${TARGET} zzz-resources-copy-${TARGET}) else() add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILES} $) @@ -82,6 +127,12 @@ macro(add_sdl_test_executable TARGET) # Make sure resource files get installed into macOS/iOS .app bundles. set_target_properties(${TARGET} PROPERTIES RESOURCE "${RESOURCE_FILES}") endif() + if(EMSCRIPTEN) + foreach(res IN LISTS RESOURCE_FILES) + get_filename_component(res_name "${res}" NAME) + target_link_options(${TARGET} PRIVATE "SHELL:--embed-file ${res}@${res_name}") + endforeach() + endif() set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$/$$/>") endif() if(AST_BUILD_DEPENDENT) @@ -97,6 +148,21 @@ macro(add_sdl_test_executable TARGET) elseif(PSP) target_link_libraries(${TARGET} PRIVATE GL) endif() + if(WINDOWS_STORE) + target_compile_definitions(${TARGET} PRIVATE "SDL_MAIN_NOIMPL") + set_property(TARGET ${TARGET} PROPERTY WIN32_EXECUTABLE TRUE) + set_property(TARGET ${TARGET} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${uwp_bindir}") + target_link_options(${TARGET} PRIVATE + -nodefaultlib:vccorlib$<$:d> + -nodefaultlib:msvcrt$<$:d> + vccorlib$<$:d>.lib + msvcrt$<$:d>.lib + ) + endif() + + if(EMSCRIPTEN) + set_property(TARGET ${TARGET} PROPERTY SUFFIX ".html") + endif() if(OPENGL_FOUND) target_compile_definitions(${TARGET} PRIVATE HAVE_OPENGL) @@ -119,11 +185,10 @@ endif() add_sdl_test_executable(checkkeys SOURCES checkkeys.c) add_sdl_test_executable(checkkeysthreads SOURCES checkkeysthreads.c) add_sdl_test_executable(loopwave NEEDS_RESOURCES TESTUTILS SOURCES loopwave.c) -add_sdl_test_executable(loopwavequeue NEEDS_RESOURCES TESTUTILS SOURCES loopwavequeue.c) add_sdl_test_executable(testsurround SOURCES testsurround.c) add_sdl_test_executable(testresample NEEDS_RESOURCES SOURCES testresample.c) add_sdl_test_executable(testaudioinfo SOURCES testaudioinfo.c) -add_sdl_test_executable(testaudiostreamdynamicresample SOURCES testaudiostreamdynamicresample.c) +add_sdl_test_executable(testaudiostreamdynamicresample NEEDS_RESOURCES TESTUTILS SOURCES testaudiostreamdynamicresample.c) file(GLOB TESTAUTOMATION_SOURCE_FILES testautomation*.c) add_sdl_test_executable(testautomation NEEDS_RESOURCES NO_C90 SOURCES ${TESTAUTOMATION_SOURCE_FILES}) @@ -203,6 +268,7 @@ if(Python3_FOUND AND Python3_VERSION VERSION_GREATER_EQUAL "3.2") endforeach() endif() +add_sdl_test_executable(testaudio NEEDS_RESOURCES TESTUTILS SOURCES testaudio.c) add_sdl_test_executable(testfile NONINTERACTIVE SOURCES testfile.c) add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers}) add_sdl_test_executable(testgeometry TESTUTILS SOURCES testgeometry.c) @@ -212,7 +278,7 @@ if(ANDROID) target_link_libraries(testgles PRIVATE GLESv1_CM) endif() add_sdl_test_executable(testgles2 SOURCES testgles2.c) -add_sdl_test_executable(testgles2_sdf TESTUTILS SOURCES testgles2_sdf.c) +add_sdl_test_executable(testgles2_sdf NEEDS_RESOURCES TESTUTILS SOURCES testgles2_sdf.c) add_sdl_test_executable(testhaptic SOURCES testhaptic.c) add_sdl_test_executable(testhotplug SOURCES testhotplug.c) add_sdl_test_executable(testrumble SOURCES testrumble.c) @@ -279,7 +345,6 @@ endif() if(SDL_DUMMYAUDIO) set_property(TARGET testaudioinfo PROPERTY SDL_NONINTERACTIVE 1) - set_property(TARGET testsurround PROPERTY SDL_NONINTERACTIVE 1) endif() if(SDL_DUMMYVIDEO) @@ -303,6 +368,12 @@ if(OPENGL_FOUND) endif() if(EMSCRIPTEN) set_property(TARGET testshader APPEND_STRING PROPERTY LINK_FLAGS " -sLEGACY_GL_EMULATION") + + find_package(Python3 COMPONENTS Interpreter) + if(TARGET Python3::Interpreter) + add_custom_target(serve-sdl-tests + COMMAND Python3::Interpreter "${CMAKE_CURRENT_SOURCE_DIR}/emscripten/server.py" -d "${CMAKE_CURRENT_BINARY_DIR}") + endif() endif() if(PSP) diff --git a/test/README b/test/README index 914c1143..4327b1d4 100644 --- a/test/README +++ b/test/README @@ -3,7 +3,6 @@ These are test programs for the SDL library: checkkeys Watch the key events to check the keyboard loopwave Audio test -- loop playing a WAV file - loopwavequeue Audio test -- loop playing a WAV file with SDL_QueueAudio testsurround Audio test -- play test tone on each audio channel testaudioinfo Lists audio device capabilities testerror Tests multi-threaded error handling diff --git a/test/audiofile.bmp b/test/audiofile.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f8b8106d6ecf70326ee677a9b3896cdfd8b59723 GIT binary patch literal 65674 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 SDL_GAMEPAD_BUTTON_PADDLE1 && i <= SDL_GAMEPAD_BUTTON_PADDLE4) { + if (i >= SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 && i <= SDL_GAMEPAD_BUTTON_LEFT_PADDLE2) { on_front = SDL_FALSE; } if (on_front == ctx->showing_front) { @@ -560,7 +560,7 @@ void RenderGamepadImage(GamepadImage *ctx) SDL_GamepadButton button_position = GetRemappedButton(ctx->face_style, (SDL_GamepadButton)i); SDL_bool on_front = SDL_TRUE; - if (i >= SDL_GAMEPAD_BUTTON_PADDLE1 && i <= SDL_GAMEPAD_BUTTON_PADDLE4) { + if (i >= SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 && i <= SDL_GAMEPAD_BUTTON_LEFT_PADDLE2) { on_front = SDL_FALSE; } if (on_front == ctx->showing_front) { @@ -681,10 +681,10 @@ static const char *gamepad_button_names[] = { "DPAD Left", "DPAD Right", "Misc1", - "Paddle1", - "Paddle2", - "Paddle3", - "Paddle4", + "Right Paddle 1", + "Left Paddle 1", + "Right Paddle 2", + "Left Paddle 2", "Touchpad", }; SDL_COMPILE_TIME_ASSERT(gamepad_button_names, SDL_arraysize(gamepad_button_names) == SDL_GAMEPAD_BUTTON_MAX); diff --git a/test/logaudiodev.bmp b/test/logaudiodev.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ef231d75a7c48057abc019ad1027575e6ada1f4b GIT binary patch literal 65674 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 F{{w+htyKU3 literal 0 HcmV?d00001 diff --git a/test/loopwave.c b/test/loopwave.c index ac5f84d3..e6cc4df1 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -31,10 +31,18 @@ static struct SDL_AudioSpec spec; Uint8 *sound; /* Pointer to wave data */ Uint32 soundlen; /* Length of wave data */ - int soundpos; /* Current play position */ + Uint32 soundpos; } wave; static SDL_AudioDeviceID device; +static SDL_AudioStream *stream; + +static void fillerup(void) +{ + if (SDL_GetAudioStreamAvailable(stream) < (int) ((wave.soundlen / 2))) { + SDL_PutAudioStreamData(stream, wave.sound, wave.soundlen); + } +} /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void @@ -51,6 +59,8 @@ static void close_audio(void) { if (device != 0) { + SDL_DestroyAudioStream(stream); + stream = NULL; SDL_CloseAudioDevice(device); device = 0; } @@ -59,56 +69,33 @@ close_audio(void) static void open_audio(void) { - /* Initialize fillerup() variables */ - device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0); + device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &wave.spec); if (!device) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); SDL_free(wave.sound); quit(2); } - - /* Let the audio run */ - SDL_PlayAudioDevice(device); -} - -#ifndef __EMSCRIPTEN__ -static void reopen_audio(void) -{ - close_audio(); - open_audio(); -} -#endif - -static 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; + stream = SDL_CreateAndBindAudioStream(device, &wave.spec); + if (!stream) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create audio stream: %s\n", SDL_GetError()); + SDL_CloseAudioDevice(device); + SDL_free(wave.sound); + quit(2); } - SDL_memcpy(stream, waveptr, len); - wave.soundpos += len; } + static int done = 0; + + #ifdef __EMSCRIPTEN__ static void loop(void) { - if (done || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING)) { + if (done) { emscripten_cancel_main_loop(); + } else { + fillerup(); } } #endif @@ -162,13 +149,11 @@ int main(int argc, char *argv[]) } /* Load the wave file into memory */ - if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { + if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); quit(1); } - wave.spec.callback = fillerup; - /* Show the list of available drivers */ SDL_Log("Available audio drivers:"); for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { @@ -179,8 +164,6 @@ int main(int argc, char *argv[]) open_audio(); - SDL_FlushEvents(SDL_EVENT_AUDIO_DEVICE_ADDED, SDL_EVENT_AUDIO_DEVICE_REMOVED); - #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else @@ -191,11 +174,9 @@ int main(int argc, char *argv[]) if (event.type == SDL_EVENT_QUIT) { done = 1; } - if ((event.type == SDL_EVENT_AUDIO_DEVICE_ADDED && !event.adevice.iscapture) || - (event.type == SDL_EVENT_AUDIO_DEVICE_REMOVED && !event.adevice.iscapture && event.adevice.which == device)) { - reopen_audio(); - } } + + fillerup(); SDL_Delay(100); } #endif diff --git a/test/loopwavequeue.c b/test/loopwavequeue.c deleted file mode 100644 index e8c4daaa..00000000 --- a/test/loopwavequeue.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - Copyright (C) 1997-2023 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this 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 load a wave file and loop playing it using SDL sound queueing */ - -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include -#include -#include - -#ifdef HAVE_SIGNAL_H -#include -#endif - -#include "testutils.h" - -static struct -{ - SDL_AudioSpec spec; - Uint8 *sound; /* Pointer to wave data */ - Uint32 soundlen; /* Length of wave data */ -} wave; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - /* Let 'main()' return normally */ - if (rc != 0) { - exit(rc); - } -} - -static int done = 0; -static void poked(int sig) -{ - done = 1; -} - -static SDL_AudioDeviceID g_audio_id = 0; - -static void loop(void) -{ -#ifdef __EMSCRIPTEN__ - if (done || (SDL_GetAudioDeviceStatus(g_audio_id) != SDL_AUDIO_PLAYING)) { - emscripten_cancel_main_loop(); - } else -#endif - { - /* The device from SDL_OpenAudio() is always device #1. */ - const Uint32 queued = SDL_GetQueuedAudioSize(g_audio_id); - SDL_Log("Device has %u bytes queued.\n", (unsigned int)queued); - if (queued <= 8192) { /* time to requeue the whole thing? */ - if (SDL_QueueAudio(g_audio_id, wave.sound, wave.soundlen) == 0) { - SDL_Log("Device queued %u more bytes.\n", (unsigned int)wave.soundlen); - } else { - SDL_Log("Device FAILED to queue %u more bytes: %s\n", (unsigned int)wave.soundlen, SDL_GetError()); - } - } - } -} - -int main(int argc, char *argv[]) -{ - int i; - char *filename = NULL; - SDLTest_CommonState *state; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, 0); - if (state == NULL) { - return 1; - } - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Parse commandline */ - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (!consumed) { - if (!filename) { - filename = argv[i]; - consumed = 1; - } - } - if (consumed <= 0) { - static const char *options[] = { "[sample.wav]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - exit(1); - } - - i += consumed; - } - - /* 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; - } - - filename = GetResourceFilename(filename, "sample.wav"); - - if (filename == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError()); - quit(1); - } - - /* Load the wave file into memory */ - if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); - quit(1); - } - - wave.spec.callback = NULL; /* we'll push audio. */ - -#ifdef HAVE_SIGNAL_H - /* Set the signals */ -#ifdef SIGHUP - (void)signal(SIGHUP, poked); -#endif - (void)signal(SIGINT, poked); -#ifdef SIGQUIT - (void)signal(SIGQUIT, poked); -#endif - (void)signal(SIGTERM, poked); -#endif /* HAVE_SIGNAL_H */ - - /* Initialize fillerup() variables */ - g_audio_id = SDL_OpenAudioDevice(NULL, 0, &wave.spec, NULL, 0); - - if (!g_audio_id) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); - SDL_free(wave.sound); - quit(2); - } - - /*static x[99999]; SDL_QueueAudio(1, x, sizeof (x));*/ - - /* Let the audio run */ - SDL_PlayAudioDevice(g_audio_id); - - done = 0; - - /* Note that we stuff the entire audio buffer into the queue in one - shot. Most apps would want to feed it a little at a time, as it - plays, but we're going for simplicity here. */ - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done && (SDL_GetAudioDeviceStatus(g_audio_id) == SDL_AUDIO_PLAYING)) { - loop(); - - SDL_Delay(100); /* let it play for a while. */ - } -#endif - - /* Clean up on signal */ - SDL_CloseAudioDevice(g_audio_id); - SDL_free(wave.sound); - SDL_free(filename); - SDL_Quit(); - SDLTest_CommonDestroyState(state); - return 0; -} diff --git a/test/physaudiodev.bmp b/test/physaudiodev.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1d4da24643f61a7c4c6e16d93144ab003b513328 GIT binary patch literal 65674 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 W(82>PJkY`eEj-Y|1OGL6;Qs?9LpXT= literal 0 HcmV?d00001 diff --git a/test/soundboard.bmp b/test/soundboard.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1a3e93f07be4d4d5e3fe59122e74b447f0df2842 GIT binary patch literal 65674 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 A;Q#;t literal 0 HcmV?d00001 diff --git a/test/soundboard_levels.bmp b/test/soundboard_levels.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ce4cd5ba77342a16d7feaf17ed34f93d77294ed9 GIT binary patch literal 2698 zcmc)IYfO_@7zc2+eOt0kx49{(pcN>zMJUXu2pCG~{cQm)n4xU}l|r0mMnOO)^8z$Z zL0!~MsM9E3K)j%A0~Ds*qzDDU3CN|i)CuLXWSd~%**R}psHmH|4{Q4C|JxADJMUh&g=8H z4{hhp|NOqtMb;s3mOT_=F7ggC$uXYG9*WQ!;i~8)s8L-3_Mro7{SvkQvqIXA#GW>k zWK_X~^s4ca^r|tl$}zlNN~(lX6`of-i4RN~-4vYK8sr$!SgNXkp1eoT%SUVZMw0%b z5%d>(L0@1XWvo63$swvXwqr!ojeWPwdwAcfVDhZ~k{%4$=a)1*y_~k8u6X z{pIF;>p3zlXK@WWkM&;dM!KN4unRI|nUJ=6|6gSNfimd5(mipGJd5VG=X(n~!FUbp z0OR$CppqYey^-JizI2AD=hz0d;b!Iyn5r!629#x$LfJvA1j-H-LpgT17&daYLIRO$ z^qv+x~p>@9~46~`~bi(NwNNVZi08W+Hq#22uEy+s@BB-U1{^TAZ1`Dc}A zzp@qvEDpq_LV`F&!*^@BbPzJ;G<*zJj<2Kk9wxuq>!B=;3=N^6Sc{N~nCY(Uy zmrGcwfXzgF%hH)%gDfY%Rw0#rPr~4~O6Z&i5<0gvgu!bI_29LKEfjRD@Dy}Py@k4P zACX?l6zZf*k&d&#e@MxSsq=TB{l=c}^B~MCpf!%qd#dE~MwNX2sFF7YS1=mO<&UiA z2u74V;nOhYvhh^8Vwg?w`ZYHrp{L&U%=t4=lh|;1HWoH2#Nm9bMiOQz}Dzi@e(>@sKId5?RC8D#HhvwG) zIP>9X@_Lexx=_@8$;7nk`AN2XOP@y z8PMF?7pJ8!?s;rSG$cu7x7n0=omY=Cjl5VM7I5!}&weej!E6 z9cP-jE(=;j?(Q0lpwa6v5l*_tU4rIuS4{J)$0T&G1__-1{hYCZ9GGB2W0Tsf{{&?3 z2?r&Mcb1^dscyNw1I7oBzX0kvXo31q_EJO6-j%36IG3Q$slH#a9ma>ge*x5UXlh^F zCmV9oRzNH(=nPq3nF8a(-%at7ewKTx)50J&Fz__T<)ii=PsPA})Z<^Fd*ZudyW{*o z;kP(Hi1L0v-|f>T5p8xAzKfNZF}KFd@s5}=N#fyDi*a3N=+-Rtxy)YhK`)Q`Nh7Ye zvi86^*$4NV?89~axO?>yW&y4(%G(7k+EcG(*CqmFzKbph+-Ftb+A*koE$YlThzVGB z;{U9V_V-o)m+z1AUy>8-JiYZzf4|7ZUb!sFdwu9xYVkd632F9~R@UcgP5fNZ|E_D* IBF2Tk0c-))uK)l5 literal 0 HcmV?d00001 diff --git a/test/speaker.bmp b/test/speaker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56f3dc1ae6699c9fc89daa9b8925c2ebacfab52b GIT binary patch literal 65674 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 LgGw8Pr@{XNkWPDZ literal 0 HcmV?d00001 diff --git a/test/testaudio-art.txt b/test/testaudio-art.txt new file mode 100644 index 00000000..f30a3d24 --- /dev/null +++ b/test/testaudio-art.txt @@ -0,0 +1,8 @@ +The .bmp files used by testaudio.c were made by AlDraw: + +https://linktr.ee/AlexDraw + +They may be distributed as public domain files! + + + diff --git a/test/testaudio.c b/test/testaudio.c new file mode 100644 index 00000000..f7401486 --- /dev/null +++ b/test/testaudio.c @@ -0,0 +1,1069 @@ +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include +#include +#include +#include "testutils.h" + +#define POOF_LIFETIME 250 + +typedef struct Texture +{ + SDL_Texture *texture; + float w; + float h; +} Texture; + +typedef enum ThingType +{ + THING_NULL, + THING_PHYSDEV, + THING_PHYSDEV_CAPTURE, + THING_LOGDEV, + THING_LOGDEV_CAPTURE, + THING_TRASHCAN, + THING_STREAM, + THING_POOF, + THING_WAV +} ThingType; + + +typedef struct Thing Thing; + +struct Thing +{ + ThingType what; + + union { + struct { + SDL_AudioDeviceID devid; + SDL_bool iscapture; + SDL_AudioSpec spec; + char *name; + } physdev; + struct { + SDL_AudioDeviceID devid; + SDL_bool iscapture; + SDL_AudioSpec spec; + Thing *physdev; + } logdev; + struct { + SDL_AudioSpec spec; + Uint8 *buf; + Uint32 buflen; + } wav; + struct { + float startw; + float starth; + float centerx; + float centery; + } poof; + struct { + SDL_AudioStream *stream; + int total_ticks; + Uint64 next_level_update; + Uint8 levels[5]; + } stream; + } data; + + Thing *line_connected_to; + char *titlebar; + SDL_FRect rect; + float z; + Uint8 r, g, b, a; + float progress; + float scale; + Uint64 createticks; + Texture *texture; + const ThingType *can_be_dropped_onto; + + void (*ontick)(Thing *thing, Uint64 now); + void (*ondrag)(Thing *thing, int button, float x, float y); + void (*ondrop)(Thing *thing, int button, float x, float y); + void (*ondraw)(Thing *thing, SDL_Renderer *renderer); + + Thing *prev; + Thing *next; +}; + + +static Uint64 app_ready_ticks = 0; +static int done = 0; +static SDLTest_CommonState *state = NULL; + +static Thing *things = NULL; +static char *current_titlebar = NULL; + +static Thing *droppable_highlighted_thing = NULL; +static Thing *dragging_thing = NULL; +static int dragging_button = -1; + +static Texture *physdev_texture = NULL; +static Texture *logdev_texture = NULL; +static Texture *audio_texture = NULL; +static Texture *trashcan_texture = NULL; +static Texture *soundboard_texture = NULL; +static Texture *soundboard_levels_texture = NULL; + +static void DestroyTexture(Texture *tex); + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void Quit(int rc) +{ + DestroyTexture(physdev_texture); + DestroyTexture(logdev_texture); + DestroyTexture(audio_texture); + DestroyTexture(trashcan_texture); + DestroyTexture(soundboard_texture); + DestroyTexture(soundboard_levels_texture); + SDLTest_CommonQuit(state); + /* Let 'main()' return normally */ + if (rc != 0) { + exit(rc); + } +} + +static char *xstrdup(const char *str) +{ + char *ptr = SDL_strdup(str); + if (!ptr) { + SDL_Log("Out of memory!"); + Quit(1); + } + return ptr; +} + +static void *xalloc(const size_t len) +{ + void *ptr = SDL_calloc(1, len); + if (!ptr) { + SDL_Log("Out of memory!"); + Quit(1); + } + return ptr; +} + + +static void SetTitleBar(const char *fmt, ...) +{ + char *newstr = NULL; + va_list ap; + va_start(ap, fmt); + SDL_vasprintf(&newstr, fmt, ap); + va_end(ap); + + if (newstr && (!current_titlebar || (SDL_strcmp(current_titlebar, newstr) != 0))) { + SDL_SetWindowTitle(state->windows[0], newstr); + SDL_free(current_titlebar); + current_titlebar = newstr; + } else { + SDL_free(newstr); + } +} + +static void SetDefaultTitleBar(void) +{ + SetTitleBar("testaudio: %s", SDL_GetCurrentAudioDriver()); +} + +static Thing *FindThingAtPoint(const float x, const float y) +{ + const SDL_FPoint pt = { x, y }; + Thing *retval = NULL; + Thing *i; + for (i = things; i != NULL; i = i->next) { + if ((i != dragging_thing) && SDL_PointInRectFloat(&pt, &i->rect)) { + retval = i; /* keep going, though, because things drawn on top are later in the list. */ + } + } + return retval; +} + +static Thing *UpdateMouseOver(const float x, const float y) +{ + Thing *thing; + + if (dragging_thing) { + thing = dragging_thing; + } else { + thing = FindThingAtPoint(x, y); + } + + if (!thing) { + SetDefaultTitleBar(); + } else if (thing->titlebar) { + SetTitleBar("%s", thing->titlebar); + } + + return thing; +} + +static Thing *CreateThing(ThingType what, float x, float y, float z, float w, float h, Texture *texture, char *titlebar) +{ + Thing *last = NULL; + Thing *i; + Thing *thing; + + thing = (Thing *) xalloc(sizeof (Thing)); + if ((w < 0) || (h < 0)) { + SDL_assert(texture != NULL); + if (w < 0) { + w = texture->w; + } + if (h < 0) { + h = texture->h; + } + } + + thing->what = what; + thing->rect.x = x; + thing->rect.y = y; + thing->rect.w = w; + thing->rect.h = h; + thing->z = z; + thing->r = 255; + thing->g = 255; + thing->b = 255; + thing->a = 255; + thing->scale = 1.0f; + thing->createticks = SDL_GetTicks(); + thing->texture = texture; + thing->titlebar = titlebar; + + /* insert in list by Z order (furthest from the "camera" first, so they get drawn over; negative Z is not drawn at all). */ + if (things == NULL) { + things = thing; + return thing; + } + + for (i = things; i != NULL; i = i->next) { + if (z > i->z) { /* insert here. */ + thing->next = i; + thing->prev = i->prev; + + SDL_assert(i->prev == last); + + if (i->prev) { + i->prev->next = thing; + } else { + SDL_assert(i == things); + things = thing; + } + i->prev = thing; + return thing; + } + last = i; + } + + if (last) { + last->next = thing; + thing->prev = last; + } + return thing; +} + +static void DestroyThing(Thing *thing) +{ + if (!thing) { + return; + } + + switch (thing->what) { + case THING_POOF: break; + case THING_NULL: break; + case THING_TRASHCAN: break; + case THING_LOGDEV: + case THING_LOGDEV_CAPTURE: + SDL_CloseAudioDevice(thing->data.logdev.devid); + break; + case THING_PHYSDEV: + case THING_PHYSDEV_CAPTURE: + SDL_free(thing->data.physdev.name); + break; + case THING_WAV: + SDL_free(thing->data.wav.buf); + break; + case THING_STREAM: + SDL_DestroyAudioStream(thing->data.stream.stream); + break; + } + + if (thing->prev) { + thing->prev->next = thing->next; + } else { + SDL_assert(thing == things); + things = thing->next; + } + + if (thing->next) { + thing->next->prev = thing->prev; + } + + SDL_free(thing->titlebar); + SDL_free(thing); +} + +static void DrawOneThing(SDL_Renderer *renderer, Thing *thing) +{ + SDL_FRect dst; + SDL_memcpy(&dst, &thing->rect, sizeof (SDL_FRect)); + if (thing->scale != 1.0f) { + const float centerx = thing->rect.x + (thing->rect.w / 2); + const float centery = thing->rect.y + (thing->rect.h / 2); + SDL_assert(thing->texture != NULL); + dst.w = thing->texture->w * thing->scale; + dst.h = thing->texture->h * thing->scale; + dst.x = centerx - (dst.w / 2); + dst.y = centery - (dst.h / 2); + } + + if (thing->texture) { + if (droppable_highlighted_thing == thing) { + SDL_SetRenderDrawColor(renderer, 255, 0, 255, 100); + SDL_RenderFillRect(renderer, &dst); + } + SDL_SetRenderDrawColor(renderer, thing->r, thing->g, thing->b, thing->a); + SDL_RenderTexture(renderer, thing->texture->texture, NULL, &dst); + } else { + SDL_SetRenderDrawColor(renderer, thing->r, thing->g, thing->b, thing->a); + SDL_RenderFillRect(renderer, &dst); + } + + if (thing->ondraw) { + thing->ondraw(thing, renderer); + } + + if (thing->progress > 0.0f) { + SDL_FRect r = { thing->rect.x, thing->rect.y + (thing->rect.h + 2.0f), 0.0f, 10.0f }; + r.w = thing->rect.w * ((thing->progress > 1.0f) ? 1.0f : thing->progress); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 128); + SDL_RenderFillRect(renderer, &r); + } +} + +static void DrawThings(SDL_Renderer *renderer) +{ + Thing *i; + + /* draw connecting lines first, so they're behind everything else. */ + for (i = things; i && (i->z >= 0.0f); i = i->next) { + Thing *dst = i->line_connected_to; + if (dst) { + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderLine(renderer, i->rect.x + (i->rect.w / 2), i->rect.y + (i->rect.h / 2), dst->rect.x + (dst->rect.w / 2), dst->rect.y + (dst->rect.h / 2)); + } + } + + /* Draw the actual things. */ + for (i = things; i && (i->z >= 0.0f); i = i->next) { + if (i != dragging_thing) { + DrawOneThing(renderer, i); + } + } + + if (dragging_thing) { + DrawOneThing(renderer, dragging_thing); /* draw last so it's always on top. */ + } +} + +static void Draw(void) +{ + SDL_Renderer *renderer = state->renderers[0]; + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 64, 0, 64, 255); + SDL_RenderClear(renderer); + DrawThings(renderer); + SDL_RenderPresent(renderer); +} + +static void RepositionRowOfThings(const ThingType what, const float y) +{ + int total_things = 0; + float texw = 0.0f; + float texh = 0.0f; + Thing *i; + + for (i = things; i != NULL; i = i->next) { + if (i->what == what) { + texw = i->rect.w; + texh = i->rect.h; + total_things++; + } + } + + if (total_things > 0) { + int w, h; + SDL_GetWindowSize(state->windows[0], &w, &h); + const float spacing = w / ((float) total_things); + float x = (spacing - texw) / 2.0f; + for (i = things; i != NULL; i = i->next) { + if (i->what == what) { + i->rect.x = x; + i->rect.y = (y >= 0.0f) ? y : ((h + y) - texh); + x += spacing; + } + } + } +} + +static const char *AudioFmtToString(const SDL_AudioFormat fmt) +{ + switch (fmt) { + #define FMTCASE(x) case SDL_AUDIO_##x: return #x + FMTCASE(U8); + FMTCASE(S8); + FMTCASE(S16LSB); + FMTCASE(S16MSB); + FMTCASE(S32LSB); + FMTCASE(S32MSB); + FMTCASE(F32LSB); + FMTCASE(F32MSB); + #undef FMTCASE + } + return "?"; +} + +static const char *AudioChansToStr(const int channels) +{ + switch (channels) { + case 1: return "mono"; + case 2: return "stereo"; + case 3: return "2.1"; + case 4: return "quad"; + case 5: return "4.1"; + case 6: return "5.1"; + case 7: return "6.1"; + case 8: return "7.1"; + default: break; + } + return "?"; +} + +static void PoofThing_ondrag(Thing *thing, int button, float x, float y) +{ + dragging_thing = NULL; /* refuse to be dragged. */ +} + +static void PoofThing_ontick(Thing *thing, Uint64 now) +{ + const int lifetime = POOF_LIFETIME; + const int elasped = (int) (now - thing->createticks); + if (elasped > lifetime) { + DestroyThing(thing); + } else { + const float pct = ((float) elasped) / ((float) lifetime); + thing->a = (Uint8) (int) (255.0f - (pct * 255.0f)); + thing->scale = 1.0f - pct; /* shrink to nothing! */ + } +} + +static Thing *CreatePoofThing(Thing *poofing_thing) +{ + const float centerx = poofing_thing->rect.x + (poofing_thing->rect.w / 2); + const float centery = poofing_thing->rect.y + (poofing_thing->rect.h / 2); + const float z = poofing_thing->z; + Thing *thing = CreateThing(THING_POOF, poofing_thing->rect.x, poofing_thing->rect.y, z, poofing_thing->rect.w, poofing_thing->rect.h, poofing_thing->texture, NULL); + thing->data.poof.startw = poofing_thing->rect.w; + thing->data.poof.starth = poofing_thing->rect.h; + thing->data.poof.centerx = centerx; + thing->data.poof.centery = centery; + thing->ontick = PoofThing_ontick; + thing->ondrag = PoofThing_ondrag; + return thing; +} + +static void DestroyThingInPoof(Thing *thing) +{ + if (thing) { + if (thing->what != THING_POOF) { + CreatePoofThing(thing); + } + DestroyThing(thing); + } +} + +/* this poofs a thing and additionally poofs all things connected to the thing. */ +static void TrashThing(Thing *thing) +{ + Thing *i, *next; + for (i = things; i != NULL; i = next) { + next = i->next; + if (i->line_connected_to == thing) { + TrashThing(i); + next = things; /* start over in case this blew up the list. */ + } + } + DestroyThingInPoof(thing); +} + +static void StreamThing_ontick(Thing *thing, Uint64 now) +{ + if (!thing->line_connected_to) { + return; + } + + /* are we playing? See if we're done, or update state. */ + if (thing->line_connected_to->what == THING_LOGDEV) { + const int available = SDL_GetAudioStreamAvailable(thing->data.stream.stream); + SDL_AudioSpec spec; + if (!available || (SDL_GetAudioStreamFormat(thing->data.stream.stream, NULL, &spec) < 0)) { + DestroyThingInPoof(thing); + } else { + const int ticksleft = (int) ((((Uint64) ((available / (SDL_AUDIO_BITSIZE(spec.format) / 8)) / spec.channels)) * 1000) / spec.freq); + const float pct = thing->data.stream.total_ticks ? (((float) (ticksleft)) / ((float) thing->data.stream.total_ticks)) : 0.0f; + thing->progress = 1.0f - pct; + } + } + + if (thing->data.stream.next_level_update <= now) { + Uint64 perf = SDL_GetPerformanceCounter(); + int i; + for (i = 0; i < SDL_arraysize(thing->data.stream.levels); i++) { + thing->data.stream.levels[i] = (Uint8) (perf % 6); + perf >>= 3; + } + thing->data.stream.next_level_update += 150; + } +} + +static void StreamThing_ondrag(Thing *thing, int button, float x, float y) +{ + if (button == SDL_BUTTON_RIGHT) { /* this is kinda hacky, but use this to disconnect from a playing source. */ + if (thing->line_connected_to) { + SDL_UnbindAudioStream(thing->data.stream.stream); /* unbind from current device */ + thing->line_connected_to = NULL; + } + } +} + +static void StreamThing_ondrop(Thing *thing, int button, float x, float y) +{ + if (droppable_highlighted_thing) { + if (droppable_highlighted_thing->what == THING_TRASHCAN) { + TrashThing(thing); + } else if (((droppable_highlighted_thing->what == THING_LOGDEV) || (droppable_highlighted_thing->what == THING_LOGDEV_CAPTURE)) && (droppable_highlighted_thing != thing->line_connected_to)) { + /* connect to a logical device! */ + SDL_Log("Binding audio stream ('%s') to logical device %u", thing->titlebar, (unsigned int) droppable_highlighted_thing->data.logdev.devid); + if (thing->line_connected_to) { + const SDL_AudioSpec *spec = &droppable_highlighted_thing->data.logdev.spec; + SDL_UnbindAudioStream(thing->data.stream.stream); /* unbind from current device */ + if (thing->line_connected_to->what == THING_LOGDEV_CAPTURE) { + SDL_FlushAudioStream(thing->data.stream.stream); + thing->data.stream.total_ticks = (int) (((((Uint64) (SDL_GetAudioStreamAvailable(thing->data.stream.stream) / (SDL_AUDIO_BITSIZE(spec->format) / 8))) / spec->channels) * 1000) / spec->freq); + } + } + + SDL_BindAudioStream(droppable_highlighted_thing->data.logdev.devid, thing->data.stream.stream); /* bind to new device! */ + + thing->progress = 0.0f; /* ontick will adjust this if we're on an output device.*/ + thing->data.stream.next_level_update = SDL_GetTicks() + 100; + thing->line_connected_to = droppable_highlighted_thing; + } + } +} + +static void StreamThing_ondraw(Thing *thing, SDL_Renderer *renderer) +{ + if (thing->line_connected_to) { /* are we playing? Update progress bar, and bounce the levels a little. */ + static const float xlocs[5] = { 18, 39, 59, 79, 99 }; + static const float ylocs[5] = { 49, 39, 29, 19, 10 }; + const float blockw = soundboard_levels_texture->w; + const float blockh = soundboard_levels_texture->h / 5.0f; + int i, j; + SDL_SetRenderDrawColor(renderer, thing->r, thing->g, thing->b, thing->a); + for (i = 0; i < SDL_arraysize(thing->data.stream.levels); i++) { + const int level = (int) thing->data.stream.levels[i]; + const float x = xlocs[i]; + for (j = 0; j < level; j++) { + const SDL_FRect src = { 0, soundboard_levels_texture->h - ((j+1) * blockh), blockw, blockh }; + const SDL_FRect dst = { thing->rect.x + x, thing->rect.y + ylocs[j], blockw, blockh }; + SDL_RenderTexture(renderer, soundboard_levels_texture->texture, &src, &dst); + } + } + } +} + +static Thing *CreateStreamThing(const SDL_AudioSpec *spec, const Uint8 *buf, const Uint32 buflen, const char *fname, const float x, const float y) +{ + static const ThingType can_be_dropped_onto[] = { THING_TRASHCAN, THING_LOGDEV, THING_LOGDEV_CAPTURE, THING_NULL }; + Thing *thing = CreateThing(THING_STREAM, x, y, 0, -1, -1, soundboard_texture, fname ? xstrdup(fname) : NULL); + SDL_Log("Adding audio stream for %s", fname ? fname : "(null)"); + thing->data.stream.stream = SDL_CreateAudioStream(spec, spec); + if (buf && buflen) { + SDL_PutAudioStreamData(thing->data.stream.stream, buf, (int) buflen); + SDL_FlushAudioStream(thing->data.stream.stream); + thing->data.stream.total_ticks = (int) (((((Uint64) (SDL_GetAudioStreamAvailable(thing->data.stream.stream) / (SDL_AUDIO_BITSIZE(spec->format) / 8))) / spec->channels) * 1000) / spec->freq); + } + thing->ontick = StreamThing_ontick; + thing->ondrag = StreamThing_ondrag; + thing->ondrop = StreamThing_ondrop; + thing->ondraw = StreamThing_ondraw; + thing->can_be_dropped_onto = can_be_dropped_onto; + return thing; +} + +static void WavThing_ondrag(Thing *thing, int button, float x, float y) +{ + if (button == SDL_BUTTON_RIGHT) { /* drag out a new audio stream. */ + dragging_thing = CreateStreamThing(&thing->data.wav.spec, thing->data.wav.buf, thing->data.wav.buflen, thing->titlebar, x - (thing->rect.w / 2), y - (thing->rect.h / 2)); + } +} + +static void WavThing_ondrop(Thing *thing, int button, float x, float y) +{ + if (droppable_highlighted_thing) { + if (droppable_highlighted_thing->what == THING_TRASHCAN) { + TrashThing(thing); + } + } +} + +static Thing *LoadWavThing(const char *fname, float x, float y) +{ + Thing *thing = NULL; + char *path; + SDL_AudioSpec spec; + Uint8 *buf = NULL; + Uint32 buflen = 0; + + path = GetNearbyFilename(fname); + if (path) { + fname = path; + } + + if (SDL_LoadWAV(fname, &spec, &buf, &buflen) == 0) { + static const ThingType can_be_dropped_onto[] = { THING_TRASHCAN, THING_NULL }; + char *titlebar = NULL; + const char *nodirs = SDL_strrchr(fname, '/'); + #ifdef __WINDOWS__ + const char *nodirs2 = SDL_strrchr(nodirs ? nodirs : fname, '\\'); + if (nodirs2) { + nodirs = nodirs2; + } + #endif + + SDL_Log("Adding WAV file '%s'", fname); + + if (nodirs) { + nodirs++; + } else { + nodirs = fname; + } + + SDL_asprintf(&titlebar, "WAV file (\"%s\", %s, %s, %uHz)", nodirs, AudioFmtToString(spec.format), AudioChansToStr(spec.channels), (unsigned int) spec.freq); + thing = CreateThing(THING_WAV, x - (audio_texture->w / 2), y - (audio_texture->h / 2), 5, -1, -1, audio_texture, titlebar); + SDL_memcpy(&thing->data.wav.spec, &spec, sizeof (SDL_AudioSpec)); + thing->data.wav.buf = buf; + thing->data.wav.buflen = buflen; + thing->can_be_dropped_onto = can_be_dropped_onto; + thing->ondrag = WavThing_ondrag; + thing->ondrop = WavThing_ondrop; + } + + SDL_free(path); + + return thing; +} + +static Thing *LoadStockWavThing(const char *fname) +{ + char *path = GetNearbyFilename(fname); + Thing *thing = LoadWavThing(path ? path : fname, 0.0f, 0.0f); /* will reposition in a moment. */ + SDL_free(path); + return thing; +} + +static void LoadStockWavThings(void) +{ + LoadStockWavThing("sample.wav"); + RepositionRowOfThings(THING_WAV, -10.0f); +} + +static void DestroyTexture(Texture *tex) +{ + if (tex) { + SDL_DestroyTexture(tex->texture); + SDL_free(tex); + } +} + +static Texture *CreateTexture(const char *fname) +{ + Texture *tex = (Texture *) xalloc(sizeof (Texture)); + int texw, texh; + tex->texture = LoadTexture(state->renderers[0], fname, SDL_TRUE, &texw, &texh); + if (!tex->texture) { + SDL_Log("Failed to load '%s': %s", fname, SDL_GetError()); + SDL_free(tex); + Quit(1); + } + SDL_SetTextureBlendMode(tex->texture, SDL_BLENDMODE_BLEND); + tex->w = (float) texw; + tex->h = (float) texh; + return tex; +} + +static Thing *CreateLogicalDeviceThing(Thing *parent, const SDL_AudioDeviceID which, const float x, const float y); + +static void DeviceThing_ondrag(Thing *thing, int button, float x, float y) +{ + if ((button == SDL_BUTTON_MIDDLE) && (thing->what == THING_LOGDEV_CAPTURE)) { /* drag out a new stream. This is a UX mess. :/ */ + dragging_thing = CreateStreamThing(&thing->data.logdev.spec, NULL, 0, NULL, x, y); + dragging_thing->data.stream.next_level_update = SDL_GetTicks() + 100; + SDL_BindAudioStream(thing->data.logdev.devid, dragging_thing->data.stream.stream); /* bind to new device! */ + dragging_thing->line_connected_to = thing; + } else if (button == SDL_BUTTON_RIGHT) { /* drag out a new logical device. */ + const SDL_AudioDeviceID which = ((thing->what == THING_LOGDEV) || (thing->what == THING_LOGDEV_CAPTURE)) ? thing->data.logdev.devid : thing->data.physdev.devid; + const SDL_AudioDeviceID devid = SDL_OpenAudioDevice(which, NULL); + dragging_thing = devid ? CreateLogicalDeviceThing(thing, devid, x - (thing->rect.w / 2), y - (thing->rect.h / 2)) : NULL; + } +} + +static void SetLogicalDeviceTitlebar(Thing *thing) +{ + SDL_AudioSpec *spec = &thing->data.logdev.spec; + SDL_GetAudioDeviceFormat(thing->data.logdev.devid, spec); + SDL_asprintf(&thing->titlebar, "Logical device #%u (%s, %s, %s, %uHz)", (unsigned int) thing->data.logdev.devid, thing->data.logdev.iscapture ? "CAPTURE" : "OUTPUT", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq); +} + +static void LogicalDeviceThing_ondrop(Thing *thing, int button, float x, float y) +{ + if (droppable_highlighted_thing) { + if (droppable_highlighted_thing->what == THING_TRASHCAN) { + TrashThing(thing); + } + } +} + +static Thing *CreateLogicalDeviceThing(Thing *parent, const SDL_AudioDeviceID which, const float x, const float y) +{ + static const ThingType can_be_dropped_onto[] = { THING_TRASHCAN, THING_NULL }; + Thing *physthing = ((parent->what == THING_LOGDEV) || (parent->what == THING_LOGDEV_CAPTURE)) ? parent->data.logdev.physdev : parent; + const SDL_bool iscapture = physthing->data.physdev.iscapture; + Thing *thing; + + SDL_Log("Adding logical audio device %u", (unsigned int) which); + thing = CreateThing(iscapture ? THING_LOGDEV_CAPTURE : THING_LOGDEV, x, y, 5, -1, -1, logdev_texture, NULL); + thing->data.logdev.devid = which; + thing->data.logdev.iscapture = iscapture; + thing->data.logdev.physdev = physthing; + thing->line_connected_to = physthing; + thing->ondrag = DeviceThing_ondrag; + thing->ondrop = LogicalDeviceThing_ondrop; + thing->can_be_dropped_onto = can_be_dropped_onto; + + SetLogicalDeviceTitlebar(thing); + return thing; +} + +static void SetPhysicalDeviceTitlebar(Thing *thing) +{ + SDL_AudioSpec *spec = &thing->data.physdev.spec; + SDL_GetAudioDeviceFormat(thing->data.physdev.devid, spec); + if (thing->data.physdev.devid == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) { + SDL_asprintf(&thing->titlebar, "Default system device (CAPTURE, %s, %s, %uHz)", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq); + } else if (thing->data.physdev.devid == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) { + SDL_asprintf(&thing->titlebar, "Default system device (OUTPUT, %s, %s, %uHz)", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq); + } else { + SDL_asprintf(&thing->titlebar, "Physical device #%u (%s, \"%s\", %s, %s, %uHz)", (unsigned int) thing->data.physdev.devid, thing->data.physdev.iscapture ? "CAPTURE" : "OUTPUT", thing->data.physdev.name, AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq); + } +} + +static void PhysicalDeviceThing_ondrop(Thing *thing, int button, float x, float y) +{ + if (droppable_highlighted_thing) { + if (droppable_highlighted_thing->what == THING_TRASHCAN) { + TrashThing(thing); + } + } +} + +static void PhysicalDeviceThing_ontick(Thing *thing, Uint64 now) +{ + const int lifetime = POOF_LIFETIME; + const int elasped = (int) (now - thing->createticks); + if (elasped > lifetime) { + thing->scale = 1.0f; + thing->a = 255; + thing->ontick = NULL; /* no more ticking. */ + } else { + const float pct = ((float) elasped) / ((float) lifetime); + thing->a = (Uint8) (int) (pct * 255.0f); + thing->scale = pct; /* grow to normal size */ + } +} + + +static Thing *CreatePhysicalDeviceThing(const SDL_AudioDeviceID which, const SDL_bool iscapture) +{ + static const ThingType can_be_dropped_onto[] = { THING_TRASHCAN, THING_NULL }; + static float next_physdev_x = 0; + Thing *thing; + int winw, winh; + + SDL_GetWindowSize(state->windows[0], &winw, &winh); + if (next_physdev_x > (winw-physdev_texture->w)) { + next_physdev_x = 0; + } + + SDL_Log("Adding physical audio device %u", (unsigned int) which); + thing = CreateThing(iscapture ? THING_PHYSDEV_CAPTURE : THING_PHYSDEV, next_physdev_x, 170, 5, -1, -1, physdev_texture, NULL); + thing->data.physdev.devid = which; + thing->data.physdev.iscapture = iscapture; + thing->data.physdev.name = SDL_GetAudioDeviceName(which); + thing->ondrag = DeviceThing_ondrag; + thing->ondrop = PhysicalDeviceThing_ondrop; + thing->ontick = PhysicalDeviceThing_ontick; + thing->can_be_dropped_onto = can_be_dropped_onto; + + SetPhysicalDeviceTitlebar(thing); + if (SDL_GetTicks() <= (app_ready_ticks + 2000)) { /* assume this is the initial batch if it happens in the first two seconds. */ + RepositionRowOfThings(THING_PHYSDEV, 10.0f); /* don't rearrange them after the initial add. */ + RepositionRowOfThings(THING_PHYSDEV_CAPTURE, 170.0f); /* don't rearrange them after the initial add. */ + next_physdev_x = 0.0f; + } else { + next_physdev_x += physdev_texture->w * 1.5f; + } + + return thing; +} + +static Thing *CreateTrashcanThing(void) +{ + int winw, winh; + SDL_GetWindowSize(state->windows[0], &winw, &winh); + return CreateThing(THING_TRASHCAN, winw - trashcan_texture->w, winh - trashcan_texture->h, 10, -1, -1, trashcan_texture, "Drag things here to remove them."); +} + +static Thing *CreateDefaultPhysicalDevice(const SDL_bool iscapture) +{ + return CreatePhysicalDeviceThing(iscapture ? SDL_AUDIO_DEVICE_DEFAULT_CAPTURE : SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, iscapture); +} + +static void TickThings(void) +{ + Thing *i; + Thing *next; + const Uint64 now = SDL_GetTicks(); + for (i = things; i != NULL; i = next) { + next = i->next; /* in case this deletes itself. */ + if (i->ontick) { + i->ontick(i, now); + } + } +} + +static void WindowResized(const int newwinw, const int newwinh) +{ + Thing *i; + const float neww = (float) newwinw; + const float newh = (float) newwinh; + const float oldw = (float) state->window_w; + const float oldh = (float) state->window_h; + for (i = things; i != NULL; i = i->next) { + const float halfw = i->rect.w / 2.0f; + const float halfh = i->rect.h / 2.0f; + const float x = (i->rect.x + halfw) / oldw; + const float y = (i->rect.y + halfh) / oldh; + i->rect.x = (x * neww) - halfw; + i->rect.y = (y * newh) - halfh; + } + state->window_w = newwinw; + state->window_h = newwinh; +} + + +static void Loop(void) +{ + SDL_Event event; + SDL_bool saw_event = SDL_FALSE; + + if (app_ready_ticks == 0) { + app_ready_ticks = SDL_GetTicks(); + } + + while (SDL_PollEvent(&event)) { + Thing *thing = NULL; + + saw_event = SDL_TRUE; + + switch (event.type) { + case SDL_EVENT_MOUSE_MOTION: + thing = UpdateMouseOver(event.motion.x, event.motion.y); + if ((dragging_button == -1) && event.motion.state) { + if (event.motion.state & SDL_BUTTON_LMASK) { + dragging_button = SDL_BUTTON_LEFT; + } else if (event.motion.state & SDL_BUTTON_RMASK) { + dragging_button = SDL_BUTTON_RIGHT; + } else if (event.motion.state & SDL_BUTTON_MMASK) { + dragging_button = SDL_BUTTON_MIDDLE; + } + + + if (dragging_button != -1) { + dragging_thing = thing; + if (thing && thing->ondrag) { + thing->ondrag(thing, dragging_button, event.motion.x, event.motion.y); + } + } + } + + droppable_highlighted_thing = NULL; + if (dragging_thing) { + dragging_thing->rect.x = event.motion.x - (dragging_thing->rect.w / 2); + dragging_thing->rect.y = event.motion.y - (dragging_thing->rect.h / 2); + if (dragging_thing->can_be_dropped_onto) { + thing = FindThingAtPoint(event.motion.x, event.motion.y); + if (thing) { + int i; + for (i = 0; dragging_thing->can_be_dropped_onto[i]; i++) { + if (dragging_thing->can_be_dropped_onto[i] == thing->what) { + droppable_highlighted_thing = thing; + break; + } + } + } + } + } + break; + + case SDL_EVENT_MOUSE_BUTTON_DOWN: + thing = UpdateMouseOver(event.button.x, event.button.y); + break; + + case SDL_EVENT_MOUSE_BUTTON_UP: + if (dragging_button == event.button.button) { + Thing *dropped_thing = dragging_thing; + dragging_thing = NULL; + dragging_button = -1; + if (dropped_thing && dropped_thing->ondrop) { + dropped_thing->ondrop(dropped_thing, event.button.button, event.button.x, event.button.y); + } + droppable_highlighted_thing = NULL; + } + thing = UpdateMouseOver(event.button.x, event.button.y); + break; + + case SDL_EVENT_MOUSE_WHEEL: + UpdateMouseOver(event.wheel.mouseX, event.wheel.mouseY); + break; + + case SDL_EVENT_DROP_FILE: + SDL_Log("Drop file! '%s'", event.drop.file); + LoadWavThing(event.drop.file, event.drop.x, event.drop.y); + /* SDLTest_CommonEvent will free the string, below. */ + break; + + case SDL_EVENT_WINDOW_RESIZED: + WindowResized(event.window.data1, event.window.data2); + break; + + case SDL_EVENT_AUDIO_DEVICE_ADDED: + CreatePhysicalDeviceThing(event.adevice.which, event.adevice.iscapture); + break; + + case SDL_EVENT_AUDIO_DEVICE_REMOVED: { + const SDL_AudioDeviceID which = event.adevice.which; + Thing *i, *next; + SDL_Log("Removing audio device %u", (unsigned int) which); + for (i = things; i != NULL; i = next) { + next = i->next; + if (((i->what == THING_PHYSDEV) || (i->what == THING_PHYSDEV_CAPTURE)) && (i->data.physdev.devid == which)) { + TrashThing(i); + next = things; /* in case we mangled the list. */ + } else if (((i->what == THING_LOGDEV) || (i->what == THING_LOGDEV_CAPTURE)) && (i->data.logdev.devid == which)) { + TrashThing(i); + next = things; /* in case we mangled the list. */ + } + } + break; + } + + default: break; + } + + SDLTest_CommonEvent(state, &event, &done); + } + + TickThings(); + Draw(); + + if (!saw_event) { + SDL_Delay(10); + } + + #ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } + #endif +} + +int main(int argc, char *argv[]) +{ + int i; + + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO | SDL_INIT_AUDIO); + if (state == NULL) { + Quit(1); + } + + state->window_flags |= SDL_WINDOW_RESIZABLE; + + for (i = 1; i < argc;) { + int consumed = SDLTest_CommonArg(state, i); + if (consumed == 0) { + consumed = -1; + /* add our own command lines here. */ + } + if (consumed < 0) { + static const char *options[] = { + /* add our own command lines here. */ + /*"[--blend none|blend|add|mod|mul|sub]",*/ + NULL + }; + SDLTest_CommonLogUsage(state, argv[0], options); + Quit(1); + } + i += consumed; + } + + if (!SDLTest_CommonInit(state)) { + Quit(2); + } + + if (state->audio_id) { + SDL_CloseAudioDevice(state->audio_id); + state->audio_id = 0; + } + + SetDefaultTitleBar(); + + physdev_texture = CreateTexture("physaudiodev.bmp"); + logdev_texture = CreateTexture("logaudiodev.bmp"); + audio_texture = CreateTexture("audiofile.bmp"); + trashcan_texture = CreateTexture("trashcan.bmp"); + soundboard_texture = CreateTexture("soundboard.bmp"); + soundboard_levels_texture = CreateTexture("soundboard_levels.bmp"); + + LoadStockWavThings(); + CreateTrashcanThing(); + CreateDefaultPhysicalDevice(SDL_FALSE); + CreateDefaultPhysicalDevice(SDL_TRUE); + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(Loop, 0, 1); +#else + while (!done) { + Loop(); + } +#endif + + Quit(0); + return 0; +} + diff --git a/test/testaudiocapture.c b/test/testaudiocapture.c index 01c26760..fd83d29f 100644 --- a/test/testaudiocapture.c +++ b/test/testaudiocapture.c @@ -22,13 +22,14 @@ 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 SDL_AudioStream *stream_in = NULL; +static SDL_AudioStream *stream_out = NULL; static int done = 0; static void loop(void) { + const SDL_AudioDeviceID devid_in = SDL_GetAudioStreamBinding(stream_in); + const SDL_AudioDeviceID devid_out = SDL_GetAudioStreamBinding(stream_out); SDL_bool please_quit = SDL_FALSE; SDL_Event e; @@ -42,17 +43,18 @@ static void loop(void) } else if (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { if (e.button.button == 1) { SDL_PauseAudioDevice(devid_out); - SDL_PlayAudioDevice(devid_in); + SDL_ResumeAudioDevice(devid_in); } } else if (e.type == SDL_EVENT_MOUSE_BUTTON_UP) { if (e.button.button == 1) { SDL_PauseAudioDevice(devid_in); - SDL_PlayAudioDevice(devid_out); + SDL_FlushAudioStream(stream_in); /* so no samples are held back for resampling purposes. */ + SDL_ResumeAudioDevice(devid_out); } } } - if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) { + if (!SDL_IsAudioDevicePaused(devid_in)) { SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); } else { SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); @@ -60,13 +62,26 @@ static void loop(void) SDL_RenderClear(renderer); SDL_RenderPresent(renderer); + /* Feed any new data we captured to the output stream. It'll play when we unpause the device. */ + while (!please_quit && (SDL_GetAudioStreamAvailable(stream_in) > 0)) { + Uint8 buf[1024]; + const int br = SDL_GetAudioStreamData(stream_in, buf, sizeof(buf)); + if (br < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to read from input audio stream: %s\n", SDL_GetError()); + please_quit = 1; + } else if (SDL_PutAudioStreamData(stream_out, buf, br) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to write to output audio stream: %s\n", SDL_GetError()); + please_quit = 1; + } + } + if (please_quit) { /* stop playing back, quit. */ SDL_Log("Shutting down.\n"); - SDL_PauseAudioDevice(devid_in); SDL_CloseAudioDevice(devid_in); - SDL_PauseAudioDevice(devid_out); SDL_CloseAudioDevice(devid_out); + SDL_DestroyAudioStream(stream_in); + SDL_DestroyAudioStream(stream_out); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); @@ -77,28 +92,18 @@ static void loop(void) done = 1; return; } - - /* 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) { - /* (NULL means "open default device.") */ - const char *devname = NULL; - SDL_AudioSpec wanted; - int devcount; - int i; + SDL_AudioDeviceID *devices; SDLTest_CommonState *state; + SDL_AudioSpec outspec; + SDL_AudioSpec inspec; + SDL_AudioDeviceID device; + SDL_AudioDeviceID want_device = SDL_AUDIO_DEVICE_DEFAULT_CAPTURE; + const char *devname = NULL; + int i; /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, 0); @@ -121,7 +126,7 @@ int main(int argc, char **argv) } } if (consumed <= 0) { - static const char *options[] = { "[driver_name]", NULL }; + static const char *options[] = { "[device_name]", NULL }; SDLTest_CommonLogUsage(state, argv[0], options); exit(1); } @@ -145,19 +150,20 @@ int main(int argc, char **argv) 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)); + devices = SDL_GetAudioCaptureDevices(NULL); + for (i = 0; devices[i] != 0; i++) { + char *name = SDL_GetAudioDeviceName(devices[i]); + SDL_Log(" Capture device #%d: '%s'\n", i, name); + if (devname && (SDL_strcmp(devname, name) == 0)) { + want_device = devices[i]; + } + SDL_free(name); } - SDL_zero(wanted); - wanted.freq = 44100; - wanted.format = SDL_AUDIO_F32SYS; - wanted.channels = 1; - wanted.samples = 4096; - wanted.callback = NULL; - - SDL_zero(spec); + if (devname && (want_device == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE)) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Didn't see a capture device named '%s', using the system default instead.\n", devname); + devname = NULL; + } /* 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, @@ -166,24 +172,42 @@ int main(int argc, char **argv) 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) { + device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, NULL); + if (!device) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError()); SDL_Quit(); exit(1); } + SDL_PauseAudioDevice(device); + SDL_GetAudioDeviceFormat(device, &outspec); + stream_out = SDL_CreateAndBindAudioStream(device, &outspec); + if (!stream_out) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream 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(devname, SDL_TRUE, &spec, &spec, 0); - if (!devid_in) { + device = SDL_OpenAudioDevice(want_device, NULL); + if (!device) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError()); SDL_Quit(); exit(1); } + SDL_PauseAudioDevice(device); + SDL_GetAudioDeviceFormat(device, &inspec); + stream_in = SDL_CreateAndBindAudioStream(device, &inspec); + if (!stream_in) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for capture: %s!\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + + SDL_SetAudioStreamFormat(stream_in, NULL, &outspec); /* make sure we output at the playback format. */ SDL_Log("Ready! Hold down mouse or finger to record!\n"); @@ -198,11 +222,7 @@ int main(int argc, char **argv) } #endif - /* SDL_DestroyRenderer(renderer); */ - /* SDL_DestroyWindow(window); */ - - /* SDL_Quit(); */ - /* SDLTest_CommonDestroyState(state); */ + SDLTest_CommonDestroyState(state); return 0; } diff --git a/test/testaudiohotplug.c b/test/testaudiohotplug.c index 61047a56..b919aa37 100644 --- a/test/testaudiohotplug.c +++ b/test/testaudiohotplug.c @@ -31,9 +31,6 @@ 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]; - static SDLTest_CommonState *state; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ @@ -48,31 +45,6 @@ quit(int rc) } } -static 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; static void poked(int sig) @@ -97,28 +69,35 @@ static void iteration(void) done = 1; } } else if (e.type == SDL_EVENT_AUDIO_DEVICE_ADDED) { - int index = e.adevice.which; - int iscapture = e.adevice.iscapture; - const char *name = SDL_GetAudioDeviceName(index, iscapture); + const SDL_AudioDeviceID which = (SDL_AudioDeviceID ) e.adevice.which; + const SDL_bool iscapture = e.adevice.iscapture ? SDL_TRUE : SDL_FALSE; + char *name = SDL_GetAudioDeviceName(which); if (name != NULL) { - SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int)index, name); + SDL_Log("New %s audio device at id %u: %s", devtypestr(iscapture), (unsigned int)which, 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()); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device, id %u, but failed to get the name: %s", + devtypestr(iscapture), (unsigned int)which, SDL_GetError()); continue; } if (!iscapture) { - positions[posindex] = 0; - spec.userdata = &positions[posindex++]; - spec.callback = fillerup; - dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0); + dev = SDL_OpenAudioDevice(which, &spec); if (!dev) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError()); } else { + SDL_AudioStream *stream; SDL_Log("Opened '%s' as %u\n", name, (unsigned int)dev); - SDL_PlayAudioDevice(dev); + stream = SDL_CreateAndBindAudioStream(dev, &spec); + if (!stream) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create/bind an audio stream to %u ('%s'): %s", (unsigned int) dev, name, SDL_GetError()); + SDL_CloseAudioDevice(dev); + } + /* !!! FIXME: laziness, this used to loop the audio, but we'll just play it once for now on each connect. */ + SDL_PutAudioStreamData(stream, sound, soundlen); + SDL_FlushAudioStream(stream); + /* !!! FIXME: this is leaking the stream for now. We'll wire it up to a dictionary or whatever later. */ } } + SDL_free(name); } else if (e.type == SDL_EVENT_AUDIO_DEVICE_REMOVED) { dev = (SDL_AudioDeviceID)e.adevice.which; SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int)dev); @@ -194,7 +173,7 @@ int main(int argc, char *argv[]) } /* Load the wave file into memory */ - if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) { + if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); quit(1); } diff --git a/test/testaudioinfo.c b/test/testaudioinfo.c index 54ad1b96..636d4aaf 100644 --- a/test/testaudioinfo.c +++ b/test/testaudioinfo.c @@ -14,29 +14,30 @@ #include static void -print_devices(int iscapture) +print_devices(SDL_bool iscapture) { SDL_AudioSpec spec; const char *typestr = ((iscapture) ? "capture" : "output"); - int n = SDL_GetNumAudioDevices(iscapture); + int n = 0; + SDL_AudioDeviceID *devices = iscapture ? SDL_GetAudioCaptureDevices(&n) : SDL_GetAudioOutputDevices(&n); - 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); + if (devices == NULL) { + SDL_Log(" Driver failed to report %s devices: %s\n\n", typestr, SDL_GetError()); } else if (n == 0) { SDL_Log(" No %s devices found.\n\n", typestr); } else { int i; + SDL_Log("Found %d %s device%s:\n", n, typestr, n != 1 ? "s" : ""); for (i = 0; i < n; i++) { - const char *name = SDL_GetAudioDeviceName(i, iscapture); + char *name = SDL_GetAudioDeviceName(devices[i]); if (name != NULL) { SDL_Log(" %d: %s\n", i, name); + SDL_free(name); } else { SDL_Log(" %d Error: %s\n", i, SDL_GetError()); } - if (SDL_GetAudioDeviceSpec(i, iscapture, &spec) == 0) { + if (SDL_GetAudioDeviceFormat(devices[i], &spec) == 0) { SDL_Log(" Sample Rate: %d\n", spec.freq); SDL_Log(" Channels: %d\n", spec.channels); SDL_Log(" SDL_AudioFormat: %X\n", spec.format); @@ -44,11 +45,11 @@ print_devices(int iscapture) } SDL_Log("\n"); } + SDL_free(devices); } int main(int argc, char **argv) { - char *deviceName = NULL; SDL_AudioSpec spec; int i; int n; @@ -88,24 +89,22 @@ int main(int argc, char **argv) SDL_Log("Using audio driver: %s\n\n", SDL_GetCurrentAudioDriver()); - print_devices(0); - print_devices(1); + print_devices(SDL_FALSE); + print_devices(SDL_TRUE); - if (SDL_GetDefaultAudioInfo(&deviceName, &spec, 0) < 0) { - SDL_Log("Error when calling SDL_GetDefaultAudioInfo: %s\n", SDL_GetError()); + if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec) < 0) { + SDL_Log("Error when calling SDL_GetAudioDeviceFormat(default output): %s\n", SDL_GetError()); } else { - SDL_Log("Default Output Name: %s\n", deviceName != NULL ? deviceName : "unknown"); - SDL_free(deviceName); + SDL_Log("Default Output Device:\n"); SDL_Log("Sample Rate: %d\n", spec.freq); SDL_Log("Channels: %d\n", spec.channels); SDL_Log("SDL_AudioFormat: %X\n", spec.format); } - if (SDL_GetDefaultAudioInfo(&deviceName, &spec, 1) < 0) { - SDL_Log("Error when calling SDL_GetDefaultAudioInfo: %s\n", SDL_GetError()); + if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_CAPTURE, &spec) < 0) { + SDL_Log("Error when calling SDL_GetAudioDeviceFormat(default capture): %s\n", SDL_GetError()); } else { - SDL_Log("Default Capture Name: %s\n", deviceName != NULL ? deviceName : "unknown"); - SDL_free(deviceName); + SDL_Log("Default Capture Device:\n"); SDL_Log("Sample Rate: %d\n", spec.freq); SDL_Log("Channels: %d\n", spec.channels); SDL_Log("SDL_AudioFormat: %X\n", spec.format); @@ -115,3 +114,4 @@ int main(int argc, char **argv) SDLTest_CommonDestroyState(state); return 0; } + diff --git a/test/testaudiostreamdynamicresample.c b/test/testaudiostreamdynamicresample.c index 66600181..96c4caff 100644 --- a/test/testaudiostreamdynamicresample.c +++ b/test/testaudiostreamdynamicresample.c @@ -15,108 +15,176 @@ #include #include #include +#include "testutils.h" -static void SDLCALL audio_callback(void *userdata, Uint8 * stream, int len) +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include + +#define SLIDER_WIDTH_PERC 500.f / 600.f +#define SLIDER_HEIGHT_PERC 100.f / 480.f + +static int done; +static SDLTest_CommonState *state; + +static int multiplier = 100; +static SDL_FRect slider_area; +static SDL_FRect slider_fill_area; +static SDL_AudioSpec spec; +static SDL_AudioStream *stream; +static Uint8 *audio_buf = NULL; +static Uint32 audio_len = 0; + +static void loop(void) { - SDL_AudioStream *audiostream = (SDL_AudioStream *) userdata; - SDL_memset(stream, 0, len); - SDL_GetAudioStreamData(audiostream, stream, len); + int i; + SDL_Event e; + int newmultiplier = multiplier; + + while (SDL_PollEvent(&e)) { + SDLTest_CommonEvent(state, &e, &done); +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif + if (e.type == SDL_EVENT_MOUSE_MOTION) { + if (e.motion.state & SDL_BUTTON_LMASK) { + const SDL_FPoint p = { e.motion.x, e.motion.y }; + if (SDL_PointInRectFloat(&p, &slider_area)) { + const float w = SDL_roundf(p.x - slider_area.x); + slider_fill_area.w = w; + newmultiplier = ((int) ((w / slider_area.w) * 800.0f)) - 400; + } + } + } + } + + if (multiplier != newmultiplier) { + SDL_AudioSpec newspec; + char title[64]; + int newfreq = spec.freq; + + multiplier = newmultiplier; + if (multiplier == 0) { + SDL_snprintf(title, sizeof (title), "Drag the slider: Normal speed"); + } else if (multiplier < 0) { + SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx slow", (-multiplier / 100.0f) + 1.0f); + } else { + SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx fast", (multiplier / 100.0f) + 1.0f); + } + for (i = 0; i < state->num_windows; i++) { + SDL_SetWindowTitle(state->windows[i], title); + } + + /* this math sucks, but whatever. */ + if (multiplier < 0) { + newfreq = spec.freq + (int) ((spec.freq * (multiplier / 400.0f)) * 0.75f); + } else if (multiplier > 0) { + newfreq = spec.freq + (int) (spec.freq * (multiplier / 100.0f)); + } + /* SDL_Log("newfreq=%d multiplier=%d\n", newfreq, multiplier); */ + SDL_memcpy(&newspec, &spec, sizeof (spec)); + newspec.freq = newfreq; + SDL_SetAudioStreamFormat(stream, &newspec, NULL); + } + + /* keep it looping. */ + if (SDL_GetAudioStreamAvailable(stream) < ((int) (audio_len / 2))) { + SDL_PutAudioStreamData(stream, audio_buf, audio_len); + } + + for (i = 0; i < state->num_windows; i++) { + SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 255, 255); + SDL_RenderClear(state->renderers[i]); + SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 0, 255); + SDL_RenderFillRect(state->renderers[i], &slider_area); + SDL_SetRenderDrawColor(state->renderers[i], 255, 0, 0, 255); + SDL_RenderFillRect(state->renderers[i], &slider_fill_area); + SDL_RenderPresent(state->renderers[i]); + } } int main(int argc, char *argv[]) { - SDL_Window *window; - SDL_Renderer *renderer; - SDL_bool done = SDL_FALSE; - const SDL_FRect slider_area = { (640 - 500) / 2, (480 - 100) / 2, 500, 100 }; - SDL_FRect slider_fill_area = slider_area; - int multiplier = 100; - SDL_AudioSpec spec; - Uint8 *audio_buf = NULL; - Uint32 audio_len = 0; - SDL_AudioStream *stream; - SDL_AudioDeviceID device; + char *filename = NULL; + int i; + int rc; - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); - window = SDL_CreateWindow("Drag the slider: Normal speed", 640, 480, 0); - renderer = SDL_CreateRenderer(window, NULL, 0); - - SDL_LoadWAV("sample.wav", &spec, &audio_buf, &audio_len); - stream = SDL_CreateAudioStream(spec.format, spec.channels, spec.freq, spec.format, spec.channels, spec.freq); - SDL_PutAudioStreamData(stream, audio_buf, audio_len); - spec.callback = audio_callback; - spec.userdata = stream; - device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &spec, NULL, 0); - SDL_PlayAudioDevice(device); - - slider_fill_area.w /= 2; - - while (!done) { - SDL_Event e; - int newmultiplier = multiplier; - while (SDL_PollEvent(&e)) { - if (e.type == SDL_EVENT_QUIT) { - done = 1; - } else if (e.type == SDL_EVENT_KEY_DOWN) { - if (e.key.keysym.sym == SDLK_ESCAPE) { - done = 1; - } - } else if (e.type == SDL_EVENT_MOUSE_MOTION) { - if (e.motion.state & SDL_BUTTON_LMASK) { - const SDL_FPoint p = { e.motion.x, e.motion.y }; - if (SDL_PointInRectFloat(&p, &slider_area)) { - const float w = SDL_roundf(p.x - slider_area.x); - slider_fill_area.w = w; - newmultiplier = ((int) ((w / slider_area.w) * 800.0f)) - 400; - } - } - } - } - - if (multiplier != newmultiplier) { - char title[64]; - int newfreq = spec.freq; - - multiplier = newmultiplier; - if (multiplier == 0) { - SDL_snprintf(title, sizeof (title), "Drag the slider: Normal speed"); - } else if (multiplier < 0) { - SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx slow", (-multiplier / 100.0f) + 1.0f); - } else { - SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx fast", (multiplier / 100.0f) + 1.0f); - } - SDL_SetWindowTitle(window, title); - - /* this math sucks, but whatever. */ - if (multiplier < 0) { - newfreq = spec.freq + (int) ((spec.freq * (multiplier / 400.0f)) * 0.75f); - } else if (multiplier > 0) { - newfreq = spec.freq + (int) (spec.freq * (multiplier / 100.0f)); - } - /* SDL_Log("newfreq=%d multiplier=%d\n", newfreq, multiplier); */ - SDL_LockAudioDevice(device); - SDL_SetAudioStreamFormat(stream, spec.format, spec.channels, newfreq, spec.format, spec.channels, spec.freq); - SDL_UnlockAudioDevice(device); - } - - /* keep it looping. */ - if (SDL_GetAudioStreamAvailable(stream) < (1024 * 100)) { - SDL_PutAudioStreamData(stream, audio_buf, audio_len); - } - - SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); - SDL_RenderClear(renderer); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderFillRect(renderer, &slider_area); - SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); - SDL_RenderFillRect(renderer, &slider_fill_area); - SDL_RenderPresent(renderer); + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, SDL_INIT_AUDIO | SDL_INIT_VIDEO); + if (state == NULL) { + return 1; } - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_CloseAudioDevice(device); + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Parse commandline */ + for (i = 1; i < argc;) { + int consumed; + + consumed = SDLTest_CommonArg(state, i); + if (!consumed) { + if (!filename) { + filename = argv[i]; + consumed = 1; + } + } + if (consumed <= 0) { + static const char *options[] = { "[sample.wav]", NULL }; + SDLTest_CommonLogUsage(state, argv[0], options); + exit(1); + } + + i += consumed; + } + + slider_area.x = state->window_w * (1.f - SLIDER_WIDTH_PERC) / 2; + slider_area.y = state->window_h * (1.f - SLIDER_HEIGHT_PERC) / 2; + slider_area.w = SLIDER_WIDTH_PERC * state->window_w; + slider_area.h = SLIDER_HEIGHT_PERC * state->window_h; + + slider_fill_area = slider_area; + slider_fill_area.w /= 2; + + /* Load the SDL library */ + if (!SDLTest_CommonInit(state)) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + filename = GetResourceFilename(filename, "sample.wav"); + rc = SDL_LoadWAV(filename, &spec, &audio_buf, &audio_len); + SDL_free(filename); + + if (rc < 0) { + SDL_Log("Failed to load '%s': %s", filename, SDL_GetError()); + SDL_Quit(); + return 1; + } + + for (i = 0; i < state->num_windows; i++) { + SDL_SetWindowTitle(state->windows[i], "Drag the slider: Normal speed"); + } + + stream = SDL_CreateAudioStream(&spec, &spec); + SDL_PutAudioStreamData(stream, audio_buf, audio_len); + SDL_BindAudioStream(state->audio_id, stream); + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + loop(); + } +#endif + + SDL_DestroyAudioStream(stream); SDL_free(audio_buf); + SDLTest_CommonQuit(state); SDL_Quit(); return 0; } diff --git a/test/testautomation_audio.c b/test/testautomation_audio.c index 9cd98a85..d7a7c659 100644 --- a/test/testautomation_audio.c +++ b/test/testautomation_audio.c @@ -38,6 +38,7 @@ static void audioTearDown(void *arg) SDLTest_AssertPass("Cleanup of test files completed"); } +#if 0 /* !!! FIXME: maybe update this? */ /* Global counter for callback invocation */ static int g_audio_testCallbackCounter; @@ -51,6 +52,7 @@ static void SDLCALL audio_testCallback(void *userdata, Uint8 *stream, int len) g_audio_testCallbackCounter++; g_audio_testCallbackLength += len; } +#endif static SDL_AudioDeviceID g_audio_id = -1; @@ -176,28 +178,22 @@ static int audio_initOpenCloseQuitAudio(void *arg) desired.freq = 22050; desired.format = SDL_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 = SDL_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_OpenAudioDevice(NULL, 0, &desired, NULL, 0); + result = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &desired); if (k == 0) { g_audio_id = result; } - SDLTest_AssertPass("Call to SDL_OpenAudioDevice(NULL, 0, desired_spec_%d, NULL, 0), call %d", j, k + 1); + SDLTest_AssertPass("Call to SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, desired_spec_%d), call %d", j, k + 1); SDLTest_AssertCheck(result > 0, "Verify return value; expected: > 0, got: %d", result); } @@ -230,11 +226,9 @@ static int audio_initOpenCloseQuitAudio(void *arg) */ static int audio_pauseUnpauseAudio(void *arg) { + int iMax; + int i, j /*, k, l*/; int result; - int i, iMax, j, k, l; - int totalDelay; - int pause_on; - int originalCounter; const char *audioDriver; SDL_AudioSpec desired; @@ -269,9 +263,6 @@ static int audio_pauseUnpauseAudio(void *arg) desired.freq = 22050; desired.format = SDL_AUDIO_S16SYS; desired.channels = 2; - desired.samples = 4096; - desired.callback = audio_testCallback; - desired.userdata = NULL; break; case 1: @@ -279,18 +270,16 @@ static int audio_pauseUnpauseAudio(void *arg) desired.freq = 48000; desired.format = SDL_AUDIO_F32SYS; desired.channels = 2; - desired.samples = 2048; - desired.callback = audio_testCallback; - desired.userdata = NULL; break; } /* Call Open */ - g_audio_id = SDL_OpenAudioDevice(NULL, 0, &desired, NULL, 0); + g_audio_id = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &desired); result = g_audio_id; - SDLTest_AssertPass("Call to SDL_OpenAudioDevice(NULL, 0, desired_spec_%d, NULL, 0)", j); + SDLTest_AssertPass("Call to SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, desired_spec_%d)", j); SDLTest_AssertCheck(result > 0, "Verify return value; expected > 0 got: %d", result); +#if 0 /* !!! FIXME: maybe update this? */ /* Start and stop audio multiple times */ for (l = 0; l < 3; l++) { SDLTest_Log("Pause/Unpause iteration: %d", l + 1); @@ -300,14 +289,13 @@ static int audio_pauseUnpauseAudio(void *arg) g_audio_testCallbackLength = 0; /* Un-pause audio to start playing (maybe multiple times) */ - pause_on = 0; for (k = 0; k <= j; k++) { SDL_PlayAudioDevice(g_audio_id); SDLTest_AssertPass("Call to SDL_PlayAudioDevice(g_audio_id), call %d", k + 1); } /* Wait for callback */ - totalDelay = 0; + int totalDelay = 0; do { SDL_Delay(10); totalDelay += 10; @@ -317,7 +305,7 @@ static int audio_pauseUnpauseAudio(void *arg) /* Pause audio to stop playing (maybe multiple times) */ for (k = 0; k <= j; k++) { - pause_on = (k == 0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999); + const int pause_on = (k == 0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999); if (pause_on) { SDL_PauseAudioDevice(g_audio_id); SDLTest_AssertPass("Call to SDL_PauseAudioDevice(g_audio_id), call %d", k + 1); @@ -328,10 +316,11 @@ static int audio_pauseUnpauseAudio(void *arg) } /* Ensure callback is not called again */ - originalCounter = g_audio_testCallbackCounter; + const int originalCounter = g_audio_testCallbackCounter; SDL_Delay(totalDelay + 10); SDLTest_AssertCheck(originalCounter == g_audio_testCallbackCounter, "Verify callback counter; expected: %d, got: %d", originalCounter, g_audio_testCallbackCounter); } +#endif /* Call Close */ SDL_CloseAudioDevice(g_audio_id); @@ -358,51 +347,34 @@ static int audio_pauseUnpauseAudio(void *arg) */ static int audio_enumerateAndNameAudioDevices(void *arg) { - int t, tt; - int i, n, nn; - const char *name, *nameAgain; + int t; + int i, n; + char *name; + SDL_AudioDeviceID *devices = NULL; /* 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); + devices = (t) ? SDL_GetAudioCaptureDevices(&n) : SDL_GetAudioOutputDevices(&n); + SDLTest_AssertPass("Call to SDL_GetAudio%sDevices(%i)", (t) ? "Capture" : "Output", 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) { + SDLTest_AssertCheck(devices != NULL, "Validate devices is not NULL if n > 0"); for (i = 0; i < n; i++) { - name = SDL_GetAudioDeviceName(i, t); - SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); - SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, t); + name = SDL_GetAudioDeviceName(devices[i]); + SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i)", i); + SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i) is not NULL", i); if (name != NULL) { - SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, t, name); - if (t == 1) { - /* Also try non-zero type */ - tt = t + SDLTest_RandomIntegerInRange(1, 10); - nameAgain = SDL_GetAudioDeviceName(i, tt); - SDLTest_AssertCheck(nameAgain != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, tt); - if (nameAgain != NULL) { - SDLTest_AssertCheck(nameAgain[0] != '\0', "Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, tt, nameAgain); - SDLTest_AssertCheck(SDL_strcmp(name, nameAgain) == 0, - "Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string", - i, t, i, tt); - } - } + SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i) is not empty, got: '%s'", i, name); + SDL_free(name); } } } + + SDL_free(devices); } return TEST_COMPLETED; @@ -416,42 +388,7 @@ static int audio_enumerateAndNameAudioDevices(void *arg) */ static int audio_enumerateAndNameAudioDevicesNegativeTests(void *arg) { - int t; - int i, j, no, nc; - const char *name; - - /* Get number of devices. */ - no = SDL_GetNumAudioDevices(0); - SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); - nc = SDL_GetNumAudioDevices(1); - SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(1)"); - - /* Invalid device index when getting name */ - for (t = 0; t < 2; t++) { - /* Negative device index */ - i = SDLTest_RandomIntegerInRange(-10, -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 NULL, expected NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); - - /* Device index past range */ - for (j = 0; j < 3; j++) { - i = (t) ? nc + j : no + j; - 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); - } - - /* Capture index past capture range but within output range */ - if ((no > 0) && (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; + return TEST_COMPLETED; /* nothing in here atm since these interfaces changed in SDL3. */ } /** @@ -532,8 +469,7 @@ static int audio_buildAudioStream(void *arg) spec1.format = SDL_AUDIO_S16LSB; spec1.channels = 2; spec1.freq = 22050; - stream = SDL_CreateAudioStream(spec1.format, spec1.channels, spec1.freq, - spec1.format, spec1.channels, spec1.freq); + stream = SDL_CreateAudioStream(&spec1, &spec1); SDLTest_AssertPass("Call to SDL_CreateAudioStream(spec1 ==> spec1)"); SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", (void *)stream); SDL_DestroyAudioStream(stream); @@ -545,8 +481,7 @@ static int audio_buildAudioStream(void *arg) spec2.format = SDL_AUDIO_S16LSB; spec2.channels = 2; spec2.freq = 44100; - stream = SDL_CreateAudioStream(spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); + stream = SDL_CreateAudioStream(&spec1, &spec2); SDLTest_AssertPass("Call to SDL_CreateAudioStream(spec1 ==> spec2)"); SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", (void *)stream); SDL_DestroyAudioStream(stream); @@ -564,8 +499,7 @@ static int audio_buildAudioStream(void *arg) spec2.format = g_audioFormats[ii]; spec2.channels = g_audioChannels[jj]; spec2.freq = g_audioFrequencies[kk]; - stream = SDL_CreateAudioStream(spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); + stream = SDL_CreateAudioStream(&spec1, &spec2); SDLTest_AssertPass("Call to SDL_CreateAudioStream(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", i, g_audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, g_audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); @@ -646,8 +580,7 @@ static int audio_buildAudioStreamNegative(void *arg) spec2.freq = 0; } SDLTest_Log("%s", message); - stream = SDL_CreateAudioStream(spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); + stream = SDL_CreateAudioStream(&spec1, &spec2); SDLTest_AssertPass("Call to SDL_CreateAudioStream(spec1 ==> spec2)"); SDLTest_AssertCheck(stream == NULL, "Verify stream value; expected: NULL, got: %p", (void *)stream); error = SDL_GetError(); @@ -669,16 +602,7 @@ static int audio_buildAudioStreamNegative(void *arg) */ static int audio_getAudioStatus(void *arg) { - SDL_AudioStatus result; - - /* Check current audio status */ - result = SDL_GetAudioDeviceStatus(g_audio_id); - SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus(g_audio_id)"); - 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; + return TEST_COMPLETED; /* no longer a thing in SDL3. */ } /** @@ -688,57 +612,7 @@ static int audio_getAudioStatus(void *arg) */ static int audio_openCloseAndGetAudioStatus(void *arg) { - SDL_AudioStatus result; - int i; - int count; - const 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 = 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 = SDL_AUDIO_S16SYS; - desired.channels = 2; - desired.samples = 4096; - desired.callback = audio_testCallback; - desired.userdata = NULL; - - /* Open device */ - id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); - SDLTest_AssertCheck(id > 0, "Validate device ID; expected: > 0, got: %" SDL_PRIu32, id); - if (id > 0) { - - /* 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; + return TEST_COMPLETED; /* not a thing in SDL3. */ } /** @@ -749,60 +623,7 @@ static int audio_openCloseAndGetAudioStatus(void *arg) */ static int audio_lockUnlockOpenAudioDevice(void *arg) { - int i; - int count; - const 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 = 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 = SDL_AUDIO_S16SYS; - desired.channels = 2; - desired.samples = 4096; - desired.callback = audio_testCallback; - desired.userdata = NULL; - - /* Open device */ - id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); - SDLTest_AssertCheck(id > 1, "Validate device ID; expected: > 0, got: %" SDL_PRIu32, id); - if (id > 0) { - /* Lock to protect callback */ - SDL_LockAudioDevice(id); - SDLTest_AssertPass("SDL_LockAudioDevice(%" SDL_PRIu32 ")", id); - - /* Simulate callback processing */ - SDL_Delay(10); - SDLTest_Log("Simulate callback processing - delay"); - - /* Unlock again */ - SDL_UnlockAudioDevice(id); - SDLTest_AssertPass("SDL_UnlockAudioDevice(%" SDL_PRIu32 ")", id); - - /* Close device again */ - SDL_CloseAudioDevice(id); - SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); - } - } - } else { - SDLTest_Log("No devices to test with"); - } - - return TEST_COMPLETED; + return TEST_COMPLETED; /* not a thing in SDL3 */ } /** @@ -862,8 +683,7 @@ static int audio_convertAudio(void *arg) spec2.channels = g_audioChannels[jj]; spec2.freq = g_audioFrequencies[kk]; - stream = SDL_CreateAudioStream(spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); + stream = SDL_CreateAudioStream(&spec1, &spec2); SDLTest_AssertPass("Call to SDL_CreateAudioStream(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", i, g_audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, g_audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); SDLTest_AssertCheck(stream != NULL, "Verify stream value; expected: != NULL, got: %p", (void *)stream); @@ -936,59 +756,7 @@ static int audio_convertAudio(void *arg) */ static int audio_openCloseAudioDeviceConnected(void *arg) { - int result = -1; - int i; - int count; - const 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 = 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 = SDL_AUDIO_S16SYS; - desired.channels = 2; - desired.samples = 4096; - desired.callback = audio_testCallback; - desired.userdata = NULL; - - /* Open device */ - id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); - SDLTest_AssertCheck(id > 0, "Validate device ID; expected: > 0, got: %" SDL_PRIu32, id); - if (id > 0) { - - /* TODO: enable test code when function is available in SDL3 */ - -#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; + return TEST_COMPLETED; /* not a thing in SDL3. */ } static double sine_wave_sample(const Sint64 idx, const Sint64 rate, const Sint64 freq, const double phase) @@ -1040,6 +808,7 @@ static int audio_resampleLoss(void *arg) const int len_in = frames_in * (int)sizeof(float); const int len_target = frames_target * (int)sizeof(float); + SDL_AudioSpec tmpspec1, tmpspec2; Uint64 tick_beg = 0; Uint64 tick_end = 0; int i = 0; @@ -1056,7 +825,13 @@ static int audio_resampleLoss(void *arg) SDLTest_AssertPass("Test resampling of %i s %i Hz %f phase sine wave from sampling rate of %i Hz to %i Hz", spec->time, spec->freq, spec->phase, spec->rate_in, spec->rate_out); - stream = SDL_CreateAudioStream(SDL_AUDIO_F32, 1, spec->rate_in, SDL_AUDIO_F32, 1, spec->rate_out); + tmpspec1.format = SDL_AUDIO_F32; + tmpspec1.channels = 1; + tmpspec1.freq = spec->rate_in; + tmpspec2.format = SDL_AUDIO_F32; + tmpspec2.channels = 1; + tmpspec2.freq = spec->rate_out; + stream = SDL_CreateAudioStream(&tmpspec1, &tmpspec2); SDLTest_AssertPass("Call to SDL_CreateAudioStream(SDL_AUDIO_F32, 1, %i, SDL_AUDIO_F32, 1, %i)", spec->rate_in, spec->rate_out); SDLTest_AssertCheck(stream != NULL, "Expected SDL_CreateAudioStream to succeed."); if (stream == NULL) { diff --git a/test/testautomation_rwops.c b/test/testautomation_rwops.c index dba85a2a..a8cdb903 100644 --- a/test/testautomation_rwops.c +++ b/test/testautomation_rwops.c @@ -95,11 +95,11 @@ static void RWopsTearDown(void *arg) * \sa SDL_RWseek * \sa SDL_RWread */ -static void testGenericRWopsValidations(SDL_RWops *rw, int write) +static void testGenericRWopsValidations(SDL_RWops *rw, SDL_bool write) { char buf[sizeof(RWopsHelloWorldTestString)]; Sint64 i; - Sint64 s; + size_t s; int seekPos = SDLTest_RandomIntegerInRange(4, 8); /* Clear buffer */ @@ -116,7 +116,7 @@ static void testGenericRWopsValidations(SDL_RWops *rw, int write) if (write) { SDLTest_AssertCheck(s == sizeof(RWopsHelloWorldTestString) - 1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int)s); } else { - SDLTest_AssertCheck(s == -1, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s); + SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s); } /* Test seek to random position */ @@ -133,7 +133,7 @@ static void testGenericRWopsValidations(SDL_RWops *rw, int write) s = SDL_RWread(rw, buf, sizeof(RWopsHelloWorldTestString) - 1); SDLTest_AssertPass("Call to SDL_RWread succeeded"); SDLTest_AssertCheck( - s == (size_t)(sizeof(RWopsHelloWorldTestString) - 1), + s == (sizeof(RWopsHelloWorldTestString) - 1), "Verify result from SDL_RWread, expected %i, got %i", (int)(sizeof(RWopsHelloWorldTestString) - 1), (int)s); @@ -242,7 +242,7 @@ static int rwops_testMem(void *arg) SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY, "Verify RWops type is SDL_RWOPS_MEMORY; expected: %d, got: %" SDL_PRIu32, SDL_RWOPS_MEMORY, rw->type); /* Run generic tests */ - testGenericRWopsValidations(rw, 1); + testGenericRWopsValidations(rw, SDL_TRUE); /* Close */ result = SDL_RWclose(rw); @@ -277,7 +277,7 @@ static int rwops_testConstMem(void *arg) SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY_RO, "Verify RWops type is SDL_RWOPS_MEMORY_RO; expected: %d, got: %" SDL_PRIu32, SDL_RWOPS_MEMORY_RO, rw->type); /* Run generic tests */ - testGenericRWopsValidations(rw, 0); + testGenericRWopsValidations(rw, SDL_FALSE); /* Close handle */ result = SDL_RWclose(rw); @@ -324,7 +324,7 @@ static int rwops_testFileRead(void *arg) #endif /* Run generic tests */ - testGenericRWopsValidations(rw, 0); + testGenericRWopsValidations(rw, SDL_FALSE); /* Close handle */ result = SDL_RWclose(rw); @@ -371,7 +371,7 @@ static int rwops_testFileWrite(void *arg) #endif /* Run generic tests */ - testGenericRWopsValidations(rw, 1); + testGenericRWopsValidations(rw, SDL_TRUE); /* Close handle */ result = SDL_RWclose(rw); @@ -437,7 +437,7 @@ static int rwops_testCompareRWFromMemWithRWFromFile(void *arg) /* Read/seek from memory */ rwops_mem = SDL_RWFromMem((void *)RWopsAlphabetString, slen); SDLTest_AssertPass("Call to SDL_RWFromMem()"); - rv_mem = (size_t)SDL_RWread(rwops_mem, buffer_mem, size * 6); + rv_mem = SDL_RWread(rwops_mem, buffer_mem, size * 6); SDLTest_AssertPass("Call to SDL_RWread(mem, size=%d)", size * 6); sv_mem = SDL_RWseek(rwops_mem, 0, SEEK_END); SDLTest_AssertPass("Call to SDL_RWseek(mem,SEEK_END)"); @@ -448,7 +448,7 @@ static int rwops_testCompareRWFromMemWithRWFromFile(void *arg) /* Read/see from file */ rwops_file = SDL_RWFromFile(RWopsAlphabetFilename, "r"); SDLTest_AssertPass("Call to SDL_RWFromFile()"); - rv_file = (size_t)SDL_RWread(rwops_file, buffer_file, size * 6); + rv_file = SDL_RWread(rwops_file, buffer_file, size * 6); SDLTest_AssertPass("Call to SDL_RWread(file, size=%d)", size * 6); sv_file = SDL_RWseek(rwops_file, 0, SEEK_END); SDLTest_AssertPass("Call to SDL_RWseek(file,SEEK_END)"); @@ -477,15 +477,14 @@ static int rwops_testCompareRWFromMemWithRWFromFile(void *arg) * * \sa SDL_RWFromFile * \sa SDL_RWClose - * \sa SDL_ReadBE16 - * \sa SDL_WriteBE16 + * \sa SDL_ReadU16BE + * \sa SDL_WriteU16BE */ static int rwops_testFileWriteReadEndian(void *arg) { SDL_RWops *rw; Sint64 result; int mode; - size_t objectsWritten; Uint16 BE16value; Uint32 BE32value; Uint64 BE64value; @@ -498,6 +497,7 @@ static int rwops_testFileWriteReadEndian(void *arg) Uint16 LE16test; Uint32 LE32test; Uint64 LE64test; + SDL_bool bresult; int cresult; for (mode = 0; mode < 3; mode++) { @@ -545,24 +545,24 @@ static int rwops_testFileWriteReadEndian(void *arg) } /* 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); + bresult = SDL_WriteU16BE(rw, BE16value); + SDLTest_AssertPass("Call to SDL_WriteU16BE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE"); + bresult = SDL_WriteU32BE(rw, BE32value); + SDLTest_AssertPass("Call to SDL_WriteU32BE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE"); + bresult = SDL_WriteU64BE(rw, BE64value); + SDLTest_AssertPass("Call to SDL_WriteU64BE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE"); + bresult = SDL_WriteU16LE(rw, LE16value); + SDLTest_AssertPass("Call to SDL_WriteU16LE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE"); + bresult = SDL_WriteU32LE(rw, LE32value); + SDLTest_AssertPass("Call to SDL_WriteU32LE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE"); + bresult = SDL_WriteU64LE(rw, LE64value); + SDLTest_AssertPass("Call to SDL_WriteU64LE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object written, expected: SDL_TRUE, got: SDL_FALSE"); /* Test seek to start */ result = SDL_RWseek(rw, 0, SDL_RW_SEEK_SET); @@ -570,24 +570,30 @@ static int rwops_testFileWriteReadEndian(void *arg) 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: %" SDL_PRIu32 ", got: %" SDL_PRIu32, 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: %" SDL_PRIu32 ", got: %" SDL_PRIu32, 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); + bresult = SDL_ReadU16BE(rw, &BE16test); + SDLTest_AssertPass("Call to SDL_ReadU16BE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE"); + SDLTest_AssertCheck(BE16test == BE16value, "Validate object read from SDL_ReadU16BE, expected: %hu, got: %hu", BE16value, BE16test); + bresult = SDL_ReadU32BE(rw, &BE32test); + SDLTest_AssertPass("Call to SDL_ReadU32BE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE"); + SDLTest_AssertCheck(BE32test == BE32value, "Validate object read from SDL_ReadU32BE, expected: %" SDL_PRIu32 ", got: %" SDL_PRIu32, BE32value, BE32test); + bresult = SDL_ReadU64BE(rw, &BE64test); + SDLTest_AssertPass("Call to SDL_ReadU64BE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE"); + SDLTest_AssertCheck(BE64test == BE64value, "Validate object read from SDL_ReadU64BE, expected: %" SDL_PRIu64 ", got: %" SDL_PRIu64, BE64value, BE64test); + bresult = SDL_ReadU16LE(rw, &LE16test); + SDLTest_AssertPass("Call to SDL_ReadU16LE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE"); + SDLTest_AssertCheck(LE16test == LE16value, "Validate object read from SDL_ReadU16LE, expected: %hu, got: %hu", LE16value, LE16test); + bresult = SDL_ReadU32LE(rw, &LE32test); + SDLTest_AssertPass("Call to SDL_ReadU32LE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE"); + SDLTest_AssertCheck(LE32test == LE32value, "Validate object read from SDL_ReadU32LE, expected: %" SDL_PRIu32 ", got: %" SDL_PRIu32, LE32value, LE32test); + bresult = SDL_ReadU64LE(rw, &LE64test); + SDLTest_AssertPass("Call to SDL_ReadU64LE()"); + SDLTest_AssertCheck(bresult == SDL_TRUE, "Validate object read, expected: SDL_TRUE, got: SDL_FALSE"); + SDLTest_AssertCheck(LE64test == LE64value, "Validate object read from SDL_ReadU64LE, expected: %" SDL_PRIu64 ", got: %" SDL_PRIu64, LE64value, LE64test); /* Close handle */ cresult = SDL_RWclose(rw); diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c index 3af68571..e9960f04 100644 --- a/test/testautomation_stdlib.c +++ b/test/testautomation_stdlib.c @@ -197,30 +197,34 @@ static int stdlib_snprintf(void *arg) { static struct { + int precision; float value; const char *expected_f; const char *expected_g; } f_and_g_test_cases[] = { - { 100.0f, "100.000000", "100" }, - { -100.0f, "-100.000000", "-100" }, - { 100.75f, "100.750000", "100.75" }, - { -100.75f, "-100.750000", "-100.75" }, - { ((100 * 60 * 1000) / 1001) / 100.0f, "59.939999", "59.94" }, - { -((100 * 60 * 1000) / 1001) / 100.0f, "-59.939999", "-59.94" }, - { ((100 * 120 * 1000) / 1001) / 100.0f, "119.879997", "119.88" }, - { -((100 * 120 * 1000) / 1001) / 100.0f, "-119.879997", "-119.88" }, - { 9.9999999f, "10.000000", "10" }, - { -9.9999999f, "-10.000000", "-10" }, + { 6, 100.0f, "100.000000", "100" }, + { 6, -100.0f, "-100.000000", "-100" }, + { 6, 100.75f, "100.750000", "100.75" }, + { 6, -100.75f, "-100.750000", "-100.75" }, + { 6, ((100 * 60 * 1000) / 1001) / 100.0f, "59.939999", "59.94" }, + { 6, -((100 * 60 * 1000) / 1001) / 100.0f, "-59.939999", "-59.94" }, + { 6, ((100 * 120 * 1000) / 1001) / 100.0f, "119.879997", "119.88" }, + { 6, -((100 * 120 * 1000) / 1001) / 100.0f, "-119.879997", "-119.88" }, + { 6, 0.9999999f, "1.000000", "1" }, + { 6, -0.9999999f, "-1.000000", "-1" }, + { 5, 9.999999f, "10.00000", "10" }, + { 5, -9.999999f, "-10.00000", "-10" }, }; int i; for (i = 0; i < SDL_arraysize(f_and_g_test_cases); ++i) { float value = f_and_g_test_cases[i].value; + int prec = f_and_g_test_cases[i].precision; - result = SDL_snprintf(text, sizeof(text), "%f", value); - predicted = SDL_snprintf(NULL, 0, "%f", value); + result = SDL_snprintf(text, sizeof(text), "%.*f", prec, value); + predicted = SDL_snprintf(NULL, 0, "%.*f", prec, value); expected = f_and_g_test_cases[i].expected_f; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", %g)", value); + SDLTest_AssertPass("Call to SDL_snprintf(\"%%.5f\", %g)", value); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text); SDLTest_AssertCheck(result == SDL_strlen(expected), "Check result value, expected: %d, got: %d", (int)SDL_strlen(expected), result); SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted); diff --git a/test/testautomation_video.c b/test/testautomation_video.c index 8300b2ce..b57fb821 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -15,6 +15,7 @@ static SDL_Window *createVideoSuiteTestWindow(const char *title) SDL_Window *window; int w, h; SDL_WindowFlags flags; + SDL_bool needs_renderer = SDL_FALSE; /* Standard window */ w = SDLTest_RandomIntegerInRange(320, 1024); @@ -25,6 +26,35 @@ static SDL_Window *createVideoSuiteTestWindow(const char *title) SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d)", w, h, flags); SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); + /* Wayland and XWayland windows require that a frame be presented before they are fully mapped and visible onscreen. + * This is required for the mouse/keyboard grab tests to pass. + */ + if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) { + needs_renderer = SDL_TRUE; + } else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) { + /* Try to detect if the x11 driver is running under XWayland */ + const char *session_type = SDL_getenv("XDG_SESSION_TYPE"); + if (session_type && SDL_strcasecmp(session_type, "wayland") == 0) { + needs_renderer = SDL_TRUE; + } + } + + if (needs_renderer) { + SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL, 0); + if (renderer) { + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + /* Some desktops don't display the window immediately after presentation, + * so delay to give the window time to actually appear on the desktop. + */ + SDL_Delay(100); + } else { + SDLTest_Log("Unable to create a renderer, some tests may fail on Wayland/XWayland"); + } + } + return window; } @@ -1629,6 +1659,11 @@ cleanup: * * Especially useful when run on a multi-monitor system with different DPI scales per monitor, * to test that the window size is maintained when moving between monitors. + * + * As the Wayland windowing protocol does not allow application windows to control their position in the + * desktop space, coupled with the general asynchronous nature of Wayland compositors, the positioning + * tests don't work in windowed mode and are unreliable in fullscreen mode, thus are disabled when using + * the Wayland video driver. All that can be done is check that the windows are the expected size. */ static int video_setWindowCenteredOnDisplay(void *arg) { @@ -1640,6 +1675,7 @@ static int video_setWindowCenteredOnDisplay(void *arg) int displayNum; int result; SDL_Rect display0, display1; + SDL_bool video_driver_is_wayland = SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0; displays = SDL_GetDisplays(&displayNum); if (displays) { @@ -1682,18 +1718,45 @@ static int video_setWindowCenteredOnDisplay(void *arg) 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"); + /* Wayland windows require that a frame be presented before they are fully mapped and visible onscreen. */ + if (video_driver_is_wayland) { + SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL, 0); + + if (renderer) { + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + /* Some desktops don't display the window immediately after presentation, + * so delay to give the window time to actually appear on the desktop. + */ + SDL_Delay(100); + } else { + SDLTest_Log("Unable to create a renderer, tests may fail under Wayland"); + } + } + /* Check the window is centered on the requested display */ currentDisplay = SDL_GetDisplayForWindow(window); SDL_GetWindowSize(window, ¤tW, ¤tH); SDL_GetWindowPosition(window, ¤tX, ¤tY); - SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display ID (current: %d, expected: %d)", currentDisplay, expectedDisplay); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display ID (current: %d, expected: %d)", currentDisplay, expectedDisplay); + } else { + SDLTest_Log("Skipping display ID validation: Wayland driver does not support window positioning"); + } SDLTest_AssertCheck(currentW == w, "Validate width (current: %d, expected: %d)", currentW, w); SDLTest_AssertCheck(currentH == h, "Validate height (current: %d, expected: %d)", currentH, h); - SDLTest_AssertCheck(currentX == expectedX, "Validate x (current: %d, expected: %d)", currentX, expectedX); - SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentX == expectedX, "Validate x (current: %d, expected: %d)", currentX, expectedX); + SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); + } else { + SDLTest_Log("Skipping window position validation: Wayland driver does not support window positioning"); + } /* Enter fullscreen desktop */ + SDL_SetWindowPosition(window, x, y); result = SDL_SetWindowFullscreen(window, SDL_TRUE); SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); @@ -1702,11 +1765,19 @@ static int video_setWindowCenteredOnDisplay(void *arg) SDL_GetWindowSize(window, ¤tW, ¤tH); SDL_GetWindowPosition(window, ¤tX, ¤tY); - SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display ID (current: %d, expected: %d)", currentDisplay, expectedDisplay); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display ID (current: %d, expected: %d)", currentDisplay, expectedDisplay); + } else { + SDLTest_Log("Skipping display ID validation: Wayland driver does not support window positioning"); + } SDLTest_AssertCheck(currentW == expectedDisplayRect.w, "Validate width (current: %d, expected: %d)", currentW, expectedDisplayRect.w); SDLTest_AssertCheck(currentH == expectedDisplayRect.h, "Validate height (current: %d, expected: %d)", currentH, expectedDisplayRect.h); - SDLTest_AssertCheck(currentX == expectedDisplayRect.x, "Validate x (current: %d, expected: %d)", currentX, expectedDisplayRect.x); - SDLTest_AssertCheck(currentY == expectedDisplayRect.y, "Validate y (current: %d, expected: %d)", currentY, expectedDisplayRect.y); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentX == expectedDisplayRect.x, "Validate x (current: %d, expected: %d)", currentX, expectedDisplayRect.x); + SDLTest_AssertCheck(currentY == expectedDisplayRect.y, "Validate y (current: %d, expected: %d)", currentY, expectedDisplayRect.y); + } else { + SDLTest_Log("Skipping window position validation: Wayland driver does not support window positioning"); + } /* Leave fullscreen desktop */ result = SDL_SetWindowFullscreen(window, SDL_FALSE); @@ -1717,11 +1788,19 @@ static int video_setWindowCenteredOnDisplay(void *arg) SDL_GetWindowSize(window, ¤tW, ¤tH); SDL_GetWindowPosition(window, ¤tX, ¤tY); - SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display index (current: %d, expected: %d)", currentDisplay, expectedDisplay); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display index (current: %d, expected: %d)", currentDisplay, expectedDisplay); + } else { + SDLTest_Log("Skipping display ID validation: Wayland driver does not support window positioning"); + } SDLTest_AssertCheck(currentW == w, "Validate width (current: %d, expected: %d)", currentW, w); SDLTest_AssertCheck(currentH == h, "Validate height (current: %d, expected: %d)", currentH, h); - SDLTest_AssertCheck(currentX == expectedX, "Validate x (current: %d, expected: %d)", currentX, expectedX); - SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentX == expectedX, "Validate x (current: %d, expected: %d)", currentX, expectedX); + SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); + } else { + SDLTest_Log("Skipping window position validation: Wayland driver does not support window positioning"); + } /* Center on display yVariation, and check window properties */ @@ -1737,11 +1816,19 @@ static int video_setWindowCenteredOnDisplay(void *arg) SDL_GetWindowSize(window, ¤tW, ¤tH); SDL_GetWindowPosition(window, ¤tX, ¤tY); - SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display ID (current: %d, expected: %d)", currentDisplay, expectedDisplay); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentDisplay == expectedDisplay, "Validate display ID (current: %d, expected: %d)", currentDisplay, expectedDisplay); + } else { + SDLTest_Log("Skipping display ID validation: Wayland driver does not support window positioning"); + } SDLTest_AssertCheck(currentW == w, "Validate width (current: %d, expected: %d)", currentW, w); SDLTest_AssertCheck(currentH == h, "Validate height (current: %d, expected: %d)", currentH, h); - SDLTest_AssertCheck(currentX == expectedX, "Validate x (current: %d, expected: %d)", currentX, expectedX); - SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); + if (!video_driver_is_wayland) { + SDLTest_AssertCheck(currentX == expectedX, "Validate x (current: %d, expected: %d)", currentX, expectedX); + SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); + } else { + SDLTest_Log("Skipping window position validation: Wayland driver does not support window positioning"); + } /* Clean up */ destroyVideoSuiteTestWindow(window); diff --git a/test/testcontroller.c b/test/testcontroller.c index d8d74d96..fa9e7e7d 100644 --- a/test/testcontroller.c +++ b/test/testcontroller.c @@ -131,10 +131,10 @@ static int s_arrBindingOrder[] = { SDL_GAMEPAD_ELEMENT_INVALID, /* Paddle sequence */ - SDL_GAMEPAD_BUTTON_PADDLE1, - SDL_GAMEPAD_BUTTON_PADDLE2, - SDL_GAMEPAD_BUTTON_PADDLE3, - SDL_GAMEPAD_BUTTON_PADDLE4, + SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, + SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, + SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, + SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, SDL_GAMEPAD_ELEMENT_INVALID, }; @@ -749,13 +749,13 @@ static const char *GetBindingInstruction(void) return "Press the D-Pad right"; case SDL_GAMEPAD_BUTTON_MISC1: return "Press the bottom center button (Share/Capture)"; - case SDL_GAMEPAD_BUTTON_PADDLE1: + case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1: return "Press the upper paddle under your right hand"; - case SDL_GAMEPAD_BUTTON_PADDLE2: + case SDL_GAMEPAD_BUTTON_LEFT_PADDLE1: return "Press the upper paddle under your left hand"; - case SDL_GAMEPAD_BUTTON_PADDLE3: + case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2: return "Press the lower paddle under your right hand"; - case SDL_GAMEPAD_BUTTON_PADDLE4: + case SDL_GAMEPAD_BUTTON_LEFT_PADDLE2: return "Press the lower paddle under your left hand"; case SDL_GAMEPAD_BUTTON_TOUCHPAD: return "Press down on the touchpad"; @@ -1024,7 +1024,7 @@ static SDL_bool ShowingFront(void) int i; /* Show the back of the gamepad if the paddles are being held or bound */ - for (i = SDL_GAMEPAD_BUTTON_PADDLE1; i <= SDL_GAMEPAD_BUTTON_PADDLE4; ++i) { + for (i = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1; i <= SDL_GAMEPAD_BUTTON_LEFT_PADDLE2; ++i) { if (SDL_GetGamepadButton(controller->gamepad, (SDL_GamepadButton)i) == SDL_PRESSED || binding_element == i) { showing_front = SDL_FALSE; diff --git a/test/testdraw.c b/test/testdraw.c index c5c1711d..d0c102c2 100644 --- a/test/testdraw.c +++ b/test/testdraw.c @@ -19,8 +19,9 @@ #include #endif -#include +#include #include +#include #define NUM_OBJECTS 100 diff --git a/test/testfile.c b/test/testfile.c index 99ef3a01..8aa48007 100644 --- a/test/testfile.c +++ b/test/testfile.c @@ -55,7 +55,7 @@ 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_DestroyRW(rwops); */ + SDL_RWclose(rwops); /* This calls SDL_DestroyRW(rwops); */ } cleanup(); SDLTest_CommonDestroyState(state); @@ -126,25 +126,25 @@ int main(int argc, char *argv[]) if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); unlink(FBASENAME2); rwops = SDL_RWFromFile(FBASENAME2, "wb+"); if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); unlink(FBASENAME2); rwops = SDL_RWFromFile(FBASENAME2, "ab"); if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); unlink(FBASENAME2); rwops = SDL_RWFromFile(FBASENAME2, "ab+"); if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); unlink(FBASENAME2); SDL_Log("test2 OK\n"); @@ -155,110 +155,110 @@ int main(int argc, char *argv[]) if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->write(rwops, "1234567", 7)) { + if (7 != SDL_RWwrite(rwops, "1234567", 7)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (-1 != rwops->read(rwops, test_buf, 1)) { + if (0 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); /* we are in write only mode */ } - rwops->close(rwops); + SDL_RWclose(rwops); rwops = SDL_RWFromFile(FBASENAME1, "rb"); /* read mode, file must exist */ if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (20 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) { + if (20 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->read(rwops, test_buf, 7)) { + if (7 != SDL_RWread(rwops, test_buf, 7)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "1234567", 7) != 0) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1)) { + if (0 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1000)) { + if (0 != SDL_RWread(rwops, test_buf, 1000)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) { + if (0 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) { RWOP_ERR_QUIT(rwops); } - if (27 != rwops->read(rwops, test_buf, 30)) { + if (27 != SDL_RWread(rwops, test_buf, 30)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "12345678901234567890", 20) != 0) { RWOP_ERR_QUIT(rwops); } - if (-1 != rwops->write(rwops, test_buf, 1)) { + if (0 != SDL_RWwrite(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); /* readonly mode */ } - rwops->close(rwops); + SDL_RWclose(rwops); /* test 3: same with w+ mode */ rwops = SDL_RWFromFile(FBASENAME1, "wb+"); /* write + read + truncation */ if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->write(rwops, "1234567", 7)) { + if (7 != SDL_RWwrite(rwops, "1234567", 7)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (1 != rwops->read(rwops, test_buf, 1)) { + if (1 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); /* we are in read/write mode */ } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (20 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) { + if (20 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->read(rwops, test_buf, 7)) { + if (7 != SDL_RWread(rwops, test_buf, 7)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "1234567", 7) != 0) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1)) { + if (0 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1000)) { + if (0 != SDL_RWread(rwops, test_buf, 1000)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) { + if (0 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) { RWOP_ERR_QUIT(rwops); } - if (27 != rwops->read(rwops, test_buf, 30)) { + if (27 != SDL_RWread(rwops, test_buf, 30)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "12345678901234567890", 20) != 0) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); SDL_Log("test3 OK\n"); /* test 4: same in r+ mode */ @@ -266,50 +266,50 @@ int main(int argc, char *argv[]) if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->write(rwops, "1234567", 7)) { + if (7 != SDL_RWwrite(rwops, "1234567", 7)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (1 != rwops->read(rwops, test_buf, 1)) { + if (1 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); /* we are in read/write mode */ } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (20 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) { + if (20 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->read(rwops, test_buf, 7)) { + if (7 != SDL_RWread(rwops, test_buf, 7)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "1234567", 7) != 0) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1)) { + if (0 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1000)) { + if (0 != SDL_RWread(rwops, test_buf, 1000)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) { + if (0 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) { RWOP_ERR_QUIT(rwops); } - if (27 != rwops->read(rwops, test_buf, 30)) { + if (27 != SDL_RWread(rwops, test_buf, 30)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "12345678901234567890", 20) != 0) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); SDL_Log("test4 OK\n"); /* test5 : append mode */ @@ -317,56 +317,56 @@ int main(int argc, char *argv[]) if (rwops == NULL) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (10 != rwops->write(rwops, "1234567890", 10)) { + if (10 != SDL_RWwrite(rwops, "1234567890", 10)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->write(rwops, "1234567", 7)) { + if (7 != SDL_RWwrite(rwops, "1234567", 7)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (1 != rwops->read(rwops, test_buf, 1)) { + if (1 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (20 + 27 != rwops->seek(rwops, -7, SDL_RW_SEEK_END)) { + if (20 + 27 != SDL_RWseek(rwops, -7, SDL_RW_SEEK_END)) { RWOP_ERR_QUIT(rwops); } - if (7 != rwops->read(rwops, test_buf, 7)) { + if (7 != SDL_RWread(rwops, test_buf, 7)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "1234567", 7) != 0) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1)) { + if (0 != SDL_RWread(rwops, test_buf, 1)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->read(rwops, test_buf, 1000)) { + if (0 != SDL_RWread(rwops, test_buf, 1000)) { RWOP_ERR_QUIT(rwops); } - if (27 != rwops->seek(rwops, -27, SDL_RW_SEEK_CUR)) { + if (27 != SDL_RWseek(rwops, -27, SDL_RW_SEEK_CUR)) { RWOP_ERR_QUIT(rwops); } - if (0 != rwops->seek(rwops, 0L, SDL_RW_SEEK_SET)) { + if (0 != SDL_RWseek(rwops, 0L, SDL_RW_SEEK_SET)) { RWOP_ERR_QUIT(rwops); } - if (30 != rwops->read(rwops, test_buf, 30)) { + if (30 != SDL_RWread(rwops, test_buf, 30)) { RWOP_ERR_QUIT(rwops); } if (SDL_memcmp(test_buf, "123456789012345678901234567123", 30) != 0) { RWOP_ERR_QUIT(rwops); } - rwops->close(rwops); + SDL_RWclose(rwops); SDL_Log("test5 OK\n"); cleanup(); SDLTest_CommonDestroyState(state); diff --git a/test/testime.c b/test/testime.c index acd286eb..84d3aecb 100644 --- a/test/testime.c +++ b/test/testime.c @@ -108,7 +108,7 @@ static int unifont_init(const char *fontname) Uint8 hexBuffer[65]; Uint32 numGlyphs = 0; int lineNumber = 1; - Sint64 bytesRead; + 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 *); @@ -150,11 +150,6 @@ static int unifont_init(const char *fontname) Uint32 codepoint; bytesRead = SDL_RWread(hexFile, hexBuffer, 9); - if (bytesRead < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "error SDL_RWread\n"); - return -1; - } - if (numGlyphs > 0 && bytesRead == 0) { break; /* EOF */ } @@ -196,9 +191,7 @@ static int unifont_init(const char *fontname) return -1; } - - - if ((size_t)bytesRead < (33 - bytesOverread)) { + if (bytesRead < (33 - bytesOverread)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n"); return -1; } diff --git a/test/testmultiaudio.c b/test/testmultiaudio.c index d2ac1cde..b75da946 100644 --- a/test/testmultiaudio.c +++ b/test/testmultiaudio.c @@ -27,85 +27,57 @@ 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_AtomicInt done; -} callback_data; +/* these have to be in globals so the Emscripten port can see them in the mainloop. :/ */ +static SDL_AudioDeviceID device = 0; +static SDL_AudioStream *stream = NULL; -static callback_data cbd[64]; - -static void SDLCALL -play_through_once(void *arg, Uint8 *stream, int len) -{ - callback_data *cbdata = (callback_data *)arg; - Uint8 *waveptr = sound + cbdata->soundpos; - int waveleft = soundlen - cbdata->soundpos; - int cpy = len; - if (cpy > waveleft) { - cpy = waveleft; - } - - SDL_memcpy(stream, waveptr, cpy); - len -= cpy; - cbdata->soundpos += cpy; - if (len > 0) { - stream += cpy; - SDL_memset(stream, spec.silence, len); - SDL_AtomicSet(&cbdata->done, 1); - } -} #ifdef __EMSCRIPTEN__ static void loop(void) { - if (SDL_AtomicGet(&cbd[0].done)) { - emscripten_cancel_main_loop(); - SDL_PauseAudioDevice(cbd[0].dev); - SDL_CloseAudioDevice(cbd[0].dev); + if (SDL_GetAudioStreamAvailable(stream) == 0) { + SDL_Log("done."); + SDL_CloseAudioDevice(device); + SDL_DestroyAudioStream(stream); SDL_free(sound); SDL_Quit(); + emscripten_cancel_main_loop(); } } #endif static void -test_multi_audio(int devcount) +test_multi_audio(SDL_AudioDeviceID *devices, int devcount) { int keep_going = 1; + SDL_AudioStream **streams = NULL; int i; -#ifdef __ANDROID__ +#ifdef __ANDROID__ /* !!! FIXME: maybe always create a window, in the SDLTest layer, so these #ifdefs don't have to be here? */ SDL_Event event; /* Create a Window to get fully initialized event processing for testing pause on Android. */ SDL_CreateWindow("testmultiaudio", 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); + char *devname = SDL_GetAudioDeviceName(devices[i]); - 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()); + SDL_Log("Playing on device #%d of %d: id=%u, name='%s'...", i, devcount, (unsigned int) devices[i], devname); + + device = SDL_OpenAudioDevice(devices[i], &spec); + if (device == 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s", SDL_GetError()); + } else if ((stream = SDL_CreateAndBindAudioStream(device, &spec)) == NULL) { /* we can reuse these, but we'll just make one each time for now. */ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed: %s", SDL_GetError()); + SDL_CloseAudioDevice(device); } else { - SDL_PlayAudioDevice(cbd[0].dev); + SDL_PutAudioStreamData(stream, sound, soundlen); + SDL_FlushAudioStream(stream); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else - while (!SDL_AtomicGet(&cbd[0].done)) { + while (SDL_GetAudioStreamAvailable(stream) > 0) { #ifdef __ANDROID__ /* Empty queue, some application events would prevent pause. */ while (SDL_PollEvent(&event)) { @@ -113,61 +85,77 @@ test_multi_audio(int devcount) #endif SDL_Delay(100); } - SDL_PauseAudioDevice(cbd[0].dev); #endif - SDL_Log("done.\n"); - SDL_CloseAudioDevice(cbd[0].dev); + SDL_Log("done."); + SDL_CloseAudioDevice(device); + SDL_DestroyAudioStream(stream); } + SDL_free(devname); + stream = NULL; } - 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_PlayAudioDevice(cbd[i].dev); - } - } - - while (keep_going) { - keep_going = 0; + /* note that Emscripten currently doesn't run this part (but maybe only has a single audio device anyhow?) */ + SDL_Log("Playing on all devices...\n"); + streams = (SDL_AudioStream **) SDL_calloc(devcount, sizeof (SDL_AudioStream *)); + if (!streams) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); + } else { for (i = 0; i < devcount; i++) { - if ((cbd[i].dev) && (!SDL_AtomicGet(&cbd[i].done))) { - keep_going = 1; + char *devname = SDL_GetAudioDeviceName(devices[i]); + device = SDL_OpenAudioDevice(devices[i], &spec); + if (device == 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d of %d (id=%u, name='%s') failed: %s\n", i, devcount, (unsigned int) devices[i], devname, SDL_GetError()); + } + SDL_free(devname); + devices[i] = device; /* just replace the physical device ID with the newly-opened logical device ID. */ + if (device) { + SDL_PauseAudioDevice(device); /* hold while we set up all the streams. */ + streams[i] = SDL_CreateAndBindAudioStream(device, &spec); + if (streams[i] == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed for device %d of %d: %s", i, devcount, SDL_GetError()); + } else { + SDL_PutAudioStreamData(streams[i], sound, soundlen); + SDL_FlushAudioStream(streams[i]); + } } } -#ifdef __ANDROID__ - /* Empty queue, some application events would prevent pause. */ - while (SDL_PollEvent(&event)) { + + /* try to start all the devices about the same time. SDL does not guarantee sync across physical devices. */ + for (i = 0; i < devcount; i++) { + if (devices[i]) { + SDL_ResumeAudioDevice(devices[i]); + } } + + while (keep_going) { + keep_going = 0; + for (i = 0; i < devcount; i++) { + if (streams[i] && (SDL_GetAudioStreamAvailable(streams[i]) > 0)) { + 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); - SDL_CloseAudioDevice(cbd[i].dev); + SDL_Delay(100); } + + for (i = 0; i < devcount; i++) { + SDL_CloseAudioDevice(devices[i]); + SDL_DestroyAudioStream(streams[i]); + } + + SDL_free(streams); } SDL_Log("All done!\n"); -#endif } int main(int argc, char **argv) { + SDL_AudioDeviceID *devices = NULL; int devcount = 0; int i; char *filename = NULL; @@ -212,20 +200,21 @@ int main(int argc, char **argv) filename = GetResourceFilename(filename, "sample.wav"); - devcount = SDL_GetNumAudioDevices(0); - if (devcount < 1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n"); + devices = SDL_GetAudioOutputDevices(&devcount); + if (devices == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!"); } else { /* Load the wave file into memory */ - if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) { + if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); } else { - test_multi_audio(devcount); + test_multi_audio(devices, devcount); SDL_free(sound); } } + SDL_free(devices); SDL_free(filename); SDL_Quit(); @@ -233,3 +222,4 @@ int main(int argc, char **argv) return 0; } + diff --git a/test/testnativecocoa.m b/test/testnativecocoa.m index 030607d6..e8950723 100644 --- a/test/testnativecocoa.m +++ b/test/testnativecocoa.m @@ -3,8 +3,15 @@ #ifdef TEST_NATIVE_COCOA +#include #include +#ifndef MAC_OS_X_VERSION_10_12 +static const unsigned int NSWindowStyleMaskTitled = NSTitledWindowMask; +static const unsigned int NSWindowStyleMaskMiniaturizable = NSMiniaturizableWindowMask; +static const unsigned int NSWindowStyleMaskClosable = NSClosableWindowMask; +#endif + static void *CreateWindowCocoa(int w, int h); static void DestroyWindowCocoa(void *window); @@ -29,7 +36,7 @@ static void *CreateWindowCocoa(int w, int h) rect.size.height = h; rect.origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - rect.origin.y - rect.size.height; - style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask); + style = (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable); nswindow = [[NSWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE]; [nswindow makeKeyAndOrderFront:nil]; diff --git a/test/testresample.c b/test/testresample.c index 75378110..83661d34 100644 --- a/test/testresample.c +++ b/test/testresample.c @@ -22,12 +22,11 @@ static void log_usage(char *progname, SDLTest_CommonState *state) { int main(int argc, char **argv) { SDL_AudioSpec spec; + SDL_AudioSpec cvtspec; SDL_AudioStream *stream = NULL; Uint8 *dst_buf = NULL; Uint32 len = 0; Uint8 *data = NULL; - int cvtfreq = 0; - int cvtchans = 0; int bitsize = 0; int blockalign = 0; int avgbytes = 0; @@ -49,6 +48,8 @@ int main(int argc, char **argv) /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + SDL_zero(cvtspec); + /* Parse commandline */ for (i = 1; i < argc;) { int consumed; @@ -65,14 +66,14 @@ int main(int argc, char **argv) consumed = 1; } else if (argpos == 2) { char *endp; - cvtfreq = (int)SDL_strtoul(argv[i], &endp, 0); + cvtspec.freq = (int)SDL_strtoul(argv[i], &endp, 0); if (endp != argv[i] && *endp == '\0') { argpos++; consumed = 1; } } else if (argpos == 3) { char *endp; - cvtchans = (int)SDL_strtoul(argv[i], &endp, 0); + cvtspec.channels = (int)SDL_strtoul(argv[i], &endp, 0); if (endp != argv[i] && *endp == '\0') { argpos++; consumed = 1; @@ -100,14 +101,14 @@ int main(int argc, char **argv) goto end; } - if (SDL_LoadWAV(file_in, &spec, &data, &len) == NULL) { + if (SDL_LoadWAV(file_in, &spec, &data, &len) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "failed to load %s: %s\n", file_in, SDL_GetError()); ret = 3; goto end; } - if (SDL_ConvertAudioSamples(spec.format, spec.channels, spec.freq, data, len, - spec.format, cvtchans, cvtfreq, &dst_buf, &dst_len) < 0) { + cvtspec.format = spec.format; + if (SDL_ConvertAudioSamples(&spec, data, len, &cvtspec, &dst_buf, &dst_len) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "failed to convert samples: %s\n", SDL_GetError()); ret = 4; goto end; @@ -122,22 +123,22 @@ int main(int argc, char **argv) } bitsize = SDL_AUDIO_BITSIZE(spec.format); - blockalign = (bitsize / 8) * cvtchans; - avgbytes = cvtfreq * blockalign; + blockalign = (bitsize / 8) * cvtspec.channels; + avgbytes = cvtspec.freq * blockalign; - SDL_WriteLE32(io, 0x46464952); /* RIFF */ - SDL_WriteLE32(io, dst_len + 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, dst_len); /* size */ + SDL_WriteU32LE(io, 0x46464952); /* RIFF */ + SDL_WriteU32LE(io, dst_len + 36); + SDL_WriteU32LE(io, 0x45564157); /* WAVE */ + SDL_WriteU32LE(io, 0x20746D66); /* fmt */ + SDL_WriteU32LE(io, 16); /* chunk size */ + SDL_WriteU16LE(io, SDL_AUDIO_ISFLOAT(spec.format) ? 3 : 1); /* uncompressed */ + SDL_WriteU16LE(io, cvtspec.channels); /* channels */ + SDL_WriteU32LE(io, cvtspec.freq); /* sample rate */ + SDL_WriteU32LE(io, avgbytes); /* average bytes per second */ + SDL_WriteU16LE(io, blockalign); /* block align */ + SDL_WriteU16LE(io, bitsize); /* significant bits per sample */ + SDL_WriteU32LE(io, 0x61746164); /* data */ + SDL_WriteU32LE(io, dst_len); /* size */ SDL_RWwrite(io, dst_buf, dst_len); if (SDL_RWclose(io) == -1) { diff --git a/test/testsurround.c b/test/testsurround.c index f4060b28..c759d073 100644 --- a/test/testsurround.c +++ b/test/testsurround.c @@ -96,20 +96,23 @@ static SDL_bool is_lfe_channel(int channel_index, int channel_count) return (channel_count == 3 && channel_index == 2) || (channel_count >= 6 && channel_index == 3); } -static void SDLCALL fill_buffer(void *unused, Uint8 *stream, int len) +static void SDLCALL fill_buffer(SDL_AudioStream *stream, int len, void *unused) { - Sint16 *buffer = (Sint16 *)stream; - int samples = len / sizeof(Sint16); + const int samples = len / sizeof(Sint16); + Sint16 *buffer = NULL; static int total_samples = 0; int i; - SDL_memset(stream, 0, len); - /* This can happen for a short time when switching devices */ if (active_channel == total_channels) { return; } + buffer = (Sint16 *) SDL_calloc(samples, sizeof(Sint16)); + if (!buffer) { + return; /* oh well. */ + } + /* Play a sine wave on the active channel only */ for (i = active_channel; i < samples; i += total_channels) { float time = (float)total_samples++ / SAMPLE_RATE_HZ; @@ -134,12 +137,18 @@ static void SDLCALL fill_buffer(void *unused, Uint8 *stream, int len) break; } } + + SDL_PutAudioStreamData(stream, buffer, samples * sizeof (Sint16)); + + SDL_free(buffer); } int main(int argc, char *argv[]) { - int i; + SDL_AudioDeviceID *devices = NULL; SDLTest_CommonState *state; + int devcount = 0; + int i; /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, 0); @@ -168,38 +177,58 @@ int main(int argc, char *argv[]) SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); - for (i = 0; i < SDL_GetNumAudioDevices(0); i++) { - const char *devname = SDL_GetAudioDeviceName(i, 0); + devices = SDL_GetAudioOutputDevices(&devcount); + if (!devices) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetAudioOutputDevices() failed: %s\n", SDL_GetError()); + devcount = 0; + } + + SDL_Log("Available audio devices:"); + for (i = 0; i < devcount; i++) { + SDL_Log("%s", SDL_GetAudioDeviceName(devices[i])); + } + + for (i = 0; i < devcount; i++) { + SDL_AudioStream *stream = NULL; + char *devname = SDL_GetAudioDeviceName(devices[i]); int j; SDL_AudioSpec spec; SDL_AudioDeviceID dev; - if (SDL_GetAudioDeviceSpec(i, 0, &spec) != 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetAudioSpec() failed: %s\n", SDL_GetError()); + SDL_Log("Testing audio device: %s\n", devname); + SDL_free(devname); + + if (SDL_GetAudioDeviceFormat(devices[i], &spec) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetAudioDeviceFormat() failed: %s\n", SDL_GetError()); continue; } + SDL_Log(" (%d channels)\n", spec.channels); + spec.freq = SAMPLE_RATE_HZ; spec.format = SDL_AUDIO_S16SYS; - spec.samples = 4096; - spec.callback = fill_buffer; - dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0); + dev = SDL_OpenAudioDevice(devices[i], &spec); if (dev == 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_OpenAudioDevice() failed: %s\n", SDL_GetError()); continue; } - SDL_Log("Testing audio device: %s (%d channels)\n", devname, spec.channels); + stream = SDL_CreateAndBindAudioStream(dev, &spec); + if (stream == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateAndBindAudioStream() failed: %s\n", SDL_GetError()); + SDL_CloseAudioDevice(dev); + continue; + } /* These are used by the fill_buffer callback */ total_channels = spec.channels; active_channel = 0; - SDL_PlayAudioDevice(dev); + SDL_SetAudioStreamGetCallback(stream, fill_buffer, NULL); for (j = 0; j < total_channels; j++) { - int sine_freq = is_lfe_channel(j, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ; + const int sine_freq = is_lfe_channel(j, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ; SDL_Log("Playing %d Hz test tone on channel: %s\n", sine_freq, get_channel_name(j, total_channels)); @@ -212,8 +241,11 @@ int main(int argc, char *argv[]) } SDL_CloseAudioDevice(dev); + SDL_DestroyAudioStream(stream); } + SDL_free(devices); + SDL_Quit(); return 0; } diff --git a/test/trashcan.bmp b/test/trashcan.bmp new file mode 100644 index 0000000000000000000000000000000000000000..64a60b22ebcc0da79d0922fe468fe920cfd15cf6 GIT binary patch literal 65674 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 F{x=oGqjCTM literal 0 HcmV?d00001 diff --git a/test/uwp/Package.appxmanifest.in b/test/uwp/Package.appxmanifest.in new file mode 100644 index 00000000..8a5d4371 --- /dev/null +++ b/test/uwp/Package.appxmanifest.in @@ -0,0 +1,52 @@ + + + + + + + + + $ + libsdl.org + logo-50x50.png + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/uwp/logo-50x50.png b/test/uwp/logo-50x50.png new file mode 100644 index 0000000000000000000000000000000000000000..e7903b79f11b0d662db06725c36893dca3646544 GIT binary patch literal 2421 zcmV-*35xcKP)Ve=Y{T7k?QSBPYM5MeUg}|M_JHhJ*fy=R017JDO2FwX(AX13b0-eAp zRF47cu^gWVfNC%BG*A}KKx7b6{Sf#72n6p<;AP-vAu>KxJHwec^F%~Eh}<#2%tjy! zkyrp!w*ys(+%PP&LuD<=UhGJ5bX=_Hg@}=)s$F8RS55Q7#`4v*{pFK$7EQ*`DWPL2 z-AAK}eS6$FZ9dnO&emgbfv)+$B2?S@k$f7cNzE;I2eqfW&4BSz)qB^^Z1dd|46oB8 zk}|vKT2XmIA$fplRj2?SZ!BB2wvR||@n1w(7AkmO-8O1mF;vESahrbs#Lm`jw>4F@ zwYY8hbA7&!K0%Qm0G%m$MSnpl2Dtc0BPF{w{?w-a*9RjKHvOi~F3v}#RKtg#2;`!& zGMo*!>F0^B%4v-9P?|KJfCzwnhi7E=+X<<3*d6a{ZsEedl~vsa!0h5a8z00cBj|WU z5>RbHduLvsZ~VM-Zt8Qh+v8*M!OpNF?Q=y=fY- z9vH-P`^#1>4wV@-yWm_yY!iJON;?RH?DhlPRsVU*1GQUkLA3*5>a2y?Js8hj)$;Z9 zR-2O@(Idw;M!BB?ejd(F6y~MCxj-H8EbwW6nSn#gZzdw&+^Xnj{Y9ELt=R+Y0YF56 zOM%SP>G`hxu4n*0j!B}<8NFeu|H$o#ya?!axVqc0?S3?U>e!=(Jt42PnY5mx3l>bd za@H$5)>Vc+W5L0F%s;db!MqSyit0z<$PO6)ehoALeOW+MmZZ(OVcJQ8B6dV(0+X;p z#`~wbZ8Pm53FIf!=9OY?aEpNJflX0n;J&}7Oj-KcIb-;jcRUHbT{5S==@0$QS9{{9 zi1qRbDK`&BA}o>SikF(P%7x>|Fau^~a$fNhV=gL836k&vHvrXVOx&_roQC*JeyQuEAoBH*kpfS~UzywwxQe5qc$-m@Cqj5*WPW)o9F+RBo)jg+6 zBz!+&{c@K8-3_X*iOB1(<`iBhB2NNIha6E{cDTVa_2{8L1BcAiR^%%=EJZ{2*lECwVZG7_uByaKD`v?JnG z)fa%$)R~3l*p2N9aW9OXz+<~B79g?JeUZD0a|-9FNMCjP zRO$sA@2&eR36XeIkE|SZUX27d(}NBdF3j^9U7mvJvu=D3n>oeEEiM8rfN!>3g?nl? z{4;EdP06ZGNSk%jfYoh%<%&b!5V7`yUjR=6t4qD(me1%oczao#cS*pICF!|Eoy%&s z_O44v`=yG6=2q=CY|j9#KsNC1@d*K@cO2w%Pr{V7-i&`3wm=v+<>AJ%lCXs*fI8)X z;vZN$d$CiuJllIbv~~u+$D@O?%<6tC)3u{GG*CVnK>jZ-qj8dP| zGh@M_+G{q%C&vNyLyoB9I-LsZ4a|od%2$W>(5=AVR#t6@cAI|xm+tt$<7t^)%}%!o zm>@pT10cJAbqQ@fZ+!7ZX-^oxjsfk%Vi5DCLTFuQ<4QWYRVxpuHGGtKV#qDAT0JIl&;X)h|pk45Gno5x>!H+Qo08cAM%rL4B$Y z1Mz?Dx2b6}?bm5Q%M6j$fQ^8|?D^6(?O7^jJvK+8U9~G19-P=npJW7!kbA zR=82YJ{;ZDyu#dJJ>wKUqjQSq^&cDF*{{f4;5MvADjBFj^{+!Ko;eJC_G_KX<^!?7 zVPGYyUwzMhoiYX|B616G16E0LH>%ZV!l~22;Gt!;v6Hb@!8}t=oem=F|B-Kj$T-CQ n4se!8q~R=)NW)nok%s>Q9U2niUnbeS00000NkvXXu0mjfuSkNP literal 0 HcmV?d00001 diff --git a/test/uwp/splash-620x300.png b/test/uwp/splash-620x300.png new file mode 100644 index 0000000000000000000000000000000000000000..0dde7737d6eb2aaa68d0eb795583d9875cb30445 GIT binary patch literal 30918 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 literal 0 HcmV?d00001 diff --git a/test/uwp/square-44x44.png b/test/uwp/square-44x44.png new file mode 100644 index 0000000000000000000000000000000000000000..f0bdcd22488bbac7b2cb8a95c53fa439114eb01e GIT binary patch literal 2082 zcmV+-2;KLIP)h($8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H12d_y) zK~z|U?U;K|RQDCfKj+?MVOe11r3iv3s5Qj#k*Yv6qfULMlNwu11>@8t65Fx16BEbA zW}KL5o6e*U+l)11O~s<^nA+5-+GsLrO+{->9kE70OhH}?sQ3VdecaPOSaglMqM546 zjNh3%bAOL>&i8lj`Tg!WKT%b_NHFd6&mEQ;;Fo{` z<)|J7eh#caBs!Gn{qk@Y;0G3>+JHzpU16~v)q{xi2IA=Q_>EB2d;fq-;V%kBL49i! zqI;6PHz6T15|REvUb+bE0Ad2;0vrOK>QU9LvbB`q^PQ&CH`zk60fz|Hs#LfS4nCr~ z(h8oNnm_MJMX!a}z|OYFnJqQ;8Ru%!hFrN2V}t#u?g&~$4DfEHv)79ghtJ3~Ri*gk z-X|L4>`M!3YFh7@aO$H4^HBK}5P!22wIHuG94J|Lop50r-~@2_JQOvSbHLSyvk_5T zFzu}`)s+80YDaRcXek%V~u`aktJyZzl!KRa7|Q{y4Jj{JW^$ zu&KKdG9)B;HzVKgn_sXiE$``30goDp3CrL*pfV8AFAFvB^-Lwi6j9(1TMH?HL6om^5=ckKsNx1yW;!F zx7{ay8rW20ff1>mE7D+(CihY^k6mgU3hY6(1Ce)tSG*$6^zmFtZLvF8n>v)bDCh35 zN$)LiqlZNz5qTXb0lox`0iFYJmzHc7)mH)j9h<~}t8JOUi@V(R&Z z@j;ct0ig8llp(FJ4EVCKIxUB~NN1;oxr@<Y#tmJOM26irCln9jaw9@jqExdEg+h z9+7NRt5l2}P`qNWDP>@JVRO|HpaNC>QSMV7AmX?)o@CF}tiXa#_8T+b<+phwMP*92 zQH6Ex0~>ETV{e}@tN?}s>&s#jFSz`k?K=`OcBJO@uO4%`rD93_iS5tk&OMJ|AwI6|f&J5%!ueK!qQ ze5c{irjNP_djiHwAAfjy``qSJ%sgAe*5u60!?DSktNM?m(+IMuY;~u5N;pImP>4ve znLC%F#&RCJ=w@3|M)dFd49fVFNk6dOYByhSAKTb|3nz{W)oGdPg6kfB6PO6to9wl< z$D9dEm)Djp{cBQ&(<6qf(%}N=1U)Pm8yXG`+MowlT0ncCI(WULe4phLY5#G?h}PrI zcn^XPr3JK6g}pY7*j8IwT>ohzHnDsC_^NNQ00Km>b~)>M#=lr$QBZr9!u)=DvmFUz z3**964mk=X3i}lbv!_pw>>gvn1RIYOMRd1=$3i{X)2Bx!PnaFkQ^j#T9~K!xR{{9- zz;R>(OMo{+o|hsHU=Of+M?!k(b3?`t6V#_F7sSABSeC~Uvlo_rsD?gnh;#}xSkNDp z6NXBPirN^3^8nSs{X^0%{M0SB6d_gLG6A( zKB`*+Z4)rB%@IjN^;~-XoCH4+qy36g471Y2Hv_B+71K0)a##&(ykBfhrll7wv9b)+ z4h*9c)L|H=+wZqh1uM#raoL18OE{&Lks^lI5;X@2R+G=-MAM7AZ_rn56K5 z!r-1{a&l(d{~yIF6DHW0J=+W&65$~78Zd>fq9eNIl&lx^H*R8jS2ZZl79uU6U_`(tXA7#rjWNs035dZ)H M07*qoM6N<$f@+G`bpQYW literal 0 HcmV?d00001