-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathREADME-migration.md
1176 lines (953 loc) · 56 KB
/
README-migration.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Migrating to SDL 3.0
This guide provides useful information for migrating applications from SDL 2.0 to SDL 3.0.
Details on API changes are organized by SDL 2.0 header below.
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
```
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)
target_link_libraries(mygame PRIVATE SDL3::SDL3)
```
Autotools users should use this snippet to include SDL support in their project:
```
PKG_CHECK_MODULES([SDL3], [sdl3])
```
and then add $SDL3_CFLAGS to their project CFLAGS and $SDL3_LIBS to their project LDFLAGS
Makefile users can use this snippet to include SDL support in their project:
```
CFLAGS += $(shell pkg-config sdl3 --cflags)
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 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.
## SDL_atomic.h
The following structures have been renamed:
- SDL_atomic_t => SDL_AtomicInt
## SDL_audio.h
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.
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.
Code that used to look like this:
```c
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate);
cvt.len = src_len;
cvt.buf = (Uint8 *) SDL_malloc(src_len * cvt.len_mult);
SDL_memcpy(cvt.buf, src_data, src_len);
SDL_ConvertAudio(&cvt);
do_something(cvt.buf, cvt.len_cvt);
```
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) {
/* error */
}
do_something(dst_data, dst_len);
SDL_free(dst_data);
```
AUDIO_U16, AUDIO_U16LSB, AUDIO_U16MSB, and AUDIO_U16SYS have been removed. They were not heavily used, and one could not memset a buffer in this format to silence with a single byte value. Use a different audio format.
If you need to convert U16 audio data to a still-supported format at runtime, the fastest, lossless conversion is to SDL_AUDIO_S16:
```c
/* this converts the buffer in-place. The buffer size does not change. */
Sint16 *audio_ui16_to_si16(Uint16 *buffer, const size_t num_samples)
{
size_t i;
const Uint16 *src = buffer;
Sint16 *dst = (Sint16 *) buffer;
for (i = 0; i < num_samples; i++) {
dst[i] = (Sint16) (src[i] ^ 0x8000);
}
return dst;
}
```
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.
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.
The following functions have been renamed:
* SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable()
* SDL_AudioStreamClear() => SDL_ClearAudioStream()
* SDL_AudioStreamFlush() => SDL_FlushAudioStream()
* SDL_AudioStreamGet() => SDL_GetAudioStreamData()
* SDL_AudioStreamPut() => SDL_PutAudioStreamData()
* SDL_FreeAudioStream() => SDL_DestroyAudioStream()
* SDL_NewAudioStream() => SDL_CreateAudioStream()
The following functions have been removed:
* SDL_ConvertAudio()
* SDL_BuildAudioCVT()
* SDL_OpenAudio()
* SDL_CloseAudio()
* SDL_PauseAudio()
* SDL_GetAudioStatus()
* SDL_LockAudio()
* SDL_UnlockAudio()
* SDL_MixAudio()
Use the SDL_AudioDevice functions instead.
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_S8 => SDL_AUDIO_S8
* AUDIO_U8 => SDL_AUDIO_U8
## SDL_cpuinfo.h
The intrinsics headers (mmintrin.h, etc.) have been moved to `<SDL3/SDL_intrin.h>` and are no longer automatically included in SDL.h.
SDL_Has3DNow() has been removed; there is no replacement.
SDL_SIMDAlloc(), SDL_SIMDRealloc(), and SDL_SIMDFree() have been removed. You can use SDL_aligned_alloc() and SDL_aligned_free() with SDL_SIMDGetAlignment() to get the same functionality.
## SDL_events.h
The timestamp member of the SDL_Event structure now represents nanoseconds, and is populated with SDL_GetTicksNS()
The timestamp_us member of the sensor events has been renamed sensor_timestamp and now represents nanoseconds. This value is filled in from the hardware, if available, and may not be synchronized with values returned from SDL_GetTicksNS().
You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().
Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.
The SDL_DISPLAYEVENT_* events have been moved to top level events, and SDL_DISPLAYEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_DISPLAYEVENT and then checking for display events. You can compare the event >= SDL_EVENT_DISPLAY_FIRST and <= SDL_EVENT_DISPLAY_LAST if you need to see whether it's a display event.
The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event.
The SDL_EVENT_WINDOW_RESIZED event is always sent, even in response to SDL_SetWindowSize().
The SDL_EVENT_WINDOW_SIZE_CHANGED event has been removed, and you can use SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED to detect window backbuffer size changes.
The gamepad event structures caxis, cbutton, cdevice, ctouchpad, and csensor have been renamed gaxis, gbutton, gdevice, gtouchpad, and gsensor.
SDL_QUERY, SDL_IGNORE, SDL_ENABLE, and SDL_DISABLE have been removed. You can use the functions SDL_SetEventEnabled() and SDL_EventEnabled() to set and query event processing state.
The following symbols have been renamed:
* SDL_APP_DIDENTERBACKGROUND => SDL_EVENT_DID_ENTER_BACKGROUND
* SDL_APP_DIDENTERFOREGROUND => SDL_EVENT_DID_ENTER_FOREGROUND
* SDL_APP_LOWMEMORY => SDL_EVENT_LOW_MEMORY
* SDL_APP_TERMINATING => SDL_EVENT_TERMINATING
* SDL_APP_WILLENTERBACKGROUND => SDL_EVENT_WILL_ENTER_BACKGROUND
* SDL_APP_WILLENTERFOREGROUND => SDL_EVENT_WILL_ENTER_FOREGROUND
* SDL_AUDIODEVICEADDED => SDL_EVENT_AUDIO_DEVICE_ADDED
* SDL_AUDIODEVICEREMOVED => SDL_EVENT_AUDIO_DEVICE_REMOVED
* SDL_CLIPBOARDUPDATE => SDL_EVENT_CLIPBOARD_UPDATE
* SDL_CONTROLLERAXISMOTION => SDL_EVENT_GAMEPAD_AXIS_MOTION
* SDL_CONTROLLERBUTTONDOWN => SDL_EVENT_GAMEPAD_BUTTON_DOWN
* SDL_CONTROLLERBUTTONUP => SDL_EVENT_GAMEPAD_BUTTON_UP
* SDL_CONTROLLERDEVICEADDED => SDL_EVENT_GAMEPAD_ADDED
* SDL_CONTROLLERDEVICEREMAPPED => SDL_EVENT_GAMEPAD_REMAPPED
* SDL_CONTROLLERDEVICEREMOVED => SDL_EVENT_GAMEPAD_REMOVED
* SDL_CONTROLLERSENSORUPDATE => SDL_EVENT_GAMEPAD_SENSOR_UPDATE
* SDL_CONTROLLERTOUCHPADDOWN => SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN
* SDL_CONTROLLERTOUCHPADMOTION => SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION
* SDL_CONTROLLERTOUCHPADUP => SDL_EVENT_GAMEPAD_TOUCHPAD_UP
* SDL_DROPBEGIN => SDL_EVENT_DROP_BEGIN
* SDL_DROPCOMPLETE => SDL_EVENT_DROP_COMPLETE
* SDL_DROPFILE => SDL_EVENT_DROP_FILE
* SDL_DROPTEXT => SDL_EVENT_DROP_TEXT
* SDL_FINGERDOWN => SDL_EVENT_FINGER_DOWN
* SDL_FINGERMOTION => SDL_EVENT_FINGER_MOTION
* SDL_FINGERUP => SDL_EVENT_FINGER_UP
* SDL_FIRSTEVENT => SDL_EVENT_FIRST
* SDL_JOYAXISMOTION => SDL_EVENT_JOYSTICK_AXIS_MOTION
* SDL_JOYBATTERYUPDATED => SDL_EVENT_JOYSTICK_BATTERY_UPDATED
* SDL_JOYBUTTONDOWN => SDL_EVENT_JOYSTICK_BUTTON_DOWN
* SDL_JOYBUTTONUP => SDL_EVENT_JOYSTICK_BUTTON_UP
* SDL_JOYDEVICEADDED => SDL_EVENT_JOYSTICK_ADDED
* SDL_JOYDEVICEREMOVED => SDL_EVENT_JOYSTICK_REMOVED
* SDL_JOYHATMOTION => SDL_EVENT_JOYSTICK_HAT_MOTION
* SDL_KEYDOWN => SDL_EVENT_KEY_DOWN
* SDL_KEYMAPCHANGED => SDL_EVENT_KEYMAP_CHANGED
* SDL_KEYUP => SDL_EVENT_KEY_UP
* SDL_LASTEVENT => SDL_EVENT_LAST
* SDL_LOCALECHANGED => SDL_EVENT_LOCALE_CHANGED
* SDL_MOUSEBUTTONDOWN => SDL_EVENT_MOUSE_BUTTON_DOWN
* SDL_MOUSEBUTTONUP => SDL_EVENT_MOUSE_BUTTON_UP
* SDL_MOUSEMOTION => SDL_EVENT_MOUSE_MOTION
* SDL_MOUSEWHEEL => SDL_EVENT_MOUSE_WHEEL
* SDL_POLLSENTINEL => SDL_EVENT_POLL_SENTINEL
* SDL_QUIT => SDL_EVENT_QUIT
* SDL_RENDER_DEVICE_RESET => SDL_EVENT_RENDER_DEVICE_RESET
* SDL_RENDER_TARGETS_RESET => SDL_EVENT_RENDER_TARGETS_RESET
* SDL_SENSORUPDATE => SDL_EVENT_SENSOR_UPDATE
* SDL_SYSWMEVENT => SDL_EVENT_SYSWM
* SDL_TEXTEDITING => SDL_EVENT_TEXT_EDITING
* SDL_TEXTEDITING_EXT => SDL_EVENT_TEXT_EDITING_EXT
* SDL_TEXTINPUT => SDL_EVENT_TEXT_INPUT
* SDL_USEREVENT => SDL_EVENT_USER
The following structures have been renamed:
* SDL_ControllerAxisEvent => SDL_GamepadAxisEvent
* SDL_ControllerButtonEvent => SDL_GamepadButtonEvent
* SDL_ControllerDeviceEvent => SDL_GamepadDeviceEvent
* SDL_ControllerSensorEvent => SDL_GamepadSensorEvent
* SDL_ControllerTouchpadEvent => SDL_GamepadTouchpadEvent
The following functions have been removed:
* SDL_EventState() - replaced with SDL_SetEventEnabled()
* SDL_GetEventState() - replaced with SDL_EventEnabled()
## SDL_gamecontroller.h
SDL_gamecontroller.h has been renamed SDL_gamepad.h, and all APIs have been renamed to match.
The SDL_EVENT_GAMEPAD_ADDED event now provides the joystick instance ID in the which member of the cdevice event structure.
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.
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.
The following enums have been renamed:
* SDL_GameControllerAxis => SDL_GamepadAxis
* SDL_GameControllerBindType => SDL_GamepadBindingType
* SDL_GameControllerButton => SDL_GamepadButton
* SDL_GameControllerType => SDL_GamepadType
The following structures have been renamed:
* SDL_GameController => SDL_Gamepad
* SDL_GameControllerButtonBind => SDL_GamepadBinding
The following functions have been renamed:
* SDL_GameControllerAddMapping() => SDL_AddGamepadMapping()
* SDL_GameControllerAddMappingsFromFile() => SDL_AddGamepadMappingsFromFile()
* SDL_GameControllerAddMappingsFromRW() => SDL_AddGamepadMappingsFromRW()
* SDL_GameControllerClose() => SDL_CloseGamepad()
* SDL_GameControllerFromInstanceID() => SDL_GetGamepadFromInstanceID()
* SDL_GameControllerFromPlayerIndex() => SDL_GetGamepadFromPlayerIndex()
* SDL_GameControllerGetAppleSFSymbolsNameForAxis() => SDL_GetGamepadAppleSFSymbolsNameForAxis()
* SDL_GameControllerGetAppleSFSymbolsNameForButton() => SDL_GetGamepadAppleSFSymbolsNameForButton()
* 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()
* SDL_GameControllerGetJoystick() => SDL_GetGamepadJoystick()
* SDL_GameControllerGetNumTouchpadFingers() => SDL_GetNumGamepadTouchpadFingers()
* SDL_GameControllerGetNumTouchpads() => SDL_GetNumGamepadTouchpads()
* SDL_GameControllerGetPlayerIndex() => SDL_GetGamepadPlayerIndex()
* SDL_GameControllerGetProduct() => SDL_GetGamepadProduct()
* SDL_GameControllerGetProductVersion() => SDL_GetGamepadProductVersion()
* SDL_GameControllerGetSensorData() => SDL_GetGamepadSensorData()
* SDL_GameControllerGetSensorDataRate() => SDL_GetGamepadSensorDataRate()
* SDL_GameControllerGetSerial() => SDL_GetGamepadSerial()
* SDL_GameControllerGetStringForAxis() => SDL_GetGamepadStringForAxis()
* SDL_GameControllerGetStringForButton() => SDL_GetGamepadStringForButton()
* SDL_GameControllerGetTouchpadFinger() => SDL_GetGamepadTouchpadFinger()
* SDL_GameControllerGetType() => SDL_GetGamepadType()
* SDL_GameControllerGetVendor() => SDL_GetGamepadVendor()
* SDL_GameControllerHasAxis() => SDL_GamepadHasAxis()
* SDL_GameControllerHasButton() => SDL_GamepadHasButton()
* SDL_GameControllerHasLED() => SDL_GamepadHasLED()
* SDL_GameControllerHasRumble() => SDL_GamepadHasRumble()
* SDL_GameControllerHasRumbleTriggers() => SDL_GamepadHasRumbleTriggers()
* SDL_GameControllerHasSensor() => SDL_GamepadHasSensor()
* SDL_GameControllerIsSensorEnabled() => SDL_GamepadSensorEnabled()
* SDL_GameControllerMapping() => SDL_GetGamepadMapping()
* SDL_GameControllerMappingForGUID() => SDL_GetGamepadMappingForGUID()
* SDL_GameControllerMappingForIndex() => SDL_GetGamepadMappingForIndex()
* SDL_GameControllerName() => SDL_GetGamepadName()
* SDL_GameControllerNumMappings() => SDL_GetNumGamepadMappings()
* SDL_GameControllerOpen() => SDL_OpenGamepad()
* SDL_GameControllerPath() => SDL_GetGamepadPath()
* SDL_GameControllerRumble() => SDL_RumbleGamepad()
* SDL_GameControllerRumbleTriggers() => SDL_RumbleGamepadTriggers()
* SDL_GameControllerSendEffect() => SDL_SendGamepadEffect()
* SDL_GameControllerSetLED() => SDL_SetGamepadLED()
* SDL_GameControllerSetPlayerIndex() => SDL_SetGamepadPlayerIndex()
* SDL_GameControllerSetSensorEnabled() => SDL_SetGamepadSensorEnabled()
* SDL_GameControllerUpdate() => SDL_UpdateGamepads()
* SDL_IsGameController() => SDL_IsGamepad()
The following functions have been removed:
* SDL_GameControllerEventState() - replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled()
* SDL_GameControllerMappingForDeviceIndex() - replaced with SDL_GetGamepadInstanceMapping()
* SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadInstanceName()
* SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadInstancePath()
* SDL_GameControllerTypeForIndex() - replaced with SDL_GetGamepadInstanceType()
The following symbols have been renamed:
* SDL_CONTROLLER_AXIS_INVALID => SDL_GAMEPAD_AXIS_INVALID
* SDL_CONTROLLER_AXIS_LEFTX => SDL_GAMEPAD_AXIS_LEFTX
* SDL_CONTROLLER_AXIS_LEFTY => SDL_GAMEPAD_AXIS_LEFTY
* SDL_CONTROLLER_AXIS_MAX => SDL_GAMEPAD_AXIS_MAX
* SDL_CONTROLLER_AXIS_RIGHTX => SDL_GAMEPAD_AXIS_RIGHTX
* SDL_CONTROLLER_AXIS_RIGHTY => SDL_GAMEPAD_AXIS_RIGHTY
* SDL_CONTROLLER_AXIS_TRIGGERLEFT => SDL_GAMEPAD_AXIS_LEFT_TRIGGER
* SDL_CONTROLLER_AXIS_TRIGGERRIGHT => SDL_GAMEPAD_AXIS_RIGHT_TRIGGER
* SDL_CONTROLLER_BINDTYPE_AXIS => SDL_GAMEPAD_BINDTYPE_AXIS
* SDL_CONTROLLER_BINDTYPE_BUTTON => SDL_GAMEPAD_BINDTYPE_BUTTON
* SDL_CONTROLLER_BINDTYPE_HAT => SDL_GAMEPAD_BINDTYPE_HAT
* SDL_CONTROLLER_BINDTYPE_NONE => SDL_GAMEPAD_BINDTYPE_NONE
* SDL_CONTROLLER_BUTTON_A => SDL_GAMEPAD_BUTTON_A
* SDL_CONTROLLER_BUTTON_B => SDL_GAMEPAD_BUTTON_B
* SDL_CONTROLLER_BUTTON_BACK => SDL_GAMEPAD_BUTTON_BACK
* SDL_CONTROLLER_BUTTON_DPAD_DOWN => SDL_GAMEPAD_BUTTON_DPAD_DOWN
* SDL_CONTROLLER_BUTTON_DPAD_LEFT => SDL_GAMEPAD_BUTTON_DPAD_LEFT
* SDL_CONTROLLER_BUTTON_DPAD_RIGHT => SDL_GAMEPAD_BUTTON_DPAD_RIGHT
* SDL_CONTROLLER_BUTTON_DPAD_UP => SDL_GAMEPAD_BUTTON_DPAD_UP
* SDL_CONTROLLER_BUTTON_GUIDE => SDL_GAMEPAD_BUTTON_GUIDE
* SDL_CONTROLLER_BUTTON_INVALID => SDL_GAMEPAD_BUTTON_INVALID
* SDL_CONTROLLER_BUTTON_LEFTSHOULDER => SDL_GAMEPAD_BUTTON_LEFT_SHOULDER
* 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_RIGHTSHOULDER => SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER
* SDL_CONTROLLER_BUTTON_RIGHTSTICK => SDL_GAMEPAD_BUTTON_RIGHT_STICK
* SDL_CONTROLLER_BUTTON_START => SDL_GAMEPAD_BUTTON_START
* SDL_CONTROLLER_BUTTON_TOUCHPAD => SDL_GAMEPAD_BUTTON_TOUCHPAD
* SDL_CONTROLLER_BUTTON_X => SDL_GAMEPAD_BUTTON_X
* SDL_CONTROLLER_BUTTON_Y => SDL_GAMEPAD_BUTTON_Y
* SDL_CONTROLLER_TYPE_AMAZON_LUNA => SDL_GAMEPAD_TYPE_AMAZON_LUNA
* SDL_CONTROLLER_TYPE_GOOGLE_STADIA => SDL_GAMEPAD_TYPE_GOOGLE_STADIA
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT
* SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO
* SDL_CONTROLLER_TYPE_NVIDIA_SHIELD => SDL_GAMEPAD_TYPE_NVIDIA_SHIELD
* SDL_CONTROLLER_TYPE_PS3 => SDL_GAMEPAD_TYPE_PS3
* SDL_CONTROLLER_TYPE_PS4 => SDL_GAMEPAD_TYPE_PS4
* SDL_CONTROLLER_TYPE_PS5 => SDL_GAMEPAD_TYPE_PS5
* SDL_CONTROLLER_TYPE_UNKNOWN => SDL_GAMEPAD_TYPE_UNKNOWN
* SDL_CONTROLLER_TYPE_VIRTUAL => SDL_GAMEPAD_TYPE_VIRTUAL
* SDL_CONTROLLER_TYPE_XBOX360 => SDL_GAMEPAD_TYPE_XBOX360
* SDL_CONTROLLER_TYPE_XBOXONE => SDL_GAMEPAD_TYPE_XBOXONE
## SDL_gesture.h
The gesture API has been removed. There is no replacement planned in SDL3.
However, the SDL2 code has been moved to a single-header library that can
be dropped into an SDL3 or SDL2 program, to continue to provide this
functionality to your app and aid migration. That is located in the
[SDL_gesture GitHub repository](https://github.com/libsdl-org/SDL_gesture).
## SDL_hints.h
SDL_AddHintCallback() now returns a standard int result instead of void, returning 0 if the function succeeds or a negative error code if there was an error.
Calling SDL_GetHint() with the name of the hint being changed from within a hint callback will now return the new value rather than the old value. The old value is still passed as a parameter to the hint callback.
The following hints have been removed:
* SDL_HINT_VIDEO_HIGHDPI_DISABLED - high DPI support is always enabled
* SDL_HINT_IDLE_TIMER_DISABLED - use SDL_DisableScreenSaver instead
* SDL_HINT_MOUSE_RELATIVE_SCALING - mouse coordinates are no longer automatically scaled by the SDL renderer
* SDL_HINT_RENDER_LOGICAL_SIZE_MODE - the logical size mode is explicitly set with SDL_SetRenderLogicalPresentation()
* SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead
* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
* Renamed hints SDL_HINT_VIDEODRIVER and SDL_HINT_AUDIODRIVER to SDL_HINT_VIDEO_DRIVER and SDL_HINT_AUDIO_DRIVER
* Renamed environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER
* The environment variables SDL_VIDEO_X11_WMCLASS and SDL_VIDEO_WAYLAND_WMCLASS have been removed and replaced with the unified hint SDL_HINT_APP_ID
## SDL_init.h
The following symbols have been renamed:
* SDL_INIT_GAMECONTROLLER => SDL_INIT_GAMEPAD
The following symbols have been removed:
* SDL_INIT_NOPARACHUTE
## SDL_joystick.h
SDL_JoystickID has changed from Sint32 to Uint32, with an invalid ID being 0.
Rather than iterating over joysticks using device index, there is a new function SDL_GetJoysticks() to get the current list of joysticks, and new functions to get information about joysticks from their instance ID:
```c
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == 0) {
int i, num_joysticks;
SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks);
if (joysticks) {
for (i = 0; i < num_joysticks; ++i) {
SDL_JoystickID instance_id = joysticks[i];
const char *name = SDL_GetJoystickInstanceName(instance_id);
const char *path = SDL_GetJoystickInstancePath(instance_id);
SDL_Log("Joystick %" SDL_PRIu32 ": %s%s%s VID 0x%.4x, PID 0x%.4x\n",
instance_id, name ? name : "Unknown", path ? ", " : "", path ? path : "", SDL_GetJoystickInstanceVendor(instance_id), SDL_GetJoystickInstanceProduct(instance_id));
}
SDL_free(joysticks);
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
}
```
The SDL_EVENT_JOYSTICK_ADDED event now provides the joystick instance ID in the `which` member of the jdevice event structure.
The functions SDL_GetJoysticks(), SDL_GetJoystickInstanceName(), SDL_GetJoystickInstancePath(), SDL_GetJoystickInstancePlayerIndex(), SDL_GetJoystickInstanceGUID(), SDL_GetJoystickInstanceVendor(), SDL_GetJoystickInstanceProduct(), SDL_GetJoystickInstanceProductVersion(), and SDL_GetJoystickInstanceType() have been added to directly query the list of available joysticks.
SDL_AttachVirtualJoystick() and SDL_AttachVirtualJoystickEx() now return the joystick instance ID instead of a device index, and return 0 if there was an error.
The following functions have been renamed:
* SDL_JoystickAttachVirtual() => SDL_AttachVirtualJoystick()
* SDL_JoystickAttachVirtualEx() => SDL_AttachVirtualJoystickEx()
* SDL_JoystickClose() => SDL_CloseJoystick()
* SDL_JoystickCurrentPowerLevel() => SDL_GetJoystickPowerLevel()
* SDL_JoystickDetachVirtual() => SDL_DetachVirtualJoystick()
* SDL_JoystickFromInstanceID() => SDL_GetJoystickFromInstanceID()
* SDL_JoystickFromPlayerIndex() => SDL_GetJoystickFromPlayerIndex()
* SDL_JoystickGetAttached() => SDL_JoystickConnected()
* SDL_JoystickGetAxis() => SDL_GetJoystickAxis()
* SDL_JoystickGetAxisInitialState() => SDL_GetJoystickAxisInitialState()
* SDL_JoystickGetButton() => SDL_GetJoystickButton()
* SDL_JoystickGetFirmwareVersion() => SDL_GetJoystickFirmwareVersion()
* SDL_JoystickGetGUID() => SDL_GetJoystickGUID()
* SDL_JoystickGetGUIDFromString() => SDL_GetJoystickGUIDFromString()
* SDL_JoystickGetGUIDString() => SDL_GetJoystickGUIDString()
* SDL_JoystickGetHat() => SDL_GetJoystickHat()
* SDL_JoystickGetPlayerIndex() => SDL_GetJoystickPlayerIndex()
* SDL_JoystickGetProduct() => SDL_GetJoystickProduct()
* SDL_JoystickGetProductVersion() => SDL_GetJoystickProductVersion()
* SDL_JoystickGetSerial() => SDL_GetJoystickSerial()
* SDL_JoystickGetType() => SDL_GetJoystickType()
* SDL_JoystickGetVendor() => SDL_GetJoystickVendor()
* SDL_JoystickInstanceID() => SDL_GetJoystickInstanceID()
* SDL_JoystickIsVirtual() => SDL_IsJoystickVirtual()
* SDL_JoystickName() => SDL_GetJoystickName()
* SDL_JoystickNumAxes() => SDL_GetNumJoystickAxes()
* SDL_JoystickNumButtons() => SDL_GetNumJoystickButtons()
* SDL_JoystickNumHats() => SDL_GetNumJoystickHats()
* SDL_JoystickOpen() => SDL_OpenJoystick()
* SDL_JoystickPath() => SDL_GetJoystickPath()
* SDL_JoystickRumble() => SDL_RumbleJoystick()
* SDL_JoystickRumbleTriggers() => SDL_RumbleJoystickTriggers()
* SDL_JoystickSendEffect() => SDL_SendJoystickEffect()
* SDL_JoystickSetLED() => SDL_SetJoystickLED()
* SDL_JoystickSetPlayerIndex() => SDL_SetJoystickPlayerIndex()
* SDL_JoystickSetVirtualAxis() => SDL_SetJoystickVirtualAxis()
* SDL_JoystickSetVirtualButton() => SDL_SetJoystickVirtualButton()
* SDL_JoystickSetVirtualHat() => SDL_SetJoystickVirtualHat()
* SDL_JoystickUpdate() => SDL_UpdateJoysticks()
The following symbols have been renamed:
* SDL_JOYSTICK_TYPE_GAMECONTROLLER => SDL_JOYSTICK_TYPE_GAMEPAD
The following functions have been removed:
* SDL_JoystickEventState() - replaced with SDL_SetJoystickEventsEnabled() and SDL_JoystickEventsEnabled()
* SDL_JoystickGetDeviceGUID() - replaced with SDL_GetJoystickInstanceGUID()
* SDL_JoystickGetDeviceInstanceID()
* SDL_JoystickGetDevicePlayerIndex() - replaced with SDL_GetJoystickInstancePlayerIndex()
* SDL_JoystickGetDeviceProduct() - replaced with SDL_GetJoystickInstanceProduct()
* SDL_JoystickGetDeviceProductVersion() - replaced with SDL_GetJoystickInstanceProductVersion()
* SDL_JoystickGetDeviceType() - replaced with SDL_GetJoystickInstanceType()
* SDL_JoystickGetDeviceVendor() - replaced with SDL_GetJoystickInstanceVendor()
* SDL_JoystickNameForIndex() - replaced with SDL_GetJoystickInstanceName()
* SDL_JoystickNumBalls() - API has been removed, see https://github.com/libsdl-org/SDL/issues/6766
* SDL_JoystickPathForIndex() - replaced with SDL_GetJoystickInstancePath()
* SDL_NumJoysticks() - replaced with SDL_GetJoysticks()
The following symbols have been removed:
* SDL_JOYBALLMOTION
## SDL_keyboard.h
The following functions have been renamed:
* SDL_IsScreenKeyboardShown() => SDL_ScreenKeyboardShown()
* SDL_IsTextInputActive() => SDL_TextInputActive()
* SDL_IsTextInputShown() => SDL_TextInputShown()
## SDL_keycode.h
The following symbols have been renamed:
* KMOD_ALT => SDL_KMOD_ALT
* KMOD_CAPS => SDL_KMOD_CAPS
* KMOD_CTRL => SDL_KMOD_CTRL
* KMOD_GUI => SDL_KMOD_GUI
* KMOD_LALT => SDL_KMOD_LALT
* KMOD_LCTRL => SDL_KMOD_LCTRL
* KMOD_LGUI => SDL_KMOD_LGUI
* KMOD_LSHIFT => SDL_KMOD_LSHIFT
* KMOD_MODE => SDL_KMOD_MODE
* KMOD_NONE => SDL_KMOD_NONE
* KMOD_NUM => SDL_KMOD_NUM
* KMOD_RALT => SDL_KMOD_RALT
* KMOD_RCTRL => SDL_KMOD_RCTRL
* KMOD_RESERVED => SDL_KMOD_RESERVED
* KMOD_RGUI => SDL_KMOD_RGUI
* KMOD_RSHIFT => SDL_KMOD_RSHIFT
* KMOD_SCROLL => SDL_KMOD_SCROLL
* KMOD_SHIFT => SDL_KMOD_SHIFT
## SDL_loadso.h
SDL_LoadFunction() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to the appropriate function type. You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.
## SDL_main.h
SDL3 doesn't have a static libSDLmain to link against anymore.
Instead SDL_main.h is now a header-only library **and not included by SDL.h anymore**.
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.
## SDL_mouse.h
SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
SDL_GetMouseState(), SDL_GetGlobalMouseState(), SDL_GetRelativeMouseState(), SDL_WarpMouseInWindow(), and SDL_WarpMouseGlobal() all use floating point mouse positions, to provide sub-pixel precision on platforms that support it.
The following functions have been renamed:
* SDL_FreeCursor() => SDL_DestroyCursor()
## SDL_mutex.h
The following functions have been renamed:
* SDL_CondBroadcast() => SDL_BroadcastCondition()
* SDL_CondSignal() => SDL_SignalCondition()
* SDL_CondWait() => SDL_WaitCondition()
* SDL_CondWaitTimeout() => SDL_WaitConditionTimeout()
* SDL_CreateCond() => SDL_CreateCondition()
* SDL_DestroyCond() => SDL_DestroyCondition()
* SDL_SemPost() => SDL_PostSemaphore()
* SDL_SemTryWait() => SDL_TryWaitSemaphore()
* SDL_SemValue() => SDL_GetSemaphoreValue()
* SDL_SemWait() => SDL_WaitSemaphore()
* SDL_SemWaitTimeout() => SDL_WaitSemaphoreTimeout()
The following symbols have been renamed:
* SDL_cond => SDL_Condition
* SDL_mutex => SDL_Mutex
* SDL_sem => SDL_Semaphore
## SDL_pixels.h
SDL_CalculateGammaRamp has been removed, because SDL_SetWindowGammaRamp has been removed as well due to poor support in modern operating systems (see [SDL_video.h](#sdl_videoh)).
The following functions have been renamed:
* SDL_AllocFormat() => SDL_CreatePixelFormat()
* SDL_AllocPalette() => SDL_CreatePalette()
* SDL_FreeFormat() => SDL_DestroyPixelFormat()
* SDL_FreePalette() => SDL_DestroyPalette()
* SDL_MasksToPixelFormatEnum() => SDL_GetPixelFormatEnumForMasks()
* SDL_PixelFormatEnumToMasks() => SDL_GetMasksForPixelFormatEnum()
The following symbols have been renamed:
* SDL_DISPLAYEVENT_DISCONNECTED => SDL_EVENT_DISPLAY_DISCONNECTED
* SDL_DISPLAYEVENT_MOVED => SDL_EVENT_DISPLAY_MOVED
* SDL_DISPLAYEVENT_ORIENTATION => SDL_EVENT_DISPLAY_ORIENTATION
* SDL_WINDOWEVENT_CLOSE => SDL_EVENT_WINDOW_CLOSE_REQUESTED
* SDL_WINDOWEVENT_DISPLAY_CHANGED => SDL_EVENT_WINDOW_DISPLAY_CHANGED
* SDL_WINDOWEVENT_ENTER => SDL_EVENT_WINDOW_ENTER
* SDL_WINDOWEVENT_EXPOSED => SDL_EVENT_WINDOW_EXPOSED
* SDL_WINDOWEVENT_FOCUS_GAINED => SDL_EVENT_WINDOW_FOCUS_GAINED
* SDL_WINDOWEVENT_FOCUS_LOST => SDL_EVENT_WINDOW_FOCUS_LOST
* SDL_WINDOWEVENT_HIDDEN => SDL_EVENT_WINDOW_HIDDEN
* SDL_WINDOWEVENT_HIT_TEST => SDL_EVENT_WINDOW_HIT_TEST
* SDL_WINDOWEVENT_ICCPROF_CHANGED => SDL_EVENT_WINDOW_ICCPROF_CHANGED
* SDL_WINDOWEVENT_LEAVE => SDL_EVENT_WINDOW_LEAVE
* SDL_WINDOWEVENT_MAXIMIZED => SDL_EVENT_WINDOW_MAXIMIZED
* SDL_WINDOWEVENT_MINIMIZED => SDL_EVENT_WINDOW_MINIMIZED
* SDL_WINDOWEVENT_MOVED => SDL_EVENT_WINDOW_MOVED
* SDL_WINDOWEVENT_RESIZED => SDL_EVENT_WINDOW_RESIZED
* SDL_WINDOWEVENT_RESTORED => SDL_EVENT_WINDOW_RESTORED
* SDL_WINDOWEVENT_SHOWN => SDL_EVENT_WINDOW_SHOWN
* SDL_WINDOWEVENT_SIZE_CHANGED => SDL_EVENT_WINDOW_SIZE_CHANGED
* SDL_WINDOWEVENT_TAKE_FOCUS => SDL_EVENT_WINDOW_TAKE_FOCUS
## SDL_platform.h
The preprocessor symbol `__MACOSX__` has been renamed `__MACOS__`, and `__IPHONEOS__` has been renamed `__IOS__`
## SDL_rect.h
The following functions have been renamed:
* SDL_EncloseFPoints() => SDL_GetRectEnclosingPointsFloat()
* SDL_EnclosePoints() => SDL_GetRectEnclosingPoints()
* SDL_FRectEmpty() => SDL_RectEmptyFloat()
* SDL_FRectEquals() => SDL_RectsEqualFloat()
* SDL_FRectEqualsEpsilon() => SDL_RectsEqualEpsilon()
* SDL_HasIntersection() => SDL_HasRectIntersection()
* SDL_HasIntersectionF() => SDL_HasRectIntersectionFloat()
* SDL_IntersectFRect() => SDL_GetRectIntersectionFloat()
* SDL_IntersectFRectAndLine() => SDL_GetRectAndLineIntersectionFloat()
* SDL_IntersectRect() => SDL_GetRectIntersection()
* SDL_IntersectRectAndLine() => SDL_GetRectAndLineIntersection()
* SDL_PointInFRect() => SDL_PointInRectFloat()
* SDL_RectEquals() => SDL_RectsEqual()
* SDL_UnionFRect() => SDL_GetRectUnionFloat()
* SDL_UnionRect() => SDL_GetRectUnion()
## SDL_render.h
SDL_GetRenderDriverInfo() has been removed, since most of the information it reported were
estimates and could not be accurate before creating a renderer. Often times this function
was used to figure out the index of a driver, so one would call it in a for-loop, looking
for the driver named "opengl" or whatnot. SDL_GetRenderDriver() has been added for this
functionality, which returns only the name of the driver.
Additionally, SDL_CreateRenderer()'s second argument is no longer an integer index, but a
`const char *` representing a renderer's name; if you were just using a for-loop to find
which index is the "opengl" or whatnot driver, you can just pass that string directly
here, now. Passing NULL is the same as passing -1 here in SDL2, to signify you want SDL
to decide for you.
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:
```c
SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED, SDL_SCALEMODE_NEAREST);
```
Mouse and touch events are no longer filtered to change their coordinates, instead you
can call SDL_ConvertEventToRenderCoordinates() to explicitly map event coordinates into
the rendering viewport.
SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SDL_RenderCoordinatesFromWindow() and SDL_RenderCoordinatesToWindow() and take floating point coordinates in both directions.
The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active.
The following functions have been renamed:
* SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize()
* SDL_RenderCopy() => SDL_RenderTexture()
* SDL_RenderCopyEx() => SDL_RenderTextureRotated()
* SDL_RenderCopyExF() => SDL_RenderTextureRotated()
* SDL_RenderCopyF() => SDL_RenderTexture()
* SDL_RenderDrawLine() => SDL_RenderLine()
* SDL_RenderDrawLineF() => SDL_RenderLine()
* SDL_RenderDrawLines() => SDL_RenderLines()
* SDL_RenderDrawLinesF() => SDL_RenderLines()
* SDL_RenderDrawPoint() => SDL_RenderPoint()
* SDL_RenderDrawPointF() => SDL_RenderPoint()
* SDL_RenderDrawPoints() => SDL_RenderPoints()
* SDL_RenderDrawPointsF() => SDL_RenderPoints()
* SDL_RenderDrawRect() => SDL_RenderRect()
* SDL_RenderDrawRectF() => SDL_RenderRect()
* SDL_RenderDrawRects() => SDL_RenderRects()
* SDL_RenderDrawRectsF() => SDL_RenderRects()
* SDL_RenderFillRectF() => SDL_RenderFillRect()
* SDL_RenderFillRectsF() => SDL_RenderFillRects()
* SDL_RenderGetClipRect() => SDL_GetRenderClipRect()
* SDL_RenderGetIntegerScale() => SDL_GetRenderIntegerScale()
* SDL_RenderGetLogicalSize() => SDL_GetRenderLogicalPresentation()
* SDL_RenderGetMetalCommandEncoder() => SDL_GetRenderMetalCommandEncoder()
* SDL_RenderGetMetalLayer() => SDL_GetRenderMetalLayer()
* SDL_RenderGetScale() => SDL_GetRenderScale()
* SDL_RenderGetViewport() => SDL_GetRenderViewport()
* SDL_RenderGetWindow() => SDL_GetRenderWindow()
* SDL_RenderIsClipEnabled() => SDL_RenderClipEnabled()
* SDL_RenderLogicalToWindow() => SDL_RenderCoordinatesToWindow()
* SDL_RenderSetClipRect() => SDL_SetRenderClipRect()
* SDL_RenderSetIntegerScale() => SDL_SetRenderIntegerScale()
* SDL_RenderSetLogicalSize() => SDL_SetRenderLogicalPresentation()
* SDL_RenderSetScale() => SDL_SetRenderScale()
* SDL_RenderSetVSync() => SDL_SetRenderVSync()
* SDL_RenderSetViewport() => SDL_SetRenderViewport()
* SDL_RenderWindowToLogical() => SDL_RenderCoordinatesFromWindow()
The following functions have been removed:
* SDL_RenderGetIntegerScale()
* SDL_RenderSetIntegerScale() - this is now explicit with SDL_LOGICAL_PRESENTATION_INTEGER_SCALE
* SDL_RenderTargetSupported() - render targets are always supported
The following symbols have been renamed:
* SDL_ScaleModeBest => SDL_SCALEMODE_BEST
* SDL_ScaleModeLinear => SDL_SCALEMODE_LINEAR
* SDL_ScaleModeNearest => SDL_SCALEMODE_NEAREST
## SDL_rwops.h
The following symbols have been renamed:
* RW_SEEK_CUR => SDL_RW_SEEK_CUR
* RW_SEEK_END => SDL_RW_SEEK_END
* RW_SEEK_SET => SDL_RW_SEEK_SET
SDL_RWread and SDL_RWwrite (and SDL_RWops::read, SDL_RWops::write) have a different function signature in SDL3.
Previously they looked more like stdio:
```c
size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum);
size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum);
```
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);
```
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);
}
```
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;
}
return (size_t)(amount / size);
}
```
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:
```c
#include <stdio.h>
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;
switch (whence) {
case SDL_RW_SEEK_SET:
stdiowhence = SEEK_SET;
break;
case SDL_RW_SEEK_CUR:
stdiowhence = SEEK_CUR;
break;
case SDL_RW_SEEK_END:
stdiowhence = SEEK_END;
break;
default:
return SDL_SetError("Unknown value for 'whence'");
}
if (fseek((FILE *)context->hidden.stdio.fp, (fseek_off_t)offset, stdiowhence) == 0) {
Sint64 pos = ftell((FILE *)context->hidden.stdio.fp);
if (pos < 0) {
return SDL_SetError("Couldn't get stream offset");
}
return pos;
}
return SDL_Error(SDL_EFSEEK);
}
static Sint64 SDLCALL
stdio_read(SDL_RWops * context, void *ptr, Sint64 size)
{
size_t nread;
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);
}
return (Sint64) nread;
}
static Sint64 SDLCALL
stdio_write(SDL_RWops * context, const void *ptr, Sint64 size)
{
size_t nwrote;
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);
}
return (Sint64) nwrote;
}
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);
}
}
SDL_DestroyRW(context);
}
return status;
}
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;
rwops->close = stdio_close;
rwops->hidden.stdio.fp = fp;
rwops->hidden.stdio.autoclose = autoclose;
rwops->type = SDL_RWOPS_STDFILE;
}
return rwops;
}
```
The following functions have been renamed:
* SDL_AllocRW() => SDL_CreateRW()
* SDL_FreeRW() => SDL_DestroyRW()
## SDL_sensor.h
SDL_SensorID has changed from Sint32 to Uint32, with an invalid ID being 0.
Rather than iterating over sensors using device index, there is a new function SDL_GetSensors() to get the current list of sensors, and new functions to get information about sensors from their instance ID:
```c
{
if (SDL_InitSubSystem(SDL_INIT_SENSOR) == 0) {
int i, num_sensors;
SDL_SensorID *sensors = SDL_GetSensors(&num_sensors);
if (sensors) {
for (i = 0; i < num_sensors; ++i) {
SDL_Log("Sensor %" SDL_PRIu32 ": %s, type %d, platform type %d\n",
sensors[i],
SDL_GetSensorInstanceName(sensors[i]),
SDL_GetSensorInstanceType(sensors[i]),
SDL_GetSensorInstanceNonPortableType(sensors[i]));
}
SDL_free(sensors);
}
SDL_QuitSubSystem(SDL_INIT_SENSOR);
}
}
```
Removed SDL_SensorGetDataWithTimestamp(), if you want timestamps for the sensor data, you should use the sensor_timestamp member of SDL_EVENT_SENSOR_UPDATE events.
The following functions have been renamed:
* SDL_SensorClose() => SDL_CloseSensor()
* SDL_SensorFromInstanceID() => SDL_GetSensorFromInstanceID()
* SDL_SensorGetData() => SDL_GetSensorData()
* SDL_SensorGetInstanceID() => SDL_GetSensorInstanceID()
* SDL_SensorGetName() => SDL_GetSensorName()
* SDL_SensorGetNonPortableType() => SDL_GetSensorNonPortableType()
* SDL_SensorGetType() => SDL_GetSensorType()
* SDL_SensorOpen() => SDL_OpenSensor()
* SDL_SensorUpdate() => SDL_UpdateSensors()
The following functions have been removed:
* SDL_LockSensors()
* SDL_NumSensors() - replaced with SDL_GetSensors()
* SDL_SensorGetDeviceInstanceID()
* SDL_SensorGetDeviceName() - replaced with SDL_GetSensorInstanceName()
* SDL_SensorGetDeviceNonPortableType() - replaced with SDL_GetSensorInstanceNonPortableType()
* SDL_SensorGetDeviceType() - replaced with SDL_GetSensorInstanceType()
* SDL_UnlockSensors()
## SDL_stdinc.h
The standard C headers like stdio.h and stdlib.h are no longer included, you should include them directly in your project if you use non-SDL C runtime functions.
M_PI is no longer defined in SDL_stdinc.h, you can use the new symbols SDL_PI_D (double) and SDL_PI_F (float) instead.
The following functions have been renamed:
* SDL_strtokr() => SDL_strtok_r()
## SDL_surface.h
Removed unused 'flags' parameter from SDL_ConvertSurface and SDL_ConvertSurfaceFormat.
SDL_CreateRGBSurface() and SDL_CreateRGBSurfaceWithFormat() have been combined into a new function SDL_CreateSurface().
SDL_CreateRGBSurfaceFrom() and SDL_CreateRGBSurfaceWithFormatFrom() have been combined into a new function SDL_CreateSurfaceFrom().
You can implement the old functions in your own code easily:
```c
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
return SDL_CreateSurface(width, height,
SDL_GetPixelFormatEnumForMasks(depth, Rmask, Gmask, Bmask, Amask));
}
SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
{
return SDL_CreateSurface(width, height, format);
}
SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
return SDL_CreateSurfaceFrom(pixels, width, height, pitch,
SDL_GetPixelFormatEnumForMasks(depth, Rmask, Gmask, Bmask, Amask));
}
SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
{
return SDL_CreateSurfaceFrom(pixels, width, height, pitch, format);
}
```
But if you're migrating your code which uses masks, you probably have a format in mind, possibly one of these:
```c
// Various mask (R, G, B, A) and their corresponding format:
0xFF000000 0x00FF0000 0x0000FF00 0x000000FF => SDL_PIXELFORMAT_RGBA8888
0x00FF0000 0x0000FF00 0x000000FF 0xFF000000 => SDL_PIXELFORMAT_ARGB8888
0x0000FF00 0x00FF0000 0xFF000000 0x000000FF => SDL_PIXELFORMAT_BGRA8888
0x000000FF 0x0000FF00 0x00FF0000 0xFF000000 => SDL_PIXELFORMAT_ABGR8888
0x0000F800 0x000007E0 0x0000001F 0x00000000 => SDL_PIXELFORMAT_RGB565
```
The following functions have been renamed:
* SDL_FillRect() => SDL_FillSurfaceRect()