Squashed 'external/sdl/SDL/' changes from ec0042081..399bc709b
399bc709b build-scripts.pl: Added add-source-to-projects.pl ac6827187 Visual-WinRT: dos2unix the project files to match other Visual Studio targets. 34719cba9 Fixed crash in hid_init() if the HIDDeviceManager isn't available 2e92e94eb Make sure we update device->sample_frames in SDL_AudioDeviceFormatChangedAlreadyLocked() 9964e5c5b wayland: Don't retrieve the drag offer strings with every pointer motion event bac7eeaaa Added missing include a541e2ac1 audio: Change a few SDL_memcpy calls to SDL_copyp. 54125c140 audio: Only update bound audiostreams' formats when necessary. e0b0f9a36 testaudio: Fix mouseover testing. 2f3deec24 wayland: Don't process drag & drop events from surfaces not owned by SDL 42bdced05 events: Log file drop position events and print the pointer coordinates c10d93d3a wayland: Replace magic constant with define 500852153 emscripten: Restore compatibility with existing emsdk releases. 953b55dd6 Use EM_ASM_PTR when the return value is a pointer a4541a255 audio: SDL_GetAudioStreamQueued now returns bytes, not frames. 703aefbce Sync SDL3 wiki -> header 99421b64d linux: Add portal drag and drop 952c5059b Remove stray  eebd5d18a linux: Handle upower's UP_DEVICE_STATE_PENDING_CHARGE, PENDING_DISCHARGE f8fdb20d8 audio: Destroy all existing SDL_AudioStreams on shutdown. 62d445997 audio: Removed declarations of functions that don't exist anymore. b656720bc loopwave: Use SDL_GetAudioStreamQueued() for more accurate results. 34b931f7e audio: Added SDL_GetAudioStreamQueued 23206b9e3 audio: Added SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED c7e6d7a1f audio: Changed debug logging output. 87ec6acf2 audio: Added a FIXME ac88ffb7e audio: don't allocate buffer in SDL_SetAudioPostmixCallback for NULL callback. 2a950f6ae audio: Replace some SDL_memcpy calls with SDL_copyp. 0dc0434a3 audio: Fixed race condition in subsystem shutdown. 23f60203a audio: precalculate if we can use simple copies instead of the full mixer. 36b0f1141 audio: Optimize setting device formats during audio thread iteration. 4c3e84897 testspriteminimal: make standalone by embedding icon.bmp 2a01f9dcb tests: plug leaks when running with --trackmem f42bbeca2 SDL_test: track stack frames of allocations on Windows 12c0be028 SDL_test: clear text cache on exit event b4bfb1831 SDL_test: free state before logging allocations 248b1edd3 SDL_test: destroy windows in SDL_CommonQuit 98da2dd30 SDL_test: don't warn about expected allocations when running with --trackmem 6a381567b Support audio rate conversion up to 384KHz b2b548a1f Don't hang if IAudioRenderClient_GetBuffer() fails indefinitely a3a5e1728 Fixed build warning '=': conversion from 'Uint32' to 'Uint16', possible loss of data 6d3e21c27 Fixed android build warnings fca2f5318 Fixed warning: this function declaration is not a prototype a72dfa6a5 Fixed sensor timestamp units for third-party PS5 controllers f6756047a Fixed error: array subscript 2 is above array bounds of ‘const Uint8[2]’ 7059a55cc Fixed sensor timestamp calculation for third-party PS5 controllers c0443e5d1 Fixed crash in SDL_IMMDevice_FindByDevID() fde8499f6 Use around 20ms for the audio buffer size e5739d7d1 video: Remove SDL_GetFocusWindow() 39c2f9737 Fix NULL dereference in SDL_OpenAudio 9a23d0e3f Added new audio files to the Xcode project a62e62f97 Refactored SDL_audiocvt.c 31229fd47 include: Added a note about SDL's iOS app delegate functions. 65aaf3a9a x11: Always update clipboard owner f622f21e6 Fixed build 5774c9638 Prefer hidraw over libusb when libusb whitelisting is not enabled 9301f7ace hidapi/libusb: only enumerate each interface once 859dc14ad Replaced SDL_GetGamepadBindForAxis() and SDL_GetGamepadBindForButton() with SDL_GetGamepadBindings() 9e50048ab Revert "Removed SDL_GamepadBinding from the API" 9f17d1a9d Don't reference the same function in "see also" 86505ea63 fix SDL_AudioStreamCallback documentation d885d5c31 Sync SDL3 wiki -> header 2f43f7bc5 audio: Allow querying of device buffer size. cf9572113 audio: Added a hint to let apps force device buffer size. 47d8c77c6 audio: Choose better default sample frame counts. 8b26e95f9 audio: Change SDL_AudioStreamCallback 9da34e8fb docs: Updated README-emscripten.md. fd1c54a00 detect fanatec steering wheels cb4414608 docs: Whoops, this got added by the wiki bridge by accident! cd633b9a8 Renamed SDL_IsAudioDevicePaused() to SDL_AudioDevicePaused() c6cad07fa Sync SDL3 wiki -> header a6e52f9e4 Sync SDL3 wiki -> header 2de2e9d03 Fix flickering of window when using desktop-fullscreen and borderless window on multiple monitors on Linux. Closes #8186. 723835d16 Windows: fix for client rect resizing larger each time we came from exclusive fullscreen -> windowed on a monitor with HiDPI set. The problem was we were using the monitor DPI rather than the window DPI so AdjustWindowRectExForDpi was giving us an incorrect size which would be too large for the client rect. Closes #8237. ce27363df wikiheaders: Sort undocumented functions. e22282b09 Added README about transparent windows in Win32 1d1c6e630 Turn off COREAUDIO debug logging by default 52efefca0 wayland: Fix drag offer leak 3a992af44 audio: Added a postmix callback to logical devices. 7207bdce5 render: Enable clipping for zero-sized rectangles 22d81fb3e cmake: use MSVC_RUNTIME_LIBRARY to force MT a2e17852d cmake: make sure SDL_GetPrefPath is run before testfilesystem 2fb266e0a ci: run tests in parallel ad1313e75 testaudio: Patched to compile. 5747ddc01 testaudio: Clean up some messy memory management. fafbea1ce audio: Move internal float32 mixing to a simplified function 116b0ec97 include: minor tweak to audio API documentation fb1377035 include: Replaced old Bugzilla URL. 38c8fc05c audio: Remove ChooseMixStrategy. b00cbd76a wikiheaders.pl: create Unsupported.md file with list of functions undocumented in either the headers or the wiki 37e1fc3b5 wayland: Ensure that the toplevel window is recreated when switching decoration modes f2ca9a615 Added SDL_AUDIO_FRAMESIZE 53122593f Added SDL_AUDIO_BYTESIZE 544351c98 Sync SDL3 wiki -> header 2e7d2b94e Clarify that SDL_BlitSurface() ignores the width and height in dstrect a2c1984d3 Detect Simagic wheel bases as wheels (#8198) 1d8dfbb22 avoid type redefinition errors after PR/8181 266b91d2f Detect Logitech G923 Playstation as wheel G923 have two different versions - Xbox version is already present in the wheel list, but not the PS version. cde67ea49 Detect Logitech PRO Racing Wheel for Xbox (PC mode) as wheel Logitech PRO Racing Wheel have two different versions - for Playstation and Xbox. Vendor + Product ID for Playstation version already present in SDL sources, but not an Xbox version 3a932141e Restore audio format binary compatibility with SDL 2.0 e85206ffd wikiheaders.pl: add --rev= option to pass revision string 233789b0d Audio types have the same naming convention as other SDL endian types, e.g. [S|U][BITS][LE|BE] 36b5f3e35 Sync SDL3 wiki -> header 0e552761b Renamed AudioStreamSpeed to AudioStreamFrequencyRatio 47bcb078f Fixed some incorrect SDL_AUDIO_F32 uses 2833f2e7b Fixed OOB access in audio_convertAccuracy test 8387fae69 Sync SDL3 wiki -> header 832181345 docs: Add note about Wayland application icons 825d34475 Make sure that the same timestamp is used for all PS5 events from the same packet 9c1430324 Removed SDL_dataqueue 28b28bd8f Added audio_formatChange test a59152688 Try and avoid overflow when handling very large audio streams 5394a805f Improved testaudiostreamdynamicresample e55844274 Added SDL_(Get|Set)AudioStreamSpeed 43c3c5736 Track the formats of data in an SDL_AudioStream 337fed3df Tweaked ResampleFrame_SSE Use _mm_unpack(lo|hi)_ps instead of _mm_shuffle_ps fd7cd91dc audio: Mix multiple streams in float32 to prevent clipping. 9097573e3 audio: Choose a mixing strategy on each iteration. bbe2e012a Don't provide the SDL3 header path c17a35f09 Fixed typo 4f72255eb Fixed README.md link e0ab59754 Simplified SDL_main.h migration notes d44bde61e Added SDL migration information to the top level README.md 6ff31e10c metal: Add hint to select low power device instead of the default one (#8182) 8a8aed477 Make sure that we process touch events that position the mouse f84c87f20 Sync SDL3 wiki -> header a7eea9997 macOS: Don't raise the parent top-level window when raising a child window, only raise the child window to the top of the parent a5e721479 Add SDL_WINDOW_NOT_FOCUSABLE flag to set that the window should not be able to gain key focus b385dc3b6 n3dsaudio: Patched to compile. 4e0c7c91f audio: PlayDevice() should return an error code. a94d724f1 wayland: add SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL da5d93d3d wayland: don't define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_* macro's f002f7d12 ci: build emscripten with Debug buid type 3699b12ed audio: Fixed some "is_*" variables to be cleaner and/or more specific. 2471d8cc2 audio: Fixed logic error in SDL_OpenAudioDeviceStream. 1b03a2430 testsurround: fix order of arguments of callback 82db2b58f Renamed audio stream callback and moved the userdata parameter first 5bdad5210 Sync SDL3 wiki -> header 58c859f64 audio: Rename SDL_GetAudioStreamBinding to SDL_GetAudioStreamDevice. efd2023a7 audio: Fixed documentation. 1e775e0ee audio: Replace SDL_CreateAndBindAudioStream with SDL_OpenAudioDeviceStream. bd088c2f9 Revert "Clarify whether an audio function expects a physical or logical device ID" 82e481b52 Added --randmem test parameter ea68bb802 Add some additional checks to audio_convertAudio f8286df16 Fixed ResampleFrame_SSE doing unnecessary work b1d63be53 Fixed audio_resampleLoss test c191d6c30 Better Win32 transparent window support 923d612ca hidapi: sync macOS code with mainstream. 363f4fa9c avoid type redefinition errors after commit ee806597b9. 615824a80 Updated documentation now that SDL_GetAudioDevices() has been split into separate functions for output and capture devices 506a133d8 Clarify whether an audio function expects a physical or logical device ID 3b1d1e4e3 hidapi: sync the hidraw changes with mainstream f617918e0 cmake: check linkage to libusb too, instead of libusb.h presence only. 041dbd6b5 Fixed GetResamplerAvailableOutputFrames Non-euclidean division is a pain b49d0a607 x11: Avoid including full Vulkan headers. 4d2f9f3a3 yuv_rgb: Comment out unused code. 3c3486e2a wayland: Don't include full Vulkan headers when not necessary. f066bbe98 x11: Don't include system headers twice. d86d02bbb updated dynapi after SDL_GDKGetDefaultUser addition 4355f9cec Fixed warning C4389: '!=': signed/unsigned mismatch 5755de07a Fixed build warnings 0f80d47bb Fixed thread-safety warning ee806597b Removed SDL_vulkan_internal.h from SDL_sysvideo.h 34860b932 Fixed testautomation --filter pixels_allocFreeFormat 6f8a6a31c gdk: GetBasePath should be a UTF8 version of Win32 GetBasePath e30e5c77e Sync SDL3 wiki -> header c0cd8c814 gdk: Add SDL_GDKGetDefaultUser, SDL_GetPrefPath implementation 106abce69 Refactored GetAudioStreamDataInternal buffer handling The final conversion step should now always go straight into the output buffer. e44f54ec5 Avoid using hex-floats 5b696996c Added ResampleFrame_SSE 958b3cfae Tweaked and enabled audio_convertAudio test 7dbb9b65b audio_convertAccuracy: Shuffle the data in case of a bad SIMD implementation f6a4080ff audio_resampleLoss: Add support for multiple channels 4f894e748 audio_resampleLoss: SDL_GetAudioStreamData now returns the correct length ab83f75bb Make sure GetAudioStreamDataInternal is called with a valid length 6a73f74b6 Rebuild full ResamplerFilter (left wing + right wing) at runtime 0c15ce006 Add a missing int cast b74ee86b1 Optimized ResampleAudio, with special cases for 1 and 2 channels This would also benefit from some SIMD, since it's just a bunch of multiply-adds fba6e1e3d Removed ResamplerFilterDifference It takes 1 extra multiply to calculate the correct interpolation, but I think the improvement in cache locality (and binary size) outweighs that. 9f7a22fa4 Removed 64-bit handling from AudioConvertByteswap 1f5327a9f Removed future_buffer, left_padding, and right_padding from SDL_AudioStream 71ad52d6d Lowered SDL_GetAudioStreamData to 32 KB No particular reason for this number, but 1 MB was a bit silly 69aec8c91 Fixed the report format for the Razer Wolverine V2 Pro 7c2669c9d Accept key events from any source 1e9d31448 Updated to Android minSdkVersion 19 and targetSdkVersion 34 8924d0d92 Added missing function prototype for SDL_WriteS64BE() 845f3c745 Fixed mismatch between stdlib calloc() and SDL free() fb7921173 emscriptenaudio: Fire the capture silence_callback at an interval. 5191b2054 emscriptenaudio: Don't bother undefining things about to be unreachable. fd75a4ca0 emscriptenaudio: Deal with blocked audio devices better. 981b8a337 emscriptenaudio: Remove unnecessary functions. c7588e426 Transparent window for Win32 + OpenGL (#8143) f9581178d cmake: fixed a typo. e6c878824 Fixed ResampleAudio interpolation factor calculation 498363863 Misc audio tweaks/cleanup 72d9d53de Invert the inner ResampleAudio loops to avoid doing unnecessary work 88123a510 The history buffer should always have the maximum possible padding frames 96e47f165 Clamp results of GetResampler(AvailableOutput|NeededInput)Frames d2b9c8b80 Fixed maths in testaudiostreamdynamicresample (and just show the actual scale) 14e38b17d Removed assertions from inner ResampleAudio loop 9d413dfdc The history buffer doesn't need to be so large 2788e848f Allow resampling less than 1 frame of input 383084e0a Pre-calculate resampling rate, and use it instead of .freq in most places 40a6a445c Update resample_offset inside ResampleAudio 47fea7f06 Used fixed-point arithmetic in ResampleAudio 7bb4e806e Clear resample_offset in SDL_ClearAudioStream, not SetAudioStreamFormat Not entirely sure if ClearAudioStream is the right place, but SetAudioStreamFormat was the wrong place b9541b9ea Improved ResampleAudio * filterindex2 was off-by-one * Generate ResamplerFilter using doubles * Transpose ResamplerFilter to improve access patterns cdaa19869 Track offset within the current sample when resampling d60ebb06d mouse: Ensure that the dummy default cursor is removed from the cursor list e58c2731f mouse: Free the default cursor when destroyed 789ce17e1 audio: Don't resample in chunks for now. cbab33482 audio: Don't call SDL_AudioStream callbacks for empty data sets. 3e1ae0c86 Clearified the libusb whitelist default logic f4520821e Removed some unnecessary integer casts 0989b7e86 Avoid using designated initializers c6c1e673c Optimized SDL_Convert_*_to_*_Scalar f97b920b3 Optimized SDL_Convert_*_to_*_SSE2 Some of the SDL_Convert_F32_to_*_SSE2 do not explicitly clamp the input, but instead rely on saturating casts. Inputs very far outside the valid [-1.0, 1.0] range may produce an incorrect result, but I believe that is an acceptable trade-off. 300d1ec3e Added audio_convertAccuracy test 32cecc2ea Fixed assertion in audio_convertAudio 33f11e21e Removed assertions in AudioConvert(To|From)Float c2f388fd8 cmake: add SDL_HIDAPI_LIBUSB_SHARED option + test on ci 371cc2d17 wayland: Remove unnecessary flag and state settings fe85e6e75 cocoa: Send a maximized event instead of restored if a deminiaturized window is zoomed ddddcb78c cocoa: Use the close method to hide a miniaturized window be8c42cfd Clarify that a window being 'hidden' means that it is unmapped/ordered out a44338cbc Fix typo in SDL_audiocvt.c f464eb2c5 SDL_hidapi.c: change 'use_libusb_whitelist_default' into a macro. 6607a3cfa Disable cache in python http server 181d5d285 hidapi: Enable libusb support by default. f0f15e365 hidapi: Use a whitelist for libusb when other backends are available c3f7a7dc4 Convert audio using SDL_AUDIO_F32SYS format instead of SDL_AUDIO_F32 796713b9d xxd.py: always write \n line endings 723bcd0a8 SDL_TriggerBreakppoint for riscv arch (both 32/64) version. git-subtree-dir: external/sdl/SDL git-subtree-split: 399bc709b7485bab57880f8261f826f29dc0d7b2
This commit is contained in:
@ -10,13 +10,13 @@ The rest of this README covers the Android gradle style build process.
|
||||
Requirements
|
||||
================================================================================
|
||||
|
||||
Android SDK (version 31 or later)
|
||||
Android SDK (version 34 or later)
|
||||
https://developer.android.com/sdk/index.html
|
||||
|
||||
Android NDK r15c or later
|
||||
https://developer.android.com/tools/sdk/ndk/index.html
|
||||
|
||||
Minimum API level supported by SDL: 16 (Android 4.1)
|
||||
Minimum API level supported by SDL: 19 (Android 4.4)
|
||||
|
||||
|
||||
How the port works
|
||||
@ -435,13 +435,13 @@ The Tegra Graphics Debugger is available from NVidia here:
|
||||
https://developer.nvidia.com/tegra-graphics-debugger
|
||||
|
||||
|
||||
Why is API level 16 the minimum required?
|
||||
Why is API level 19 the minimum required?
|
||||
================================================================================
|
||||
|
||||
The latest NDK toolchain doesn't support targeting earlier than API level 16.
|
||||
As of this writing, according to https://developer.android.com/about/dashboards/index.html
|
||||
about 99% of the Android devices accessing Google Play support API level 16 or
|
||||
higher (January 2018).
|
||||
The latest NDK toolchain doesn't support targeting earlier than API level 19.
|
||||
As of this writing, according to https://www.composables.com/tools/distribution-chart
|
||||
about 99.7% of the Android devices accessing Google Play support API level 19 or
|
||||
higher (August 2023).
|
||||
|
||||
|
||||
A note regarding the use of the "dirty rectangles" rendering technique
|
||||
|
@ -1,27 +1,187 @@
|
||||
# Emscripten
|
||||
|
||||
(This documentation is not very robust; we will update and expand this later.)
|
||||
## The state of things
|
||||
|
||||
## A quick note about audio
|
||||
(As of September 2023, but things move quickly and we don't update this
|
||||
document often.)
|
||||
|
||||
In modern times, all the browsers you probably care about (Chrome, Firefox,
|
||||
Edge, and Safari, on Windows, macOS, Linux, iOS and Android), support some
|
||||
reasonable base configurations:
|
||||
|
||||
- WebAssembly (don't bother with asm.js any more)
|
||||
- WebGL (which will look like OpenGL ES 2 or 3 to your app).
|
||||
- Threads (see caveats, though!)
|
||||
- Game controllers
|
||||
- Autoupdating (so you can assume they have a recent version of the browser)
|
||||
|
||||
All this to say we're at the point where you don't have to make a lot of
|
||||
concessions to get even a fairly complex SDL-based game up and running.
|
||||
|
||||
|
||||
## RTFM
|
||||
|
||||
This document is a quick rundown of some high-level details. The
|
||||
documentation at [emscripten.org](https://emscripten.org/) is vast
|
||||
and extremely detailed for a wide variety of topics, and you should at
|
||||
least skim through it at some point.
|
||||
|
||||
|
||||
## Porting your app to Emscripten
|
||||
|
||||
Many many things just need some simple adjustments and they'll compile
|
||||
like any other C/C++ code, as long as SDL was handling the platform-specific
|
||||
work for your program.
|
||||
|
||||
First, you probably need this in at least one of your source files:
|
||||
|
||||
```c
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
```
|
||||
|
||||
Second: assembly language code has to go. Replace it with C. You can even use
|
||||
[x86 SIMD intrinsic functions in Emscripten](https://emscripten.org/docs/porting/simd.html)!
|
||||
|
||||
Third: Middleware has to go. If you have a third-party library you link
|
||||
against, you either need an Emscripten port of it, or the source code to it
|
||||
to compile yourself, or you need to remove it.
|
||||
|
||||
Fourth: You still start in a function called main(), but you need to get out of
|
||||
it and into a function that gets called repeatedly, and returns quickly,
|
||||
called a mainloop.
|
||||
|
||||
Somewhere in your program, you probably have something that looks like a more
|
||||
complicated version of this:
|
||||
|
||||
```c
|
||||
void main(void)
|
||||
{
|
||||
initialize_the_game();
|
||||
while (game_is_still_running) {
|
||||
check_for_new_input();
|
||||
think_about_stuff();
|
||||
draw_the_next_frame();
|
||||
}
|
||||
deinitialize_the_game();
|
||||
}
|
||||
```
|
||||
|
||||
This will not work on Emscripten, because the main thread needs to be free
|
||||
to do stuff and can't sit in this loop forever. So Emscripten lets you set up
|
||||
a [mainloop](https://emscripten.org/docs/porting/emscripten-runtime-environment.html#browser-main-loop).
|
||||
|
||||
```c
|
||||
static void mainloop(void) /* this will run often, possibly at the monitor's refresh rate */
|
||||
{
|
||||
if (!game_is_still_running) {
|
||||
deinitialize_the_game();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_cancel_main_loop(); /* this should "kill" the app. */
|
||||
#else
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
check_for_new_input();
|
||||
think_about_stuff();
|
||||
draw_the_next_frame();
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
initialize_the_game();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(mainloop, 0, 1);
|
||||
#else
|
||||
while (1) { mainloop(); }
|
||||
#endif
|
||||
}
|
||||
```
|
||||
|
||||
Basically, `emscripten_set_main_loop(mainloop, 0, 1);` says "run
|
||||
`mainloop` over and over until I end the program." The function will
|
||||
run, and return, freeing the main thread for other tasks, and then
|
||||
run again when it's time. The `1` parameter does some magic to make
|
||||
your main() function end immediately; this is useful because you
|
||||
don't want any shutdown code that might be sitting below this code
|
||||
to actually run if main() were to continue on, since we're just
|
||||
getting started.
|
||||
|
||||
There's a lot of little details that are beyond the scope of this
|
||||
document, but that's the biggest intial set of hurdles to porting
|
||||
your app to the web.
|
||||
|
||||
|
||||
## Do you need threads?
|
||||
|
||||
If you plan to use threads, they work on all major browsers now. HOWEVER,
|
||||
they bring with them a lot of careful considerations. Rendering _must_
|
||||
be done on the main thread. This is a general guideline for many
|
||||
platforms, but a hard requirement on the web.
|
||||
|
||||
Many other things also must happen on the main thread; often times SDL
|
||||
and Emscripten make efforts to "proxy" work to the main thread that
|
||||
must be there, but you have to be careful (and read more detailed
|
||||
documentation than this for the finer points).
|
||||
|
||||
Even when using threads, your main thread needs to set an Emscripten
|
||||
mainloop that runs quickly and returns, or things will fail to work
|
||||
correctly.
|
||||
|
||||
You should definitely read [Emscripten's pthreads docs](https://emscripten.org/docs/porting/pthreads.html)
|
||||
for all the finer points. Mostly SDL's thread API will work as expected,
|
||||
but is built on pthreads, so it shares the same little incompatibilities
|
||||
that are documented there, such as where you can use a mutex, and when
|
||||
a thread will start running, etc.
|
||||
|
||||
|
||||
IMPORTANT: You have to decide to either build something that uses
|
||||
threads or something that doesn't; you can't have one build
|
||||
that works everywhere. This is an Emscripten (or maybe WebAssembly?
|
||||
Or just web browsers in general?) limitation. If you aren't using
|
||||
threads, it's easier to not enable them at all, at build time.
|
||||
|
||||
If you use threads, you _have to_ run from a web server that has
|
||||
[COOP/COEP headers set correctly](https://web.dev/why-coop-coep/)
|
||||
or your program will fail to start at all.
|
||||
|
||||
If building with threads, `__EMSCRIPTEN_PTHREADS__` will be defined
|
||||
for checking with the C preprocessor, so you can build something
|
||||
different depending on what sort of build you're compiling.
|
||||
|
||||
|
||||
## Audio
|
||||
|
||||
Audio works as expected at the API level, but not exactly like other
|
||||
platforms.
|
||||
|
||||
You'll only see a single default audio device. Audio capture also works;
|
||||
if the browser pops up a prompt to ask for permission to access the
|
||||
microphone, the SDL_OpenAudioDevice call will succeed and start producing
|
||||
silence at a regular interval. Once the user approves the request, real
|
||||
audio data will flow. If the user denies it, the app is not informed and
|
||||
will just continue to receive silence.
|
||||
|
||||
Modern web browsers will not permit web pages to produce sound before the
|
||||
user has interacted with them; this is for several reasons, not the least
|
||||
of which being that no one likes when a random browser tab suddenly starts
|
||||
making noise and the user has to scramble to figure out which and silence
|
||||
it.
|
||||
user has interacted with them (clicked or tapped on them, usually); this is
|
||||
for several reasons, not the least of which being that no one likes when a
|
||||
random browser tab suddenly starts making noise and the user has to scramble
|
||||
to figure out which and silence it.
|
||||
|
||||
To solve this, most browsers will refuse to let a web app use the audio
|
||||
subsystem at all before the user has interacted with (clicked on) the page
|
||||
in a meaningful way. SDL-based apps also have to deal with this problem; if
|
||||
the user hasn't interacted with the page, SDL_OpenAudioDevice will fail.
|
||||
SDL will allow you to open the audio device for playback in this
|
||||
circumstance, and your audio callback will fire, but SDL will throw the audio
|
||||
data away until the user interacts with the page. This helps apps that depend
|
||||
on the audio callback to make progress, and also keeps audio playback in sync
|
||||
once the app is finally allowed to make noise.
|
||||
|
||||
There are two reasonable ways to deal with this: if you are writing some
|
||||
sort of media player thing, where the user expects there to be a volume
|
||||
control when you mouseover the canvas, just default that control to a muted
|
||||
state; if the user clicks on the control to unmute it, on this first click,
|
||||
open the audio device. This allows the media to play at start, the user can
|
||||
reasonably opt-in to listening, and you never get access denied to the audio
|
||||
device.
|
||||
There are two reasonable ways to deal with the silence at the app level:
|
||||
if you are writing some sort of media player thing, where the user expects
|
||||
there to be a volume control when you mouseover the canvas, just default
|
||||
that control to a muted state; if the user clicks on the control to unmute
|
||||
it, on this first click, open the audio device. This allows the media to
|
||||
play at start, and the user can reasonably opt-in to listening.
|
||||
|
||||
Many games do not have this sort of UI, and are more rigid about starting
|
||||
audio along with everything else at the start of the process. For these, your
|
||||
@ -36,41 +196,170 @@ Please see the discussion at https://github.com/libsdl-org/SDL/issues/6385
|
||||
for some Javascript code to steal for this approach.
|
||||
|
||||
|
||||
## Rendering
|
||||
|
||||
If you use SDL's 2D render API, it will use GLES2 internally, which
|
||||
Emscripten will turn into WebGL calls. You can also use OpenGL ES 2
|
||||
directly by creating a GL context and drawing into it.
|
||||
|
||||
Calling SDL_RenderPresent (or SDL_GL_SwapWindow) will not actually
|
||||
present anything on the screen until your return from your mainloop
|
||||
function.
|
||||
|
||||
|
||||
## Building SDL/emscripten
|
||||
|
||||
First: do you _really_ need to build SDL from source?
|
||||
|
||||
If you aren't developing SDL itself, have a desire to mess with its source
|
||||
code, or need something on the bleeding edge, don't build SDL. Just use
|
||||
Emscripten's packaged version!
|
||||
|
||||
Compile and link your app with `-sUSE_SDL=2` and it'll use a build of
|
||||
SDL packaged with Emscripten. This comes from the same source code and
|
||||
fixes the Emscripten project makes to SDL are generally merged into SDL's
|
||||
revision control, so often this is much easier for app developers.
|
||||
|
||||
`-sUSE_SDL=1` will select Emscripten's JavaScript reimplementation of SDL
|
||||
1.2 instead; if you need SDL 1.2, this might be fine, but we generally
|
||||
recommend you don't use SDL 1.2 in modern times.
|
||||
|
||||
|
||||
If you want to build SDL, though...
|
||||
|
||||
SDL currently requires at least Emscripten 3.1.35 to build. Newer versions
|
||||
are likely to work, as well.
|
||||
|
||||
|
||||
Build:
|
||||
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ emcmake cmake ..
|
||||
$ emmake make
|
||||
This works on Linux/Unix and macOS. Please send comments about Windows.
|
||||
|
||||
Or with cmake:
|
||||
Make sure you've [installed emsdk](https://emscripten.org/docs/getting_started/downloads.html)
|
||||
first, and run `source emsdk_env.sh` at the command line so it finds the
|
||||
tools.
|
||||
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ emcmake cmake ..
|
||||
$ emmake make
|
||||
(These cmake options might be overkill, but this has worked for me.)
|
||||
|
||||
To build one of the tests:
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
emcmake cmake ..
|
||||
# you can also do `emcmake cmake -G Ninja ..` and then use `ninja` instead of this command.
|
||||
emmake make -j4
|
||||
```
|
||||
|
||||
$ cd test/
|
||||
$ emcc -O2 --js-opts 0 -g4 testdraw.c -I../include ../build/.libs/libSDL3.a ../build/libSDL3_test.a -o a.html
|
||||
If you want to build with thread support, something like this works:
|
||||
|
||||
Uses GLES2 renderer or software
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
emcmake cmake -DSDL_THREADS=On ..
|
||||
# you can also do `emcmake cmake -G Ninja ..` and then use `ninja` instead of this command.
|
||||
emmake make -j4
|
||||
```
|
||||
|
||||
Some other SDL3 libraries can be easily built (assuming SDL3 is installed somewhere):
|
||||
To build the tests, add `-DSDL_TESTS=On` to the `emcmake cmake` command line.
|
||||
|
||||
SDL_mixer (http://www.libsdl.org/projects/SDL_mixer/):
|
||||
|
||||
$ emcmake cmake ..
|
||||
build as usual...
|
||||
## Building your app
|
||||
|
||||
You need to compile with `emcc` instead of `gcc` or `clang` or whatever, but
|
||||
mostly it uses the same command line arguments as Clang.
|
||||
|
||||
Link against the SDL/build/libSDL3.a file you generated by building SDL,
|
||||
link with `-sUSE_SDL=2` to use Emscripten's prepackaged SDL2 build.
|
||||
|
||||
Usually you would produce a binary like this:
|
||||
|
||||
```bash
|
||||
gcc -o mygame mygame.c # or whatever
|
||||
```
|
||||
|
||||
But for Emscripten, you want to output something else:
|
||||
|
||||
```bash
|
||||
emcc -o index.html mygame.c
|
||||
```
|
||||
|
||||
This will produce several files...support Javascript and WebAssembly (.wasm)
|
||||
files. The `-o index.html` will produce a simple HTML page that loads and
|
||||
runs your app. You will (probably) eventually want to replace or customize
|
||||
that file and do `-o index.js` instead to just build the code pieces.
|
||||
|
||||
If you're working on a program of any serious size, you'll likely need to
|
||||
link with `-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb` to get access
|
||||
to more memory. If using pthreads, you'll need the `-sMAXIMUM_MEMORY=1gb`
|
||||
or the app will fail to start on iOS browsers, but this might be a bug that
|
||||
goes away in the future.
|
||||
|
||||
|
||||
## Data files
|
||||
|
||||
Your game probably has data files. Here's how to access them.
|
||||
|
||||
Filesystem access works like a Unix filesystem; you have a single directory
|
||||
tree, possibly interpolated from several mounted locations, no drive letters,
|
||||
'/' for a path separator. You can access them with standard file APIs like
|
||||
open() or fopen() or SDL_RWops. You can read or write from the filesystem.
|
||||
|
||||
By default, you probably have a "MEMFS" filesystem (all files are stored in
|
||||
memory, but access to them is immediate and doesn't need to block). There are
|
||||
other options, like "IDBFS" (files are stored in a local database, so they
|
||||
don't need to be in RAM all the time and they can persist between runs of the
|
||||
program, but access is not synchronous). You can mix and match these file
|
||||
systems, mounting a MEMFS filesystem at one place and idbfs elsewhere, etc,
|
||||
but that's beyond the scope of this document. Please refer to Emscripten's
|
||||
[page on the topic](https://emscripten.org/docs/porting/files/file_systems_overview.html)
|
||||
for more info.
|
||||
|
||||
The _easiest_ (but not the best) way to get at your data files is to embed
|
||||
them in the app itself. Emscripten's linker has support for automating this.
|
||||
|
||||
```bash
|
||||
emcc -o index.html loopwave.c --embed-file=../test/sample.wav@/sounds/sample.wav
|
||||
```
|
||||
|
||||
This will pack ../test/sample.wav in your app, and make it available at
|
||||
"/sounds/sample.wav" at runtime. Emscripten makes sure this data is available
|
||||
before your main() function runs, and since it's in MEMFS, you can just
|
||||
read it like you do on other platforms. `--embed-file` can also accept a
|
||||
directory to pack an entire tree, and you can specify the argument multiple
|
||||
times to pack unrelated things into the final installation.
|
||||
|
||||
Note that this is absolutely the best approach if you have a few small
|
||||
files to include and shouldn't worry about the issue further. However, if you
|
||||
have hundreds of megabytes and/or thousands of files, this is not so great,
|
||||
since the user will download it all every time they load your page, and it
|
||||
all has to live in memory at runtime.
|
||||
|
||||
[Emscripten's documentation on the matter](https://emscripten.org/docs/porting/files/packaging_files.html)
|
||||
gives other options and details, and is worth a read.
|
||||
|
||||
|
||||
## Debugging
|
||||
|
||||
Debugging web apps is a mixed bag. You should compile and link with
|
||||
`-gsource-map`, which embeds a ton of source-level debugging information into
|
||||
the build, and make sure _the app source code is available on the web server_,
|
||||
which is often a scary proposition for various reasons.
|
||||
|
||||
When you debug from the browser's tools and hit a breakpoint, you can step
|
||||
through the actual C/C++ source code, though, which can be nice.
|
||||
|
||||
If you try debugging in Firefox and it doesn't work well for no apparent
|
||||
reason, try Chrome, and vice-versa. These tools are still relatively new,
|
||||
and improving all the time.
|
||||
|
||||
SDL_Log() (or even plain old printf) will write to the Javascript console,
|
||||
and honestly I find printf-style debugging to be easier than setting up a build
|
||||
for proper debugging, so use whatever tools work best for you.
|
||||
|
||||
|
||||
## Questions?
|
||||
|
||||
Please give us feedback on this document at [the SDL bug tracker](https://github.com/libsdl-org/SDL/issues).
|
||||
If something is wrong or unclear, we want to know!
|
||||
|
||||
|
||||
SDL_gfx (http://cms.ferzkopp.net/index.php/software/13-sdl-gfx):
|
||||
|
||||
$ emcmake cmake ..
|
||||
build as usual...
|
||||
|
@ -29,6 +29,12 @@ The Windows GDK port supports the full set of Win32 APIs, renderers, controllers
|
||||
* Global task queue callbacks are dispatched during `SDL_PumpEvents` (which is also called internally if using `SDL_PollEvent`).
|
||||
* You can get the handle of the global task queue through `SDL_GDKGetTaskQueue`, if needed. When done with the queue, be sure to use `XTaskQueueCloseHandle` to decrement the reference count (otherwise it will cause a resource leak).
|
||||
|
||||
* Single-player games have some additional features available:
|
||||
* Call `SDL_GDKGetDefaultUser` to get the default XUserHandle pointer.
|
||||
* `SDL_GetPrefPath` still works, but only for single-player titles.
|
||||
|
||||
These functions mostly wrap around async APIs, and thus should be treated as synchronous alternatives. Also note that the single-player functions return on any OS errors, so be sure to validate the return values!
|
||||
|
||||
* What doesn't work:
|
||||
* Compilation with anything other than through the included Visual C++ solution file
|
||||
|
||||
|
@ -4,6 +4,8 @@ This guide provides useful information for migrating applications from SDL 2.0 t
|
||||
|
||||
Details on API changes are organized by SDL 2.0 header below.
|
||||
|
||||
The file with your main() function should include <SDL3/SDL_main.h>, as that is no longer included in SDL.h.
|
||||
|
||||
Many functions and symbols have been renamed. We have provided a handy Python script [rename_symbols.py](https://github.com/libsdl-org/SDL/blob/main/build-scripts/rename_symbols.py) to rename SDL2 functions to their SDL3 counterparts:
|
||||
```sh
|
||||
rename_symbols.py --all-symbols source_code_path
|
||||
@ -11,14 +13,11 @@ rename_symbols.py --all-symbols source_code_path
|
||||
|
||||
It's also possible to apply a semantic patch to migrate more easily to SDL3: [SDL_migration.cocci](https://github.com/libsdl-org/SDL/blob/main/build-scripts/SDL_migration.cocci)
|
||||
|
||||
|
||||
SDL headers should now be included as `#include <SDL3/SDL.h>`. Typically that's the only header you'll need in your application unless you are using OpenGL or Vulkan functionality. We have provided a handy Python script [rename_headers.py](https://github.com/libsdl-org/SDL/blob/main/build-scripts/rename_headers.py) to rename SDL2 headers to their SDL3 counterparts:
|
||||
```sh
|
||||
rename_headers.py source_code_path
|
||||
```
|
||||
|
||||
The file with your main() function should also include <SDL3/SDL_main.h>, see below in the SDL_main.h section.
|
||||
|
||||
CMake users should use this snippet to include SDL support in their project:
|
||||
```
|
||||
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
||||
@ -39,10 +38,7 @@ LDFLAGS += $(shell pkg-config sdl3 --libs)
|
||||
|
||||
The SDL3test library has been renamed SDL3_test.
|
||||
|
||||
There is no SDLmain library anymore, it's now header-only, see below in the SDL_main.h section.
|
||||
|
||||
|
||||
begin_code.h and close_code.h in the public headers have been renamed to SDL_begin_code.h and SDL_close_code.h. These aren't meant to be included directly by applications, but if your application did, please update your `#include` lines.
|
||||
The SDLmain library has been removed, it's been entirely replaced by SDL_main.h.
|
||||
|
||||
The vi format comments have been removed from source code. Vim users can use the [editorconfig plugin](https://github.com/editorconfig/editorconfig-vim) to automatically set tab spacing for the SDL coding style.
|
||||
|
||||
@ -53,15 +49,15 @@ 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 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; however, there is still a callback method available if needed.
|
||||
|
||||
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:
|
||||
SDL3's audio subsystem offers an enormous amount of power over SDL2, but if you just want a simple migration of your existing code, you can ignore most of it. The simplest migration path from SDL2 looks something like this:
|
||||
|
||||
In SDL2, you might have done something like this to play audio:
|
||||
In SDL2, you might have done something like this to play audio...
|
||||
|
||||
```c
|
||||
void SDLCALL MyAudioCallback(void *userdata, Uint8 * stream, int len)
|
||||
@ -82,20 +78,7 @@ In SDL2, you might have done something like this to play audio:
|
||||
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:
|
||||
...in SDL3, you can do this...
|
||||
|
||||
```c
|
||||
void SDLCALL MyAudioCallback(SDL_AudioStream *stream, int len, void *userdata)
|
||||
@ -105,19 +88,32 @@ If you absolutely require the callback method, SDL_AudioStreams can use a callba
|
||||
}
|
||||
|
||||
/* ...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. */
|
||||
const SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 };
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec, MyAudioCallback, &my_audio_callback_user_data);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
```
|
||||
|
||||
If you used SDL_QueueAudio instead of a callback in SDL2, this is also straightforward.
|
||||
|
||||
```c
|
||||
/* ...somewhere near startup... */
|
||||
const SDL_AudioSpec spec = { SDL_AUDIO_S16, 2, 44100 };
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec, NULL, NULL);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
|
||||
/* ...in your main loop... */
|
||||
/* calculate a little more audio into `buf`, add it to `stream` */
|
||||
SDL_PutAudioStreamData(stream, buf, buflen);
|
||||
|
||||
```
|
||||
|
||||
...these same migration examples apply to audio capture, just using SDL_GetAudioStreamData instead of SDL_PutAudioStreamData.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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, and logical and physical devices are almost entirely interchangeable at the API level.
|
||||
|
||||
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.
|
||||
|
||||
@ -125,13 +121,13 @@ Devices are not opened by an arbitrary string name anymore, but by device instan
|
||||
|
||||
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:
|
||||
Rather than iterating over audio devices using a device index, there are new functions, SDL_GetAudioOutputDevices() and SDL_GetAudioCaptureDevices(), 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);
|
||||
SDL_AudioDeviceID *devices = SDL_GetAudioOutputDevices(&num_devices);
|
||||
if (devices) {
|
||||
for (i = 0; i < num_devices; ++i) {
|
||||
SDL_AudioDeviceID instance_id = devices[i];
|
||||
@ -152,7 +148,7 @@ SDL_PauseAudioDevice() no longer takes a second argument; it always pauses the d
|
||||
|
||||
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_GetAudioDeviceStatus() has been removed; there is now SDL_AudioDevicePaused().
|
||||
|
||||
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.
|
||||
|
||||
@ -259,18 +255,18 @@ The following functions have been removed:
|
||||
* SDL_GetQueuedAudioSize()
|
||||
|
||||
The following symbols have been renamed:
|
||||
* AUDIO_F32 => SDL_AUDIO_F32
|
||||
* AUDIO_F32LSB => SDL_AUDIO_F32LSB
|
||||
* AUDIO_F32MSB => SDL_AUDIO_F32MSB
|
||||
* AUDIO_F32SYS => SDL_AUDIO_F32SYS
|
||||
* AUDIO_S16 => SDL_AUDIO_S16
|
||||
* AUDIO_S16LSB => SDL_AUDIO_S16LSB
|
||||
* AUDIO_S16MSB => SDL_AUDIO_S16MSB
|
||||
* AUDIO_S16SYS => SDL_AUDIO_S16SYS
|
||||
* AUDIO_S32 => SDL_AUDIO_S32
|
||||
* AUDIO_S32LSB => SDL_AUDIO_S32LSB
|
||||
* AUDIO_S32MSB => SDL_AUDIO_S32MSB
|
||||
* AUDIO_S32SYS => SDL_AUDIO_S32SYS
|
||||
* AUDIO_F32 => SDL_AUDIO_F32LE
|
||||
* AUDIO_F32LSB => SDL_AUDIO_F32LE
|
||||
* AUDIO_F32MSB => SDL_AUDIO_F32BE
|
||||
* AUDIO_F32SYS => SDL_AUDIO_F32
|
||||
* AUDIO_S16 => SDL_AUDIO_S16LE
|
||||
* AUDIO_S16LSB => SDL_AUDIO_S16LE
|
||||
* AUDIO_S16MSB => SDL_AUDIO_S16BE
|
||||
* AUDIO_S16SYS => SDL_AUDIO_S16
|
||||
* AUDIO_S32 => SDL_AUDIO_S32LE
|
||||
* AUDIO_S32LSB => SDL_AUDIO_S32LE
|
||||
* AUDIO_S32MSB => SDL_AUDIO_S32BE
|
||||
* AUDIO_S32SYS => SDL_AUDIO_S32
|
||||
* AUDIO_S8 => SDL_AUDIO_S8
|
||||
* AUDIO_U8 => SDL_AUDIO_U8
|
||||
|
||||
@ -378,8 +374,6 @@ The SDL_EVENT_GAMEPAD_ADDED event now provides the joystick instance ID in the w
|
||||
|
||||
The functions SDL_GetGamepads(), SDL_GetGamepadInstanceName(), SDL_GetGamepadInstancePath(), SDL_GetGamepadInstancePlayerIndex(), SDL_GetGamepadInstanceGUID(), SDL_GetGamepadInstanceVendor(), SDL_GetGamepadInstanceProduct(), SDL_GetGamepadInstanceProductVersion(), and SDL_GetGamepadInstanceType() have been added to directly query the list of available gamepads.
|
||||
|
||||
The gamepad binding structure has been removed in favor of exchanging bindings in text format.
|
||||
|
||||
SDL_GameControllerGetSensorDataWithTimestamp() has been removed. If you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_GAMEPAD_SENSOR_UPDATE events.
|
||||
|
||||
SDL_CONTROLLER_TYPE_VIRTUAL has been removed, so virtual controllers can emulate other gamepad types. If you need to know whether a controller is virtual, you can use SDL_IsJoystickVirtual().
|
||||
@ -417,7 +411,6 @@ The following enums have been renamed:
|
||||
|
||||
The following structures have been renamed:
|
||||
* SDL_GameController => SDL_Gamepad
|
||||
* SDL_GameControllerButtonBind => SDL_GamepadBinding
|
||||
|
||||
The following functions have been renamed:
|
||||
* SDL_GameControllerAddMapping() => SDL_AddGamepadMapping()
|
||||
@ -431,8 +424,6 @@ The following functions have been renamed:
|
||||
* SDL_GameControllerGetAttached() => SDL_GamepadConnected()
|
||||
* SDL_GameControllerGetAxis() => SDL_GetGamepadAxis()
|
||||
* SDL_GameControllerGetAxisFromString() => SDL_GetGamepadAxisFromString()
|
||||
* SDL_GameControllerGetBindForAxis() => SDL_GetGamepadBindForAxis()
|
||||
* SDL_GameControllerGetBindForButton() => SDL_GetGamepadBindForButton()
|
||||
* SDL_GameControllerGetButton() => SDL_GetGamepadButton()
|
||||
* SDL_GameControllerGetButtonFromString() => SDL_GetGamepadButtonFromString()
|
||||
* SDL_GameControllerGetFirmwareVersion() => SDL_GetGamepadFirmwareVersion()
|
||||
@ -475,8 +466,8 @@ The following functions have been renamed:
|
||||
|
||||
The following functions have been removed:
|
||||
* SDL_GameControllerEventState() - replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled()
|
||||
* SDL_GameControllerGetBindForAxis()
|
||||
* SDL_GameControllerGetBindForButton()
|
||||
* SDL_GameControllerGetBindForAxis() - replaced with SDL_GetGamepadBindings()
|
||||
* SDL_GameControllerGetBindForButton() - replaced with SDL_GetGamepadBindings()
|
||||
* SDL_GameControllerMappingForDeviceIndex() - replaced with SDL_GetGamepadInstanceMapping()
|
||||
* SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadInstanceName()
|
||||
* SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadInstancePath()
|
||||
@ -699,27 +690,6 @@ Instead SDL_main.h is now a header-only library **and not included by SDL.h anym
|
||||
Using it is really simple: Just `#include <SDL3/SDL_main.h>` in the source file with your standard
|
||||
`int main(int argc, char* argv[])` function.
|
||||
|
||||
The rest happens automatically: If your target platform needs the SDL_main functionality,
|
||||
your main function will be renamed to SDL_main (with a macro, just like in SDL2),
|
||||
and the real main-function will be implemented by inline code from SDL_main.h - and if your target
|
||||
platform doesn't need it, nothing happens.
|
||||
Like in SDL2, if you want to handle the platform-specific main yourself instead of using the SDL_main magic,
|
||||
you can `#define SDL_MAIN_HANDLED` before `#include <SDL3/SDL_main.h>` - don't forget to call SDL_SetMainReady()
|
||||
|
||||
If you need SDL_main.h in another source file (that doesn't implement main()), you also need to
|
||||
`#define SDL_MAIN_HANDLED` there, to avoid that multiple main functions are generated by SDL_main.h
|
||||
|
||||
There is currently one platform where this approach doesn't always work: WinRT.
|
||||
It requires WinMain to be implemented in a C++ source file that's compiled with `/ZW`. If your main
|
||||
is implemented in plain C, or you can't use `/ZW` on that file, you can add another .cpp
|
||||
source file that just contains `#include <SDL3/SDL_main.h>` and compile that with `/ZW` - but keep
|
||||
in mind that the source file with your standard main also needs that include!
|
||||
See [README-winrt.md](./README-winrt.md) for more details.
|
||||
|
||||
Furthermore, the different SDL_*RunApp() functions (SDL_WinRtRunApp, SDL_GDKRunApp, SDL_UIKitRunApp)
|
||||
have been unified into just `int SDL_RunApp(int argc, char* argv[], void * reserved)` (which is also
|
||||
used by additional platforms that didn't have a SDL_RunApp-like function before).
|
||||
|
||||
## SDL_metal.h
|
||||
|
||||
SDL_Metal_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place.
|
||||
|
@ -34,3 +34,12 @@ encounter limitations or behavior that is different from other windowing systems
|
||||
### Warping the global mouse cursor position via ```SDL_WarpMouseGlobal()``` doesn't work
|
||||
|
||||
- For security reasons, Wayland does not allow warping the global mouse cursor position.
|
||||
|
||||
### The application icon can't be set via ```SDL_SetWindowIcon()```
|
||||
|
||||
- Wayland doesn't support programmatically setting the application icon. To provide a custom icon for your application,
|
||||
you must create an associated desktop entry file, aka a `.desktop` file, that points to the icon image. Please see the
|
||||
[Desktop Entry Specification](https://specifications.freedesktop.org/desktop-entry-spec/latest/) for more information
|
||||
on the format of this file. Note that if your application manually sets the application ID via the `SDL_APP_ID` hint
|
||||
string, the desktop entry file name should match the application ID. For example, if your application ID is set
|
||||
to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`.
|
||||
|
@ -56,3 +56,11 @@ it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You
|
||||
must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to
|
||||
use Vulkan graphics in your application.
|
||||
|
||||
## Transparent Window Support
|
||||
|
||||
SDL uses the Desktop Window Manager (DWM) to create transparent windows. DWM is
|
||||
always enabled from Windows 8 and above. Windows 7 only enables DWM with Aero Glass
|
||||
theme.
|
||||
|
||||
However, it cannot be guaranteed to work on all hardware configurations (an example
|
||||
is hybrid GPU systems, such as NVIDIA Optimus laptops).
|
||||
|
Reference in New Issue
Block a user