Compare commits

..
142 Commits
Author SHA1 Message Date
Sam Lantinga d9836d15e7 Lock joysticks when they are connected/disconnected on emscripten
Fixes https://github.com/libsdl-org/SDL/issues/11499

(cherry picked from commit 0281071243)
2025-12-08 21:00:22 -08:00
Cameron Gutman 3146374e4a egl: Fix X11 EGL window creation on Nvidia
This is a port of 808a3f5 to SDL2.

Fixes #13094
2025-12-05 23:51:56 -05:00
Cameron Gutman 1d852d1c28 quit: don't call signal() if we're using sigaction()
At best, this is a no-op.

At worst, it might:
 - Clobber a signal handler someone registered after us
 - Overwrite the signal mask or flags
 - Cause unregistration to fail (sigaction() isn't guaranteed to return the exact pointer passed to signal())
2025-12-01 18:56:12 -06:00
Sam Lantinga 6ad5a966ea Revert "Use DefWindowProc for the initial SDL window proc"
This reverts commit afeeef9cf5.
2025-11-24 19:06:13 -08:00
Anonymous MaartenandSam Lantinga a65111bd2d Add SDL_(Get|Set)ClipRect automation test
Co-authored-by: Sam Lantinga <slouken@libsdl.org>
2025-11-22 10:43:46 +00:00
yuanhecai c44d37b5cf loongarch: Switch to software render when using LG100 series 2025-11-14 07:14:48 -08:00
Sam Lantinga f36d683b61 Check for wine_get_version() to detect Wine/Proton
If this application is being run under Wine but Steam doesn't know that, Steam won't set STEAM_COMPAT_PROTON. So we'll use wine_get_version() to detect that we're running under Wine instead.

(cherry picked from commit e2e8f86076)
2025-11-12 23:07:51 -08:00
Sam Lantinga 5bdf7bc625 Don't check SteamVirtualGamepadInfo when running as Wine
Wine will ignore the Steam Virtual Gamepad if it looks like it has the original (blocked) controller VID/PID.

Fixes https://github.com/libsdl-org/SDL/issues/14410

(cherry picked from commit 493bc621e4)
2025-11-12 23:07:51 -08:00
Petar Popovic 38e0094637 Fix uninitialized variable warning when compiling tests with clang compiler 2025-11-07 07:56:26 -08:00
Ozkan Sezer ba38fda752 Revert "pipewire: disable -Wdeclaration-after-statement for pipewire headers"
This reverts commit f9435eab16.

Issue in pipewire release candidate 1.5.81 has been resolved in 1.5.82

Reference issue: Fixes: https://github.com/libsdl-org/SDL/issues/14343
2025-11-06 19:55:02 +03:00
yuanhecai 14eebdab3c loongarch: add SDL_FillRect4LSX opt 2025-11-06 07:27:56 -08:00
yuanhecai 686c18026b loongarch: add BlitRGBtoRGBPixelAlphaLSX opt 2025-11-06 07:27:56 -08:00
Sam Lantinga 6db23faa44 Clamp the audio drain delay to 100 ms
Fixes https://github.com/libsdl-org/SDL/issues/9829

(cherry picked from commit 0882623092)
2025-11-02 11:20:39 -08:00
Sam Lantinga 6570d9e23f Don't consider USB devices which have already been skipped
Fixes https://github.com/libsdl-org/SDL/issues/14367
2025-11-02 09:25:13 -08:00
Sam Lantinga 2bb0eb4641 Fixed the right touchpad calculation for the BLE Steam Controller
Fixes https://github.com/libsdl-org/SDL/issues/14368

(cherry picked from commit eb87a36940)
2025-11-02 08:34:16 -08:00
Sam Lantinga afeeef9cf5 Use DefWindowProc for the initial SDL window proc
This makes sure that anything that hooks window creation to set up window proc hooks will call DefWindowProc instead of infinitely recursing when we set up our window proc afterwards.

Fixes https://github.com/libsdl-org/SDL/issues/10529

(cherry picked from commit 6c4f2bd83d)
2025-11-02 07:24:54 -08:00
Petar Popovic 398bacbac3 Fix leak in SDL_GameControllerTypeForIndex() 2025-11-01 08:40:12 -07:00
Ozkan Sezer f9435eab16 pipewire: disable -Wdeclaration-after-statement for pipewire headers
Fixes: https://github.com/libsdl-org/SDL/issues/14343
2025-11-01 00:45:10 +03:00
Sam Lantinga 66ac6f4ea7 Revert "Remove special-case Xbox 360 wireless controller mappings"
This reverts commit 4151df83fe.
2025-10-27 17:37:43 -07:00
Dave Wickham 4151df83fe Remove special-case Xbox 360 wireless controller mappings
Effectively https://github.com/libsdl-org/SDL/pull/14339 for SDL2
Fixes https://github.com/libsdl-org/SDL/issues/14324
2025-10-27 08:56:00 -07:00
Ozkan Sezer 00d4f1c2c4 SDL_kmsdrmvideo.c: fix build in C90 mode 2025-10-26 04:35:20 +03:00
Sam Lantinga 1c19bee000 Perform full rectangle intersection for empty rects
If we don't do that, we leave the x and y values uninitialized.

Fixes https://github.com/libsdl-org/sdl12-compat/issues/365

(cherry picked from commit ffd0ca4391)
2025-10-25 13:51:58 -07:00
danprice142 639c7a1e52 Sdl2 Add support for launchOnExit URI for WinRT
Implements extraction and launching of a 'launchOnExit' URI parameter from protocol activation in SDL_WinRTApp. The URI is stored and launched on app exit, suspension, or window close, enabling return-to-caller scenarios for protocol-activated apps.
2025-10-25 08:13:45 -07:00
Ozkan Sezer c9889fb013 updated dynapi after latest api addition 2025-10-24 21:11:50 +03:00
SDL Wiki Bot 1edb3283b0 Sync SDL2 wiki -> header
[ci skip]
2025-10-24 17:35:46 +00:00
danprice142 3e1cebed3c Add protocol activation URI support for WinRT (#14309) 2025-10-24 10:34:44 -07:00
SDL Wiki Bot 66d87bf0e1 Sync SDL2 wiki -> header
[ci skip]
2025-10-13 06:06:49 +00:00
Frank Praznik 235e4870af wayland: Special-case relative warp mode to deliver accelerated relative motion
The Wayland backend lacks pointer warp functionality, so special-case the relative warp mode hint to deliver accelerated relative motion deltas, which is ultimately what the client wants by enabling this hint.
2025-10-09 11:19:27 -04:00
AL2009man 8ef0a07a52 Disable SDL_HINT_JOYSTICK_RAWINPUT by default
backported from SDL3 commit aa870d5

 Fixes #13047
2025-10-08 11:34:55 -07:00
Ozkan Sezer 26d1eadda3 ci: bump cross-platform-actions.
(cherry-picked from commit 97c1df66a8)
2025-10-07 14:28:10 +03:00
Wohlstand 39a0fab4d7 SDL2: PSP: Fixed render-to-texture larger than screen
I found if I try to make texture bigger than screen and use it as a frame buffer, it gets cuts of content. To ensure that render will be valid, I making sure scissors were initialised properly.

P.S. This works on hardware, however, emulator PPSSPP seems has a bug in this case, so I going to report that and making the simple demo.
2025-09-29 19:10:12 -07:00
Wohlstand 67141e5079 SDL_render_psp.c: Implemented working viewport support
Since it's no known way to use genuine viewport with PSP SDK, I implemented the workaround using manually added/subtracted offsets to vertices passing to the render API. To assign viewport and cliprect in valid way, I copied part of code from the Vita's module and adjusted it to work on PSP.
2025-09-29 19:10:12 -07:00
Brad Smith 641201a99a Use elf_aux_info() on OpenBSD
NFC for ARMv7. For PowerPC move elf_aux_info() to higher priority over
sysctl for newer systems.

(cherry picked from commit b299e0de46)
2025-09-27 09:01:04 -07:00
Fierelier 7b28fb29bd [SDL3] [PS2] Framebuffer resolution + 240p/480p + PAL support (#13993)
* Do not override NTSC/PAL

* Fix PS2 build instructions

* Add PS2 GS hints
Allows for switching between NTSC/PAL, progressive/interlaced, etc

(cherry picked from commit 3fd0b46215)
2025-09-26 07:46:13 -07:00
Sam Lantinga ecb72142fd Removed UWP workflow from CI
The GitHub runners no longer have the needed SDK for this
2025-09-19 08:33:00 -07:00
krnl32 9859c05178 Added a default case to the switch statement in the HEADER FILE to prevent compiler warnings about missing defaults. This change helps avoid compilation breaks when warnings are treated as errors. 2025-09-16 17:16:50 -07:00
Ozkan Sezer 07c3b3fb7c fix build. 2025-09-15 20:29:50 +03:00
Ozkan Sezer 9343246616 SDL_endian.h: don't add _m_prefetch hack for clang-cl if available as a builtin
Fixes: https://github.com/libsdl-org/SDL/issues/13952 .

(backport from SDL3 commit 81f2f44843)
2025-09-15 20:10:50 +03:00
Sam Lantinga b55059b487 Remove Windows 32-bit ARM build from CI
This architecture is deprecated and is now failing with:
Windows SDK 10.0.22621.0 : 'C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\um' not found or was incomplete

Fixes https://github.com/libsdl-org/SDL/issues/13949

(cherry picked from commit cc3274b6f1)
2025-09-14 18:03:17 -07:00
Sam Lantinga 55b599d693 Only use a transparent cursor on Windows when connected via RDP
VMware relies on the cursor being set to NULL to optimize relative mouse motion for games.

We should also revisit whether current RDP works better with a NULL cursor or a transparent cursor.

Fixes https://github.com/libsdl-org/SDL/issues/13700

(cherry picked from commit dac6af4ba6)
2025-09-14 17:31:32 -07:00
Wes Lord 2eb5bff91a Add missing parameters and return types to SDL2 header docs (#13162) 2025-09-13 07:37:33 -07:00
Gianfranco Berardi be6ab7f9a6 Provide Android targetsdk 35 support in SDL2 (#13776) 2025-09-13 07:17:28 -07:00
Joshua Root eb974470ec Guard use of @available in SDL_cocoaevents.m
Older compilers don't understand this syntax.
2025-09-07 16:46:19 -07:00
Ozkan Sezer f0e7000f92 alsa: fix signatures of snd_pcm_info_free and snd_pcm_hw_params_get_rate
Reference issue: https://github.com/libsdl-org/SDL/issues/13845.
2025-09-02 17:02:32 +03:00
Ozkan Sezer d2ab01b8bb openslES: really fix build.. 2025-09-01 20:38:37 +03:00
Ozkan Sezer f5246d0181 openslES: fix build 2025-09-01 20:25:28 +03:00
Ryan C. Gordon b8c802632b openslES: OpenSL ES on Android only supports two formats, limit to that.
(Three with the floating point extension, which we use.)

This is according to:

https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android

Previously, this would accept a request for Sint8 or Sint32 and disaster
would ensue.

Fixes #13779.

(cherry picked from commit 0b2a003a35)
(cherry picked from commit 7323104f97)
2025-09-01 11:37:10 -04:00
Ozkan Sezer 1725d6b049 regenerate configure script. 2025-08-31 20:20:04 +03:00
Gleb Mazovetskiy 5ed21d1ccb configure.ac: Fix AC_DEFINE HAVE_LIBUSB
Fixes an error with autoconf 2.72
2025-08-31 09:36:24 -07:00
Ozkan Sezer 7a34e14c8e SDL_hidapi.c: fix -Wundef failures due to HAVE_DRIVER_BACKEND check 2025-08-30 14:33:32 +03:00
Ozkan Sezer 1a8e667f3d CI: add OpenBSD workflow
(backported from commit c0e5fd55d2)
2025-08-30 14:23:40 +03:00
Frank Praznik d31d98d436 wayland: Add a sigtimedwait() implementation for OpenBSD
sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it. Add a replacement implementation based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation

(backported from commit 1049426a76)
2025-08-30 14:23:04 +03:00
Ozkan Sezer 56d43ee296 update config.guess and config.sub from git://git.sv.gnu.org/config.git 2025-08-28 11:22:50 +03:00
Chase Knowlden 1f21aae242 Update NDK version to 28 (#13729)
* Update NDK version to 28 and add 16kb page size linker flags to x86_64

* Remove Android Linker Options

16kb page size is now the default since NDK r28c

* Update Android CI to use NDK 28

(cherry picked from commit 6e422e5ff2)
2025-08-13 15:13:18 +02:00
Sam Lantinga 5e85a29e75 Support the "ambient" value for SDL_HINT_AUDIO_CATEGORY
Fixes https://github.com/libsdl-org/SDL/issues/13732

(cherry picked from commit 4725213eef)
2025-08-12 09:54:57 -07:00
Anonymous Maarten f201b64ffe release: build aarch64 libraries with 16kiB page size 2025-08-09 05:25:31 +02:00
Sam Lantinga 4f9723ece7 Revert "autotools, android: Support Google Play 16 KB Page Size Requirement"
This reverts commit e7489a0931.

If you need to support the Google Play 16 kiB page size requirement, the recommendation is to use NDK r28c or newer, which automatically aligns binaries correctly.
2025-08-07 11:38:29 -07:00
Sam Lantinga 53dbe1862e Revert "Support Google Play 16 KB Page Size Requirement (#13470)"
This reverts commit 4b2aa3f102.

If you need to support the Google Play 16 kiB page size requirement, the recommendation is to use NDK r28c or newer, which automatically aligns binaries correctly.
2025-08-07 11:38:24 -07:00
Ozkan Sezer e7489a0931 autotools, android: Support Google Play 16 KB Page Size Requirement
autotools port of commit 4b2aa3f102.
2025-08-07 20:10:02 +03:00
Anonymous Maarten 4b2aa3f102 Support Google Play 16 KB Page Size Requirement (#13470)
- See: https://developer.android.com/guide/practices/page-sizes#update-packaging
- Also, make min API uniform at 21 (from 16 and 23 in a few places)

Manual backport of dc2c83c383
2025-08-07 17:59:05 +02:00
Ryan C. Gordon 272b073323 SDL_enabled_assert(): Use NULL istead of 0 to explicity initialize the pointer members of SDL_AssertData
(cherry picked from commit faf3bd9991)
2025-08-03 13:40:12 -04:00
SDL Wiki Bot d310b5679f Sync SDL2 wiki -> header
[ci skip]
2025-07-30 03:15:25 +00:00
Ryan C. Gordon afc1d9122b pipewire: Report correct device default formats instead of hardcoding Float32.
The comment in the source wasn't true; PipeWire doesn't _have_ to work in
float format. It presumably does if it has to mix, but if a game is the only
thing making noise on the system--a common scenario--then it might be able to
pass, say, Sint16 data straight through to the hardware without conversion.

Fixes #12129.

(cherry picked from commit 943c4abcb4)
2025-07-29 18:21:01 -04:00
Sam Lantinga af2279b286 Revert "Use SDL_MessageBoxFlags and SDL_MessageBoxButtonFlags appropriately"
This reverts commit 059af5265a.
2025-07-29 09:41:35 -07:00
Sam Lantinga 059af5265a Use SDL_MessageBoxFlags and SDL_MessageBoxButtonFlags appropriately
(cherry picked from commit 991d28ae37)
2025-07-29 09:38:52 -07:00
Dan Andrus e610529e84 Check NSWindow::isVisible before sending SDL_WINDOWEVENT_RESTORED during Cocoa_WindowListener::windowDidResize 2025-07-28 14:46:55 -04:00
Ozkan Sezer 74df61530f autotools, cmake: fix the sys/audioio.h checks.
Reference issue: https://github.com/libsdl-org/SDL/issues/13405.
2025-07-28 12:40:30 +03:00
Boris I. Bendovsky 3c36718348 [SDL2] Implement SDL_GL_GetAttribute for SDL_GL_FLOATBUFFERS 2025-07-27 19:55:57 -07:00
Anonymous Maarten b36252b120 ci+n3ds: avoid apt-get package manager
- use Unix Makefiles (with parallelization) CMake generator
- use binutils strings binary from devkitpro

( Manual backport of commit e6d200e51c )
2025-07-27 23:50:02 +03:00
Ozkan Sezer ead4a032d3 sun audio: remove ifdefs, always include sys/audioio.h and sys/ioctl.h 2025-07-27 00:10:02 +03:00
Ryan C. Gordon cf1eb95fb1 sunaudio: don't compile in the sun audio backend if sys/audioio.h is missing.
Newer Solaris-based releases, like OpenIndiana, don't include this, using
Open Sound System, or something layered over OSS like PulseAudio, instead.

Fixes #13405.
2025-07-26 13:50:20 -04:00
vanfanel 34691de22b SDL2: Fill the SDL_AudioSpec in add_device() 2025-07-20 23:47:25 -04:00
vanfanel 874ca5a678 SDL2: Add missing symbol loading for SDL_GetDefaultAudioInfo() implementation on ALSA. 2025-07-17 13:08:52 -04:00
vanfanel 8d5984464e SDL2: Implement SDL_GetDefaultAudioInfo() on the ALSA backend. 2025-07-17 13:08:52 -04:00
Ryan C. Gordon 2a6baf50e9 include: Added some basic documentation so SDL_KeyCode shows up on the wiki.
Fixes #11525.
2025-07-14 00:33:32 -04:00
Yorick Reum 6c9c2a9ac2 Xcode-iOS/Demos/src/fireworks.c: Make rendering CPU efficient 2025-07-12 07:35:08 -07:00
Anonymous Maarten 8605624158 ci: build MSVC release binary on windows-2025 2025-07-12 13:08:31 +02:00
Ryan C. Gordon b537380065 cocoa: Patched to compile. 2025-07-10 16:27:47 -04:00
Ryan C. Gordon b2c3e6fade cocoa: Don't use trick of briefly focusing the Dock on newer macOS releases.
On newer systems, the trick isn't necessary, and if you do it, if the user is
moving the mouse when launching the app, it'll show a hidden Dock.

Fixes #10340.

(manually backported from SDL3 from commit 279dabfc96)
2025-07-10 15:57:55 -04:00
Wouter Wijsman 309d1481a4 PSP: Truncate thread name when passing to sceKernelCreateThread 2025-07-09 17:11:32 +02:00
Ozkan Sezer 2fb6abb9ad fix ARM64 linkage with Visual Studio >= 17.14 when SDL_LIBC is disabled
Reference issue:  https://github.com/libsdl-org/SDL/issues/13254
2025-07-08 14:50:10 +03:00
Ryan C. Gordon cd0cf8b855 SDL_audio.h: tweak SDL_OpenAudioDevice() docs to fix a weird wordwrap issue.
Fixes https://github.com/libsdl-org/sdlwiki/pull/816.

("Fixes.")
2025-07-01 13:38:16 -04:00
evgenydrainov 2bc3ec44b1 keyboard: Add reference to SDL_Keymod in the comments 2025-06-24 07:36:22 -07:00
Mitch Cairns e4475d1868 Fixed Nintendo Switch thumbstick calibration
(cherry picked from commit 3a6f9e01f8)
2025-06-22 15:29:12 -07:00
Sam Lantinga 6a71328638 Fixed Nintendo Switch Pro thumbstick calibration
Fixes https://github.com/libsdl-org/SDL/issues/13246

(cherry picked from commit 038a3806eb)
2025-06-21 20:06:08 -07:00
Wohlstand 6701f938f7 Vita Render: Limit the scope of cliprect to viewport
Don't allow cliprect be larger than viewport's scope
2025-06-20 13:15:57 -07:00
Wohlstand 1c09a7117a Vita: Fixed absence of clipping when viewport is set
#13034
2025-06-20 13:15:57 -07:00
ceski 9eb50a906a Read Switch controller gyro/accel sensitivity coeffs (SDL2)
These vary by controller, so using the stored values should improve the accuracy of the sensor data.
2025-06-13 12:18:12 -07:00
SDL Wiki Bot 027d46f03a Sync SDL2 wiki -> header
[ci skip]
2025-06-13 17:09:05 +00:00
Son Phan Trung 3416296366 README-touch.md: fix header separators 2025-06-06 08:28:10 -07:00
Wes Lord 01c3ccd541 Move comment in .wikiheaders-options to own line
Was not parsing correctly, causing an error
2025-06-02 07:21:42 -04:00
Ryan C. Gordon 3c08172d06 Revert "opengles2: Restore previous default texture_formats."
This reverts commit 9f7ccbe8d4.

Fixes #13109.
2025-06-01 03:21:36 -04:00
Francisco Javier Trujillo Mata d0c2d8bc40 Fix wrong callback type
(cherry picked from commit c89357bf60)
2025-05-20 11:11:47 -07:00
Sam Lantinga 33eb167da8 Fixed rare crash trying to interrupt SDL_WaitEvent()
Fixes https://github.com/libsdl-org/SDL/issues/12797

(cherry picked from commit 992e4c59bd)
2025-05-19 14:24:26 -07:00
Joe [ReRezd] 4b4f6b3e22 Fix: GameCube controller adapter hotplug not working
SDL_PrivateJoystickAdded was called before setting the InstanceId in the adapters ctx->joysticks array.  This would eventually broadcast the SDL_EVENT_JOYSTICK_ADDED event with the new InstanceId, if your program listens for the added events and opens joysticks at that point it would always fail because there would be no matching InstanceId in the ctx->joysticks array.

(cherry picked from commit afd1e51023)
2025-05-19 08:26:25 -07:00
Sam Lantinga 2163887f29 Define illegal_instruction() when it will be actually used
(cherry picked from commit 29d2116495)
2025-05-08 12:53:33 -07:00
Sam Clegg c0f78dee5e [emscripten] Remove reference to Module['createContext']
Backported from https://github.com/libsdl-org/SDL/pull/12970
2025-05-06 14:46:19 -07:00
A. Wilcox 17e6208c1b cpuinfo: Use auxv for AltiVec on Linux if possible
The SIGILL handler is not very reliable and can cause crashes.

Linux provides the CPU's AltiVec support status in getauxval.

(cherry picked from commit 7490471796)
2025-05-04 13:55:59 -07:00
Ozkan Sezer 157f894d5d don't prototype strdup() for __clang_analyzer__ case in windows builds.
Fixes:  https://github.com/libsdl-org/SDL/issues/12948.
(cherry picked from commit 17bba029ba)
2025-05-04 20:47:28 +03:00
Derek Schuff a220e7c422 Port #12581 to SDL2
This fixes undefined behavior resulting from adding offsets to nullptr.
2025-05-01 21:36:23 -07:00
Sam Lantinga 2442c85cb8 Call IOHIDDeviceClose() if needed in hid_close() on macOS
Unregistering the input report callback marks the device as disconnected, so IOHIDDeviceClose() would never be called if the device wasn't already disconnected  when hid_close() was called.

Fixes https://github.com/libsdl-org/SDL/issues/12255
2025-04-29 11:21:26 -07:00
Sam Lantinga 5b951141d2 Revert "Don't leak device handle in macOS 10.10 or newer"
This reverts commit 5925c27efb.

Fixes https://github.com/libsdl-org/SDL/issues/12807
2025-04-29 11:07:29 -07:00
Cameron Gutman 15fd3fcdc2 events: Fix undefined behavior when disabling some event types
Shifting a signed int left by 31 is UB.
2025-04-29 00:30:41 -05:00
Sam Lantinga 45b01d16b1 Fixed reliability of initializing Switch controllers on macOS
It looks like both macOS (15.1.1) and SDL are trying to talk to the controller at the same time, which can cause interleaved replies or even locking up the controller. Waiting a bit before talking to the controller seems to take care of this.
2025-04-28 20:21:53 -07:00
SternXD 433810c58d SDL2: Update from Visual Studio 2019 to Visual Studio 2022 2025-04-22 20:59:26 -07:00
SDL Wiki Bot 916ddb1ef8 Sync SDL2 wiki -> header
[ci skip]
2025-04-22 21:18:56 +00:00
Sam Lantinga 1c75cb4f8a Revert "Sync SDL2 wiki -> header"
This reverts commit 26e946ef08.

Stop it Skynet!
2025-04-22 14:17:22 -07:00
SDL Wiki Bot 26e946ef08 Sync SDL2 wiki -> header
[ci skip]
2025-04-22 17:22:42 +00:00
Petar Popovic 035518d065 SDL_BlitSurface() comment: only dstrect is modified in function 2025-04-22 10:22:27 -07:00
Boris I. Bendovsky 40b1eac541 [SDL2] Fix using of DXSDK_DIR in older CMake
- Remove duplicate 'dollar' symbol in the path
- Use command 'file' to normalize file paths
2025-04-22 10:12:01 -07:00
Ozkan Sezer bfab0a968f SDL_cpuinfo.h: only include immintrin.h for x86 targets.
Reference issue: https://github.com/libsdl-org/SDL_image/issues/537
Reference issue: https://github.com/libsdl-org/SDL_mixer/issues/648
2025-04-03 18:55:04 +03:00
Sam Lantinga f0a8e09f7c Skip the Jack audio server test
The Jack server might not be running even though the libraries are installed.
2025-03-30 21:31:38 -07:00
SDL Wiki Bot 2e4c12cd2c Sync SDL2 wiki -> header
[ci skip]
2025-03-27 19:20:39 +00:00
Sam Lantinga 3e47181800 Default SDL_HINT_ACCELEROMETER_AS_JOYSTICK to 0 on Linux
The Linux joystick driver supports associating sensor devices with the related controller device, so enable that by default.

Fixes https://github.com/libsdl-org/SDL/issues/12043
2025-03-25 09:07:10 -07:00
Anonymous Maarten 8436ce98b4 tests: port failing SDL_Renderer test from pysdl2 to testautomation 2025-03-21 00:55:52 +01:00
Carl Åstholm a8f0eb4c33 emscripten: Don't use legacy JS library functions for assertions
(cherry picked from commit 54f5b73333)
2025-03-20 16:36:02 -07:00
Anonymous Maarten 069eb012aa tests: port failing SDL subsystem test from pysdl2 to testautomation 2025-03-20 20:30:18 +01:00
Anonymous Maarten 7d8a6f1603 tests: port failing SDL_Renderer test from pysdl2 to testautomation 2025-03-20 20:30:18 +01:00
Dragon-Baroque d63b3376a4 The posix4 library has been merged into the libc library
Backported from commit 07e4dea693.
Reference issue: https://github.com/libsdl-org/SDL/issues/12588.
2025-03-20 09:47:20 +03:00
Sam Lantinga 52146cf067 Fixed raw input device GUIDs changing randomly between runs
On Windows 11, apparently HidD_GetManufacturerString() and HidD_GetProductString() can return TRUE without actually filling in any string data.

Fixes https://github.com/libsdl-org/SDL/issues/12566

(cherry picked from commit 4fc9509ab7)
2025-03-17 13:57:35 -07:00
Sam Lantinga 46a51b4298 Fixed crash if info->path is NULL
(cherry picked from commit 715301cef5)
2025-03-17 09:47:53 -07:00
Anonymous Maarten 4f488b9be2 tests: port failing window test from pysdl2 to testautomation 2025-03-16 18:15:16 -07:00
Anonymous Maarten f48a96a976 test: actually run rect tests 2025-03-14 21:40:31 +01:00
Anonymous Maarten 39bb71c442 tests: port failing SDL_Rect tests from pysdl2 to testautomation 2025-03-14 17:29:27 +01:00
Anonymous Maarten 177fb9cb6c tests: port failing SDL_Hint tests from pysdl2 to testautomation 2025-03-14 17:29:27 +01:00
SDL Wiki Bot fc536dcb7e Sync SDL2 wiki -> header
[ci skip]
2025-03-12 19:23:45 +00:00
Sam Lantinga 1caae3e9e4 Fixed sscanf("026", "%1x%1x%1x", &r, &g, &b)
Fixes https://github.com/libsdl-org/SDL/issues/12510

(cherry picked from commit be6ed6e9c4)
2025-03-10 15:45:31 -07:00
SDL Wiki Bot 22a87a22ca Sync SDL2 wiki -> header
[ci skip]
2025-03-07 17:02:06 +00:00
Neal Gompa 6be87ceb33 pipewire: Ensure that the correct struct is used for enumeration APIs
PipeWire now requires the correct struct type is used, otherwise
it will fail to compile.

Reference: https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/188d920733f0791413d3386e5536ee7377f71b2f

Fixes: https://github.com/libsdl-org/SDL/issues/12224
(cherry picked from commit d35bef64e9)
2025-03-06 14:36:44 -05:00
Sam Lantinga ab44451578 Added support for the "%n" sscanf format specifier
(cherry picked from commit 6980325310)
2025-02-25 08:07:33 -08:00
SDL Wiki Bot 52ac07d327 Sync SDL2 wiki -> header
[ci skip]
2025-02-25 15:55:15 +00:00
Tomasz Pakuła 0809be4ec5 [SDL2] Add SDL_HINT_JOYSTICK_HAPTIC_AXES
Allows users to overwrite the number of haptic axes defined for a given
joystick. Also supports a "wildcard" VID:PID of 0xFFFF/0xFFFF
2025-02-25 07:54:59 -08:00
Petter Reinholdtsen 24693ac285 Changed PULSEAUDIO_FlushRecording() to only flush audio present when called.
When the flushing is not able to keep up with the audio stream coming in,
it will end up flushing forever and block API clients from getting any audio.

Fixes #9706
2025-02-24 07:31:06 -08:00
Cameron Gutman 92cadaf917 keyboard: Fix comment regarding implicit calls to SDL_StartTextInput()
It was always done inside SDL_VideoInit().
2025-02-23 19:00:32 -06:00
Anonymous Maarten d2eb72fd14 ci: drop classic Intel compiler
1) The classic Intel compiler is depreated in favor of the oneapi compiler
2) SPA_FALLTHROUGH is used in pipewire's spa/utils/json.h, and causes build errors
2025-02-23 21:26:10 +01:00
Anonymous Maarten b4d733619a ci: GitHub is retiring Ubuntu 20.04 support
backport of 8d3db06ff2
2025-02-23 19:45:27 +01:00
Anonymous Maarten ed2c004c8a ci: clang32 on msys2 is EOL
backport of 70f657e520
2025-02-23 19:40:38 +01:00
Paper 6421f12d7f thread/windows: fix stack overflow in exception naming
(cherry picked from commit 1a853973ab)
2025-02-20 08:20:41 -08:00
Ozkan Sezer ee49025f80 dynapi: use DosScanEnv() for os/2. 2025-02-20 11:50:04 +03:00
Sam Lantinga 5925c27efb Don't leak device handle in macOS 10.10 or newer
Merged upstream fix for macOS:
https://github.com/libusb/hidapi/commit/cdc473dfe43f6432dda7ad53d7656b8ae8ff968b

In one of the early versions of macOS, when you try to close the device
with IOHIDDeviceClose() that is being physically disconnected.
Starting with some version of macOS, this crash bug was fixed,
and starting with macSO 10.15 the opposite effect took place:
in some environments crash happens if IOHIDDeviceClose() is _not_ called.

This patch is to keep a workaround for old versions of macOS,
and don't have a leak in new/tested environments.

Fixes https://github.com/libsdl-org/SDL/issues/12255
2025-02-19 16:55:03 -08:00
Sam Clegg aa00738a21 Fix SDL_emscriptenaudio.c under wasm64
Verified locally by running `browser64.test_sdl2_mixer_wav` in
emscripten.
2025-02-18 13:53:58 -08:00
Sam Lantinga 5330041ea9 Updated to version 2.33.0 for development 2025-02-08 09:15:11 -08:00
50 changed files with 1354 additions and 150 deletions

No files matched your search

+2 -1
View File
@@ -23,7 +23,8 @@ manpageheaderfiletext = Defined in %fname%
# A handful of others we fix up in the header itself with /* WIKI CATEGORY: x */ comments.
headercategoryeval = s/\ASDL_config_.*?\.h\Z//; s/\ASDL_test_.*?\.h\Z//; s/\ASDL_?(.*?)\.h\Z/$1/; ucfirst();
quickrefenabled = 0 # !!! FIXME: maybe later, but there are probably documentation gaps to fix first.
# !!! FIXME: maybe later, but there are probably documentation gaps to fix first.
quickrefenabled = 0
quickrefcategoryorder = Init,Hints,Error,Version,Properties,Log,Video,Events,Keyboard,Mouse,Touch,Gesture,GameController,Joystick,Haptic,Audio,Timer,Render,LoadSO,Thread,Mutex,Atomic,Filesystem,RWOPS,Pixels,Surface,Blendmode,Rect,Clipboard,Messagebox,Vulkan,Metal,Platform,Power,Sensor,Bits,Endian,Assert,CPUInfo,Locale,System,Misc,GUID,Main,Stdinc
quickreftitle = SDL2 API Quick Reference
quickrefurl = https://libsdl.org/
+2 -2
View File
@@ -88,8 +88,8 @@ endif()
# See docs/release_checklist.md
set(SDL_MAJOR_VERSION 2)
set(SDL_MINOR_VERSION 32)
set(SDL_MICRO_VERSION 11)
set(SDL_MINOR_VERSION 33)
set(SDL_MICRO_VERSION 0)
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
# Set defaults preventing destination file conflicts
+2 -2
View File
@@ -14,8 +14,8 @@
LIBNAME = SDL2
MAJOR_VERSION = 2
MINOR_VERSION = 32
MICRO_VERSION = 11
MINOR_VERSION = 33
MICRO_VERSION = 0
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
DESCRIPTION = Simple DirectMedia Layer 2
+2 -2
View File
@@ -5,8 +5,8 @@
LIBNAME = SDL2
MAJOR_VERSION = 2
MINOR_VERSION = 32
MICRO_VERSION = 11
MINOR_VERSION = 33
MICRO_VERSION = 0
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
LIBHOME = .
+3 -2
View File
@@ -371,6 +371,7 @@
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.0.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -391,7 +392,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -603,4 +604,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+2 -2
View File
@@ -19,10 +19,10 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.32.11</string>
<string>2.33.0</string>
<key>CFBundleSignature</key>
<string>SDLX</string>
<key>CFBundleVersion</key>
<string>2.32.11</string>
<string>2.33.0</string>
</dict>
</plist>
+10 -10
View File
@@ -9728,8 +9728,8 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
DYLIB_CURRENT_VERSION = 3201.11.0;
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
DYLIB_CURRENT_VERSION = 3301.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ALTIVEC_EXTENSIONS = YES;
@@ -9770,7 +9770,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_LINK_OBJC_RUNTIME = NO;
MARKETING_VERSION = 2.32.11;
MARKETING_VERSION = 2.33.0;
OTHER_LDFLAGS = "-liconv";
};
name = Release;
@@ -9813,8 +9813,8 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
DYLIB_CURRENT_VERSION = 3201.11.0;
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
DYLIB_CURRENT_VERSION = 3301.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -9856,7 +9856,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_LINK_OBJC_RUNTIME = NO;
MARKETING_VERSION = 2.32.11;
MARKETING_VERSION = 2.33.0;
OTHER_LDFLAGS = "-liconv";
};
name = Debug;
@@ -10062,8 +10062,8 @@
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
DYLIB_CURRENT_VERSION = 3201.11.0;
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
DYLIB_CURRENT_VERSION = 3301.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
@@ -10114,8 +10114,8 @@
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
DYLIB_CURRENT_VERSION = 3201.11.0;
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
DYLIB_CURRENT_VERSION = 3301.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
+1 -1
View File
@@ -1,4 +1,4 @@
Title SDL 2.32.11
Title SDL 2.33.0
Version 1
Description SDL Library for Mac OS X (http://www.libsdl.org)
DefaultLocation /Library/Frameworks
@@ -60,8 +60,8 @@ import java.util.Locale;
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 32;
private static final int SDL_MICRO_VERSION = 11;
private static final int SDL_MINOR_VERSION = 33;
private static final int SDL_MICRO_VERSION = 0;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
+131 -40
View File
@@ -37,6 +37,8 @@ logger = logging.getLogger(__name__)
GIT_HASH_FILENAME = ".git-hash"
REVISION_TXT = "REVISION.txt"
RE_ILLEGAL_MINGW_LIBRARIES = re.compile(r"(?:lib)?(?:gcc|(?:std)?c[+][+]|(?:win)?pthread).*", flags=re.I)
def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime:
try:
@@ -339,6 +341,12 @@ class ArchiveFileTree:
def add_file(self, file: NodeInArchive):
self._tree[file.arcpath] = file
def __iter__(self) -> typing.Iterable[NodeInArchive]:
yield from self._tree.values()
def __contains__(self, value: str) -> bool:
return value in self._tree
def get_latest_mod_time(self) -> datetime.datetime:
return max(item.time for item in self._tree.values() if item.time)
@@ -526,6 +534,16 @@ class SourceCollector:
return path_times
class AndroidApiVersion:
def __init__(self, name: str, ints: tuple[int, ...]):
self.name = name
self.ints = ints
def __repr__(self) -> str:
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
ANDROID_ABI_EXTRA_LINK_OPTIONS = {}
class Releaser:
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
self.release_info = release_info
@@ -586,12 +604,22 @@ class Releaser:
def create_source_archives(self) -> None:
source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter)
print(f"Collecting sources of {self.project}...")
archive_tree = source_collector.get_archive_file_tree()
archive_tree: ArchiveFileTree = source_collector.get_archive_file_tree()
latest_mod_time = archive_tree.get_latest_mod_time()
archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time))
archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time))
archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time)
if "Makefile.am" in archive_tree:
patched_time = latest_mod_time + datetime.timedelta(minutes=1)
print(f"Makefile.am detected -> touching aclocal.m4, */Makefile.in, configure")
for node_data in archive_tree:
arc_name = os.path.basename(node_data.arcpath)
arc_name_we, arc_name_ext = os.path.splitext(arc_name)
if arc_name in ("aclocal.m4", "configure", "Makefile.in"):
print(f"Bumping time of {node_data.arcpath}")
node_data.time = patched_time
archive_base = f"{self.project}-{self.version}"
zip_path = self.dist_path / f"{archive_base}.zip"
tgz_path = self.dist_path / f"{archive_base}.tar.gz"
@@ -668,6 +696,15 @@ class Releaser:
def git_hash_data(self) -> bytes:
return f"{self.commit}\n".encode()
def verify_mingw_library(self, triplet: str, path: Path):
objdump_output = self.executer.check_output([f"{triplet}-objdump", "-p", str(path)])
libraries = re.findall(r"DLL Name: ([^\n]+)", objdump_output)
logger.info("%s (%s) libraries: %r", path, triplet, libraries)
illegal_libraries = list(filter(RE_ILLEGAL_MINGW_LIBRARIES.match, libraries))
logger.error("Detected 'illegal' libraries: %r", illegal_libraries)
if illegal_libraries:
raise Exception(f"{path} links to illegal libraries: {illegal_libraries}")
def create_mingw_archives(self) -> None:
build_type = "Release"
build_parent_dir = self.root / "build-mingw"
@@ -764,7 +801,6 @@ class Releaser:
f"--includedir=${{prefix}}/include",
f"--libdir=${{prefix}}/lib",
f"--bindir=${{prefix}}/bin",
f"--exec-prefix=${{prefix}}/bin",
f"--host={triplet}",
f"--build=x86_64-none-linux-gnu",
"CFLAGS=-O2",
@@ -772,9 +808,10 @@ class Releaser:
"LDFLAGS=-Wl,-s",
] + extra_args, cwd=build_path, env=new_env)
with self.section_printer.group(f"Build MinGW {triplet} (autotools)"):
self.executer.run(["make", "V=1", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
self.executer.run(["make", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
with self.section_printer.group(f"Install MinGW {triplet} (autotools)"):
self.executer.run(["make", "install"], cwd=build_path, env=new_env)
self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll")
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
print("Recording arch-dependent extra files for MinGW development archive ...")
@@ -830,6 +867,7 @@ class Releaser:
self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env)
with self.section_printer.group(f"Install MinGW {triplet} (CMake)"):
self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env)
self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll")
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
print("Recording arch-dependent extra files for MinGW development archive ...")
@@ -857,22 +895,25 @@ class Releaser:
self.artifacts["mingw-devel-tar-gz"] = tgz_path
self.artifacts["mingw-devel-tar-xz"] = txz_path
def _detect_android_api(self, android_home: str) -> typing.Optional[int]:
def _detect_android_api(self, android_home: str) -> typing.Optional[AndroidApiVersion]:
platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*"))
re_platform = re.compile("android-([0-9]+)")
platform_versions = []
re_platform = re.compile("^android-([0-9]+)(?:-ext([0-9]+))?$")
platform_versions: list[AndroidApiVersion] = []
for platform_dir in platform_dirs:
logger.debug("Found Android Platform SDK: %s", platform_dir)
if not (platform_dir / "android.jar").is_file():
logger.debug("Skipping SDK, missing android.jar")
continue
if m:= re_platform.match(platform_dir.name):
platform_versions.append(int(m.group(1)))
platform_versions.sort()
platform_versions.append(AndroidApiVersion(name=platform_dir.name, ints=(int(m.group(1)), int(m.group(2) or 0))))
platform_versions.sort(key=lambda v: v.ints)
logger.info("Available platform versions: %s", platform_versions)
platform_versions = list(filter(lambda v: v >= self._android_api_minimum, platform_versions))
logger.info("Valid platform versions (>=%d): %s", self._android_api_minimum, platform_versions)
platform_versions = list(filter(lambda v: v.ints >= self._android_api_minimum.ints, platform_versions))
logger.info("Valid platform versions (>=%s): %s", self._android_api_minimum.ints, platform_versions)
if not platform_versions:
return None
android_api = platform_versions[0]
logger.info("Selected API version %d", android_api)
logger.info("Selected API version %s", android_api)
return android_api
def _get_prefab_json_text(self) -> str:
@@ -896,8 +937,19 @@ class Releaser:
return json.dumps(module_json_dict, indent=4)
@property
def _android_api_minimum(self):
return self.release_info["android"]["api-minimum"]
def _android_api_minimum(self) -> AndroidApiVersion:
value = self.release_info["android"]["api-minimum"]
if isinstance(value, int):
ints = (value, )
elif isinstance(value, str):
ints = tuple(split("."))
else:
raise ValueError("Invalid android.api-minimum: must be X or X.Y")
match len(ints):
case 1: name = f"android-{ints[0]}"
case 2: name = f"android-{ints[0]}-ext-{ints[1]}"
case _: raise ValueError("Invalid android.api-minimum: must be X or X.Y")
return AndroidApiVersion(name=name, ints=ints)
@property
def _android_api_target(self):
@@ -910,7 +962,7 @@ class Releaser:
def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str:
abi_json_dict = {
"abi": abi,
"api": self._android_api_minimum,
"api": self._android_api_minimum.ints[0],
"ndk": self._android_ndk_minimum,
"stl": "c++_shared" if cpp else "none",
"static": not shared,
@@ -923,7 +975,7 @@ class Releaser:
xmlns:android="http://schemas.android.com/apk/res/android"
package="org.libsdl.android.{self.project}" android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="{self._android_api_minimum}"
<uses-sdk android:minSdkVersion="{self._android_api_minimum.ints[0]}"
android:targetSdkVersion="{self._android_api_target}" />
</manifest>
""")
@@ -933,7 +985,8 @@ class Releaser:
if not cmake_toolchain_file.exists():
logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file)
raise SystemExit(1)
aar_path = self.dist_path / f"{self.project}-{self.version}.aar"
aar_path = self.root / "build-android" / f"{self.project}-{self.version}.aar"
android_dist_path = self.dist_path / f"{self.project}-devel-{self.version}-android.zip"
android_abis = self.release_info["android"]["abis"]
java_jars_added = False
module_data_added = False
@@ -941,16 +994,27 @@ class Releaser:
shutil.rmtree(android_deps_path, ignore_errors=True)
for dep, depinfo in self.release_info["android"].get("dependencies", {}).items():
android_aar = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
with self.section_printer.group(f"Extracting Android dependency {dep} ({android_aar.name})"):
self.executer.run([sys.executable, str(android_aar), "-o", str(android_deps_path)])
dep_devel_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
dep_extract_path = self.deps_path / f"extract/android/{dep}"
shutil.rmtree(dep_extract_path, ignore_errors=True)
dep_extract_path.mkdir(parents=True, exist_ok=True)
with self.section_printer.group(f"Extracting Android dependency {dep} ({dep_devel_zip})"):
with zipfile.ZipFile(dep_devel_zip, "r") as zf:
zf.extractall(dep_extract_path)
dep_devel_aar = dep_extract_path / glob.glob("*.aar", root_dir=dep_extract_path)[0]
self.executer.run([sys.executable, str(dep_devel_aar), "-o", str(android_deps_path)])
for module_name, module_info in self.release_info["android"]["modules"].items():
assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type"
archive_file_tree = ArchiveFileTree()
aar_file_tree = ArchiveFileTree()
android_devel_file_tree = ArchiveFileTree()
for android_abi in android_abis:
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
build_dir = self.root / "build-android" / f"{android_abi}-build"
install_dir = self.root / "install-android" / f"{android_abi}-install"
@@ -961,8 +1025,11 @@ class Releaser:
"cmake",
"-S", str(self.root),
"-B", str(build_dir),
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
# NDK 21e does not support -ffile-prefix-map
# f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
@@ -999,20 +1066,20 @@ class Releaser:
assert library.suffix in (".so", ".a")
assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}"
arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}"
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
if not module_data_added:
library_name = None
if module_info["type"] == "library":
library_name = Path(module_info["library"]).stem.removeprefix("lib")
export_libraries = module_info.get("export-libraries", [])
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
arcdir_prefab_include = f"prefab/modules/{module_name}/include"
if "includes" in module_info:
archive_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
aar_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
else:
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
module_data_added = True
if not java_jars_added:
@@ -1025,21 +1092,28 @@ class Releaser:
assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})"
assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})"
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives"
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
aar_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["aar-files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
archive_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
archive_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
aar_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
with Archiver(zip_path=aar_path) as archiver:
archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
aar_file_tree.add_to_archiver(archive_base="", archiver=archiver)
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
self.artifacts[f"android-aar"] = aar_path
android_devel_file_tree.add_file(NodeInArchive.from_fs(arcpath=aar_path.name, path=aar_path))
android_devel_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
with Archiver(zip_path=android_dist_path) as archiver:
android_devel_file_tree.add_to_archiver(archive_base="", archiver=archiver)
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
self.artifacts[f"android-aar"] = android_dist_path
def download_dependencies(self):
shutil.rmtree(self.deps_path, ignore_errors=True)
@@ -1076,7 +1150,7 @@ class Releaser:
assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
if "android" in self.release_info:
android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {android_matches}"
@staticmethod
def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig:
@@ -1202,6 +1276,10 @@ class Releaser:
platform_context = self.get_context(extra_context=arch_platform.extra_context())
build_type = "Release"
extra_context = {
"ARCH": arch_platform.arch,
"PLATFORM": arch_platform.platform,
}
built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list)
logger.info("CMake builds these files, to be included in the package: %s", built_paths)
@@ -1252,7 +1330,7 @@ class Releaser:
logger.info("Collecting files...")
archive_file_tree = ArchiveFileTree()
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time)
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
logger.info("Creating %s", zip_path)
with Archiver(zip_path=zip_path) as archiver:
@@ -1316,7 +1394,7 @@ def main(argv=None) -> int:
parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?")
parser.set_defaults(loglevel=logging.INFO)
parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year")
parser.add_argument('--android-api', type=int, dest="android_api", help="Android API version")
parser.add_argument('--android-api', dest="android_api", help="Android API version")
parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder")
parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder")
parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator")
@@ -1443,14 +1521,27 @@ def main(argv=None) -> int:
if args.android_api is None:
with section_printer.group("Detect Android APIS"):
args.android_api = releaser._detect_android_api(android_home=args.android_home)
if args.android_api is None or not (Path(args.android_home) / f"platforms/android-{args.android_api}").is_dir():
else:
try:
android_api_ints = tuple(int(v) for v in args.android_api.split("."))
match len(android_api_ints):
case 1: android_api_name = f"android-{android_api_ints[0]}"
case 2: android_api_name = f"android-{android_api_ints[0]}-ext-{android_api_ints[1]}"
case _: raise ValueError
except ValueError:
logger.error("Invalid --android-api, must be a 'X' or 'X.Y' version")
args.android_api = AndroidApiVersion(ints=android_api_ints, name=android_api_name)
if args.android_api is None:
parser.error("Invalid --android-api, and/or could not be detected")
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
if not android_api_path.is_dir():
logger.warning(f"Android API directory does not exist ({android_api_path})")
with section_printer.group("Android arguments"):
print(f"android_home = {args.android_home}")
print(f"android_ndk_home = {args.android_ndk_home}")
print(f"android_api = {args.android_api}")
releaser.create_android_archives(
android_api=args.android_api,
android_api=args.android_api.ints[0],
android_home=args.android_home,
android_ndk_home=args.android_ndk_home,
)
Vendored
+2 -2
View File
@@ -3515,8 +3515,8 @@ orig_CFLAGS="$CFLAGS"
# See docs/release_checklist.md
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=32
SDL_MICRO_VERSION=11
SDL_MINOR_VERSION=33
SDL_MICRO_VERSION=0
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
+2 -2
View File
@@ -12,8 +12,8 @@ orig_CFLAGS="$CFLAGS"
dnl Set various version strings - taken gratefully from the GTk sources
# See docs/release_checklist.md
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=32
SDL_MICRO_VERSION=11
SDL_MINOR_VERSION=33
SDL_MICRO_VERSION=0
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
+1 -1
View File
@@ -29,7 +29,7 @@ cmake --install build
## Compiling a HelloWorld
[PSP Hello World](https://psp-dev.org/doku.php?id=tutorial:hello_world)
[PSP Hello World](https://pspdev.github.io/basic_programs.html#hello-world)
## To Do
- PSP Screen Keyboard
-3
View File
@@ -14,7 +14,6 @@ Works out of box.
Windows:
Unfortunately there is no windows support as of yet. Support for Windows 7 is planned, but we currently have no way to test. If you have a Windows 7 WM_TOUCH supported device, and are willing to help test please contact me at jim.tla+sdl_touch@gmail.com
===========================================================================
Events
===========================================================================
SDL_FINGERDOWN:
@@ -39,7 +38,6 @@ Fields:
Same as SDL_FINGERDOWN.
===========================================================================
Functions
===========================================================================
SDL provides the ability to access the underlying SDL_Finger structures.
@@ -76,7 +74,6 @@ A SDL_Finger has the following fields:
The pressure of the touch.
===========================================================================
Notes
===========================================================================
For a complete example see test/testgesture.c
+11 -1
View File
@@ -648,7 +648,7 @@ extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name,
* \param obtained an SDL_AudioSpec structure filled in with the actual output
* format; see SDL_OpenAudio() for more information.
* \param allowed_changes 0, or one or more flags OR'd together.
* \returns a valid device ID that is > 0 on success or 0 on failure; call
* \returns a valid device ID > 0 on success or 0 on failure; call
* SDL_GetError() for more information.
*
* For compatibility with SDL 1.2, this will never return 1, since
@@ -1059,6 +1059,9 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *bu
* resample correctly, so this number might be lower than what you expect, or
* even be zero. Add more data or flush the stream if you need the data now.
*
* \param stream the audio stream to query.
* \returns the number of bytes available.
*
* \since This function is available since SDL 2.0.7.
*
* \sa SDL_NewAudioStream
@@ -1078,6 +1081,9 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream);
* audio gaps in the output. Generally this is intended to signal the end of
* input, so the complete output becomes available.
*
* \param stream the audio stream to flush.
* \returns 0 on success, otherwise -1.
*
* \since This function is available since SDL 2.0.7.
*
* \sa SDL_NewAudioStream
@@ -1092,6 +1098,8 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream);
/**
* Clear any pending data in the stream without converting it
*
* \param stream the audio stream to clear.
*
* \since This function is available since SDL 2.0.7.
*
* \sa SDL_NewAudioStream
@@ -1106,6 +1114,8 @@ extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream);
/**
* Free an audio stream
*
* \param stream the audio stream to free.
*
* \since This function is available since SDL 2.0.7.
*
* \sa SDL_NewAudioStream
+17
View File
@@ -226,6 +226,7 @@ extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void);
/**
* Get the mapping at a particular index.
*
* \param mapping_index mapping index.
* \returns the mapping string. Must be freed with SDL_free(). Returns NULL if
* the index is out of range.
*
@@ -850,6 +851,9 @@ extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *ga
/**
* Get the number of touchpads on a game controller.
*
* \param gamecontroller a controller.
* \returns number of touchpads.
*
* \since This function is available since SDL 2.0.14.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller);
@@ -858,6 +862,10 @@ extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController
* Get the number of supported simultaneous fingers on a touchpad on a game
* controller.
*
* \param gamecontroller a controller.
* \param touchpad a touchpad.
* \returns number of supported simultaneous fingers.
*
* \since This function is available since SDL 2.0.14.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad);
@@ -865,6 +873,15 @@ extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameCont
/**
* Get the current state of a finger on a touchpad on a game controller.
*
* \param gamecontroller a controller.
* \param touchpad a touchpad.
* \param finger a finger.
* \param state a pointer filled with the finger state.
* \param x a pointer filled with the x position.
* \param y a pointer filled with the y position.
* \param pressure a pointer filled with pressure value.
* \returns 0 on success or negative on failure.
*
* \since This function is available since SDL 2.0.14.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure);
+1
View File
@@ -227,6 +227,7 @@ extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id,
* platform-specific path name can be used (eg: /dev/hidraw0 on Linux).
*
* \param path The path name of the device to open.
* \param bExclusive boolean exclusive.
* \returns a pointer to a SDL_hid_device object on success or NULL on
* failure.
*
+8
View File
@@ -214,6 +214,9 @@ extern DECLSPEC const char *SDLCALL SDL_JoystickPathForIndex(int device_index);
* Get the player index of a joystick, or -1 if it's not available This can be
* called before any joysticks are opened.
*
* \param device_index device index.
* \returns player index, or -1 if not available.
*
* \since This function is available since SDL 2.0.9.
*/
extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
@@ -356,6 +359,10 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_ind
/**
* Attach a new virtual joystick.
*
* \param type joystick type.
* \param naxes number of axes.
* \param nbuttons number of buttons.
* \param nhats number of hats.
* \returns the joystick's device index, or -1 if an error occurred.
*
* \since This function is available since SDL 2.0.14.
@@ -409,6 +416,7 @@ typedef struct SDL_VirtualJoystickDesc
/**
* Attach a new virtual joystick with extended properties.
*
* \param desc joystick description.
* \returns the joystick's device index, or -1 if an error occurred.
*
* \since This function is available since SDL 2.24.0.
+3
View File
@@ -298,6 +298,9 @@ extern DECLSPEC void SDLCALL SDL_ClearComposition(void);
/**
* Returns if an IME Composite or Candidate window is currently shown.
*
* \returns SDL_TRUE if an IME Composite or Candidate window is currently
* shown else SDL_FALSE.
*
* \since This function is available since SDL 2.0.22.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputShown(void);
+6
View File
@@ -41,12 +41,18 @@
*
* A special exception is the number keys at the top of the keyboard which map
* to SDLK_0...SDLK_9 on AZERTY layouts.
*
* The actual values that might be set for this type are listed in the
* SDL_KeyCode (capital C) enumeration.
*/
typedef Sint32 SDL_Keycode;
#define SDLK_SCANCODE_MASK (1<<30)
#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
/**
* The possible values for keycodes.
*/
typedef enum SDL_KeyCode
{
SDLK_UNKNOWN = 0,
+1 -2
View File
@@ -163,8 +163,7 @@ extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void);
/**
* Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO.
*
* = * \param fmt a printf() style message format string
*
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the `fmt` string, if
* any.
*
+2 -2
View File
@@ -187,8 +187,8 @@ extern DECLSPEC void SDLCALL SDL_SetMainReady(void);
* \param name the window class name, in UTF-8 encoding. If NULL, SDL
* currently uses "SDL_app" but this isn't guaranteed.
* \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL
* currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of
* what is specified here.
* currently uses `(CS_BYTEALIGNCLIENT \| CS_OWNDC)` regardless
* of what is specified here.
* \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL
* will use `GetModuleHandle(NULL)` instead.
* \returns 0 on success, -1 on error. SDL_GetError() may have details.
+8
View File
@@ -59,6 +59,9 @@ typedef void *SDL_MetalView;
* The returned handle can be casted directly to a NSView or UIView. To access
* the backing CAMetalLayer, call SDL_Metal_GetLayer().
*
* \param window the window.
* \returns handle NSView or UIView.
*
* \since This function is available since SDL 2.0.12.
*
* \sa SDL_Metal_DestroyView
@@ -72,6 +75,8 @@ extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window);
* This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was
* called after SDL_CreateWindow.
*
* \param view the SDL_MetalView object.
*
* \since This function is available since SDL 2.0.12.
*
* \sa SDL_Metal_CreateView
@@ -81,6 +86,9 @@ extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view);
/**
* Get a pointer to the backing CAMetalLayer for the given view.
*
* \param view the SDL_MetalView object.
* \returns a pointer.
*
* \since This function is available since SDL 2.0.14.
*
* \sa SDL_Metal_CreateView
+27
View File
@@ -106,6 +106,10 @@ typedef struct SDL_FRect
/**
* Returns true if point resides inside a rectangle.
*
* \param p the point to test.
* \param r the rectangle to test.
* \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
*/
SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
{
@@ -115,6 +119,9 @@ SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
/**
* Returns true if the rectangle has no area.
*
* \param r the rectangle to test.
* \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
*/
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
{
@@ -123,6 +130,10 @@ SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
/**
* Returns true if the two rectangles are equal.
*
* \param a the first rectangle to test.
* \param b the second rectangle to test.
* \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
*/
SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b)
{
@@ -229,6 +240,10 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *
/**
* Returns true if point resides inside a rectangle.
*
* \param p the point to test.
* \param r the rectangle to test.
* \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
*/
SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r)
{
@@ -238,6 +253,9 @@ SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect
/**
* Returns true if the rectangle has no area.
*
* \param r the rectangle to test.
* \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
*/
SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
{
@@ -247,6 +265,11 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
/**
* Returns true if the two rectangles are equal, within some given epsilon.
*
* \param a the first rectangle to test.
* \param b the second rectangle to test.
* \param epsilon the epsilon value for comparison.
* \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
*
* \since This function is available since SDL 2.0.22.
*/
SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
@@ -262,6 +285,10 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_F
/**
* Returns true if the two rectangles are equal, using a default epsilon.
*
* \param a the first rectangle to test.
* \param b the second rectangle to test.
* \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
*
* \since This function is available since SDL 2.0.22.
*/
SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b)
+2 -1
View File
@@ -30,6 +30,7 @@
* - single pixel lines
* - filled rectangles
* - texture images
* - 2D polygons
*
* The primitives may be drawn in opaque, blended, or additive modes.
*
@@ -38,7 +39,7 @@
* may also be stretched with linear interpolation.
*
* This API is designed to accelerate simple 2D operations. You may want more
* functionality such as polygons and particle effects and in that case you
* functionality such as 3D polygons and particle effects and in that case you
* should use SDL's OpenGL/Direct3D support or one of the many good 3D
* engines.
*
+35
View File
@@ -467,6 +467,11 @@ typedef void (SDLCALL *SDL_free_func)(void *mem);
/**
* Get the original set of SDL memory functions
*
* \param malloc_func filled with malloc function.
* \param calloc_func filled with calloc function.
* \param realloc_func filled with realloc function.
* \param free_func filled with free function.
*
* \since This function is available since SDL 2.24.0.
*/
extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func,
@@ -477,6 +482,11 @@ extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *mal
/**
* Get the current set of SDL memory functions
*
* \param malloc_func filled with malloc function.
* \param calloc_func filled with calloc function.
* \param realloc_func filled with realloc function.
* \param free_func filled with free function.
*
* \since This function is available since SDL 2.0.7.
*/
extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func,
@@ -487,6 +497,13 @@ extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func
/**
* Replace SDL's memory allocation functions with a custom set
*
* \param malloc_func custom malloc function.
* \param calloc_func custom calloc function.
* \param realloc_func custom realloc function.
* \param free_func custom free function.
* \returns 0 on success or -1 on failure; call SDL_GetError() for more
* information.
*
* \since This function is available since SDL 2.0.7.
*/
extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func,
@@ -497,6 +514,8 @@ extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func,
/**
* Get the number of outstanding (unfreed) allocations
*
* \returns number of unfreed allocations.
*
* \since This function is available since SDL 2.0.7.
*/
extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void);
@@ -716,6 +735,12 @@ extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf,
* This function converts a buffer or string between encodings in one pass,
* returning a string that must be freed with SDL_free() or NULL on error.
*
* \param tocode the character encoding of the output string.
* \param fromcode the character encoding of data in `inbuf`.
* \param inbuf the string to convert to a different encoding.
* \param inbytesleft the size of the input string _in bytes_.
* \returns a new string, converted to the new encoding, or NULL on error.
*
* \since This function is available since SDL 2.0.0.
*/
extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode,
@@ -807,6 +832,11 @@ SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_B
*
* Otherwise store a * b via ret and return 0.
*
* \param a the multiplicand.
* \param b the multiplier.
* \param ret on non-overflow output, stores the multiplication result.
* \returns -1 on overflow, 0 if result is multiplied without overflow.
*
* \since This function is available since SDL 2.24.0.
*/
SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a,
@@ -838,6 +868,11 @@ SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a,
*
* Otherwise store a + b via ret and return 0.
*
* \param a the first addend.
* \param b the second addend.
* \param ret on non-overflow output, stores the addition result.
* \returns false on overflow, true if result is added without overflow.
*
* \since This function is available since SDL 2.24.0.
*/
SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a,
+58 -6
View File
@@ -801,15 +801,14 @@ extern DECLSPEC int SDLCALL SDL_FillRect
extern DECLSPEC int SDLCALL SDL_FillRects
(SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color);
/* !!! FIXME: merge this documentation with the wiki */
/**
* Performs a fast blit from the source surface to the destination surface.
*
* This assumes that the source and destination rectangles are the same size.
* If either `srcrect` or `dstrect` are NULL, the entire surface (`src` or
* `dst`) is copied. The final blit rectangle is saved in `dstrect` after
* all clipping is performed.
* `dstrect`'s width and height are ignored, only its position is used. If
* either `srcrect` or `dstrect` are NULL, the entire surface (`src` or `dst`)
* is copied. The final blit rectangle is saved in `dstrect` after all
* clipping is performed.
*
* The blit function should not be called on a locked surface.
*
@@ -859,7 +858,17 @@ extern DECLSPEC int SDLCALL SDL_FillRects
* You should call SDL_BlitSurface() unless you know exactly how SDL blitting
* works internally and how to use the other blit functions.
*
* \returns 0 if the blit is successful, otherwise it returns -1.
* \param src the SDL_Surface structure to be copied from.
* \param srcrect the SDL_Rect structure representing the rectangle to be
* copied, or NULL to copy the entire surface.
* \param dst the SDL_Surface structure that is the blit target.
* \param dstrect the SDL_Rect structure representing the x and y position in
* the destination surface, or NULL for (0,0). The width and
* height are ignored, and are copied from `srcrect`. If you
* want a specific width and height, you should use
* SDL_BlitScaled().
* \returns 0 if the blit is successful or a negative error code on failure;
* call SDL_GetError() for more information.
*/
#define SDL_BlitSurface SDL_UpperBlit
@@ -869,6 +878,18 @@ extern DECLSPEC int SDLCALL SDL_FillRects
* SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a
* macro for this function with a less confusing name.
*
* \param src the SDL_Surface structure to be copied from.
* \param srcrect the SDL_Rect structure representing the rectangle to be
* copied, or NULL to copy the entire surface.
* \param dst the SDL_Surface structure that is the blit target.
* \param dstrect the SDL_Rect structure representing the x and y position in
* the destination surface, or NULL for (0,0). The width and
* height are ignored, and are copied from `srcrect`. If you
* want a specific width and height, you should use
* SDL_BlitScaled().
* \returns 0 if the blit is successful or a negative error code on failure;
* call SDL_GetError() for more information.
*
* \since This function is available since SDL 2.0.0.
*
* \sa SDL_BlitSurface
@@ -910,6 +931,13 @@ extern DECLSPEC int SDLCALL SDL_LowerBlit
*
* Please use SDL_BlitScaled() instead.
*
* \param src the surface to be copied from.
* \param srcrect the rectangle to be copied.
* \param dst the surface that is the blit target.
* \param dstrect the rectangle that is copied into.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 2.0.0.
*/
extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
@@ -920,6 +948,13 @@ extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
/**
* Perform bilinear scaling between two surfaces of the same format, 32BPP.
*
* \param src the surface to be copied from.
* \param srcrect the rectangle to be copied.
* \param dst the surface that is the blit target.
* \param dstrect the rectangle that is copied into.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 2.0.16.
*/
extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src,
@@ -934,6 +969,15 @@ extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src,
* SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is
* merely a macro for this function with a less confusing name.
*
* \param src the SDL_Surface structure to be copied from.
* \param srcrect the SDL_Rect structure representing the rectangle to be
* copied, or NULL to copy the entire surface.
* \param dst the SDL_Surface structure that is the blit target.
* \param dstrect the SDL_Rect structure representing the rectangle that is
* copied into, or NULL to copy into the entire surface.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 2.0.0.
*
* \sa SDL_BlitScaled
@@ -971,6 +1015,8 @@ extern DECLSPEC int SDLCALL SDL_LowerBlitScaled
/**
* Set the YUV conversion mode
*
* \param mode the YUV conversion mode.
*
* \since This function is available since SDL 2.0.8.
*/
extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode);
@@ -978,6 +1024,8 @@ extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mo
/**
* Get the YUV conversion mode
*
* \returns YUV conversion mode.
*
* \since This function is available since SDL 2.0.8.
*/
extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
@@ -986,6 +1034,10 @@ extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
* Get the YUV conversion mode, returning the correct mode for the resolution
* when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC
*
* \param width the resolution width.
* \param height the resolution height.
* \returns YUV conversion mode.
*
* \since This function is available since SDL 2.0.8.
*/
extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height);
+21
View File
@@ -463,6 +463,7 @@ extern DECLSPEC int SDLCALL SDL_AndroidShowToast(const char* message, int durati
*
* \param command user command that must be greater or equal to 0x8000.
* \param param user parameter.
* \returns 0 on success, otherwise -1.
*
* \since This function is available since SDL 2.0.22.
*/
@@ -571,6 +572,26 @@ extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathT
*/
extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily();
/**
* Get the protocol activation URI if the app was launched via protocol
* activation.
*
* When a UWP/WinRT app is launched via a custom URI scheme (e.g.,
* myapp://action?param=value), this function retrieves the full activation
* URI string.
*
* The URI is only available once per activation - after the first successful
* call, subsequent calls will return NULL. This ensures the URI is processed
* only once.
*
* \returns the protocol activation URI as a UTF-8 string that must be freed
* with SDL_free(), or NULL if the app was not activated via protocol
* or the URI was already retrieved.
*
* \since This function is available since SDL 2.33.0.
*/
extern DECLSPEC char * SDLCALL SDL_WinRTGetProtocolActivationURI(void);
#endif /* __WINRT__ */
/**
+7
View File
@@ -99,6 +99,10 @@ extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index);
* Get the touch device name as reported from the driver or NULL if the index
* is invalid.
*
* \param index the touch device index.
* \returns touch device name, or NULL on failure; call SDL_GetError() for
* more information.
*
* \since This function is available since SDL 2.0.22.
*/
extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index);
@@ -106,6 +110,9 @@ extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index);
/**
* Get the type of the given touch device.
*
* \param touchID the ID of a touch device.
* \returns touch device type.
*
* \since This function is available since SDL 2.0.10.
*/
extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID);
+2 -2
View File
@@ -57,8 +57,8 @@ typedef struct SDL_version
/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
*/
#define SDL_MAJOR_VERSION 2
#define SDL_MINOR_VERSION 32
#define SDL_PATCHLEVEL 11
#define SDL_MINOR_VERSION 33
#define SDL_PATCHLEVEL 0
/**
* Macro to determine SDL version program was compiled against.
+3
View File
@@ -1008,6 +1008,8 @@ extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window,
* \param h the height of the window in pixels, in screen coordinates, must be
* > 0.
*
* \threadsafety This function should only be called on the main thread.
*
* \since This function is available since SDL 2.0.0.
*
* \sa SDL_GetWindowSize
@@ -1315,6 +1317,7 @@ extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window,
/**
* Return whether the window has a surface associated with it.
*
* \param window the window to query.
* \returns SDL_TRUE if there is a surface associated with the window, or
* SDL_FALSE otherwise.
*
+94
View File
@@ -20,6 +20,8 @@
*/
#include "../../SDL_internal.h"
/* Standard C++11 includes: */
#include <string>
/* Windows includes */
#include "ppltasks.h"
using namespace concurrency;
@@ -43,6 +45,7 @@ extern "C" {
#include "SDL_hints.h"
#include "SDL_main.h"
#include "SDL_stdinc.h"
#include "SDL_system.h"
#include "SDL_render.h"
#include "../../video/SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
@@ -80,6 +83,60 @@ extern "C" void D3D11_Trim(SDL_Renderer *);
// SDL_CreateWindow().
SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
// Protocol activation URI storage
static Platform::String^ WINRT_ProtocolActivationURI = nullptr;
// Store launchOnExit URI separately since WINRT_ProtocolActivationURI gets cleared
static std::wstring WINRT_LaunchOnExitURI;
// Helper function to extract and store launchOnExit from protocol URI
static void WINRT_ExtractLaunchOnExitURI(Platform::String^ fullUri)
{
if (fullUri == nullptr)
return;
std::wstring uri(fullUri->Data());
// Look for launchOnExit parameter in the URI
size_t launchPos = uri.find(L"launchOnExit=");
if (launchPos == std::wstring::npos)
return;
// Extract the launchOnExit URI value
launchPos += 13; // Skip past "launchOnExit="
size_t endPos = uri.find(L'&', launchPos);
if (endPos == std::wstring::npos)
endPos = uri.length();
std::wstring launchUri = uri.substr(launchPos, endPos - launchPos);
// URL decode the URI (convert %3A to :, etc.)
WINRT_LaunchOnExitURI.clear();
for (size_t i = 0; i < launchUri.length(); i++) {
if (launchUri[i] == L'%' && i + 2 < launchUri.length()) {
wchar_t hex[3] = { launchUri[i + 1], launchUri[i + 2], 0 };
WINRT_LaunchOnExitURI += (wchar_t)wcstol(hex, nullptr, 16);
i += 2;
} else {
WINRT_LaunchOnExitURI += launchUri[i];
}
}
}
// Helper function to launch URI on exit if protocol activation included launchOnExit parameter
static void WINRT_LaunchExitUriIfSet()
{
if (!WINRT_LaunchOnExitURI.empty()) {
try {
// Launch the URI
auto uri = ref new Windows::Foundation::Uri(ref new Platform::String(WINRT_LaunchOnExitURI.c_str()));
Windows::System::Launcher::LaunchUriAsync(uri);
} catch (...) {
// Silently ignore errors during termination
}
}
}
ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
@@ -107,6 +164,22 @@ int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
return 0;
}
extern "C" char* SDL_WinRTGetProtocolActivationURI(void)
{
if (WINRT_ProtocolActivationURI == nullptr)
return nullptr;
Platform::String^ uriStr = WINRT_ProtocolActivationURI;
const wchar_t* uriWide = uriStr->Data();
int uriLen = WideCharToMultiByte(CP_UTF8, 0, uriWide, -1, nullptr, 0, nullptr, nullptr);
char* uriUtf8 = (char*)SDL_malloc(uriLen);
if (uriUtf8)
WideCharToMultiByte(CP_UTF8, 0, uriWide, -1, uriUtf8, uriLen, nullptr, nullptr);
// Clear after first successful read (only return it once)
WINRT_ProtocolActivationURI = nullptr;
return uriUtf8;
}
static void WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange()
{
CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
@@ -164,6 +237,12 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false),
{
}
SDL_WinRTApp::~SDL_WinRTApp()
{
// Launch exit URI if set (handles protocol activation returning to caller)
WINRT_LaunchExitUriIfSet();
}
void SDL_WinRTApp::Initialize(CoreApplicationView ^ applicationView)
{
applicationView->Activated +=
@@ -585,15 +664,29 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ arg
SDL_Log("%s\n", __FUNCTION__);
#endif
m_windowClosed = true;
WINRT_LaunchExitUriIfSet();
}
void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args)
{
if (args->Kind == Windows::ApplicationModel::Activation::ActivationKind::Protocol)
{
auto protocolArgs = dynamic_cast<Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs^>(args);
if (protocolArgs && protocolArgs->Uri)
{
WINRT_ProtocolActivationURI = protocolArgs->Uri->AbsoluteUri;
// Extract and store launchOnExit URI before main URI gets cleared
WINRT_ExtractLaunchOnExitURI(WINRT_ProtocolActivationURI);
}
}
CoreWindow::GetForCurrentThread()->Activate();
}
void SDL_WinRTApp::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ args)
{
// Launch exit URI if set before suspending
WINRT_LaunchExitUriIfSet();
// Save app state asynchronously after requesting a deferral. Holding a deferral
// indicates that the application is busy performing suspending operations. Be
// aware that a deferral may not be held indefinitely. After about five seconds,
@@ -647,6 +740,7 @@ void SDL_WinRTApp::OnResuming(Platform::Object ^ sender, Platform::Object ^ args
void SDL_WinRTApp::OnExiting(Platform::Object ^ sender, Platform::Object ^ args)
{
SDL_SendAppEvent(SDL_APP_TERMINATING);
WINRT_LaunchExitUriIfSet();
}
static void WINRT_LogPointerEvent(const char *header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
+1
View File
@@ -26,6 +26,7 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
{
public:
SDL_WinRTApp();
virtual ~SDL_WinRTApp();
// IFrameworkView Methods.
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView);
+1
View File
@@ -872,3 +872,4 @@
++'_SDL_DestroyWindowSurface'.'SDL2.dll'.'SDL_DestroyWindowSurface'
# ++'_SDL_GDKGetDefaultUser'.'SDL2.dll'.'SDL_GDKGetDefaultUser'
++'_SDL_GameControllerGetSteamHandle'.'SDL2.dll'.'SDL_GameControllerGetSteamHandle'
# ++'_SDL_WinRTGetProtocolActivationURI'.'SDL2.dll'.'SDL_WinRTGetProtocolActivationURI'
+1
View File
@@ -898,3 +898,4 @@
#define SDL_DestroyWindowSurface SDL_DestroyWindowSurface_REAL
#define SDL_GDKGetDefaultUser SDL_GDKGetDefaultUser_REAL
#define SDL_GameControllerGetSteamHandle SDL_GameControllerGetSteamHandle_REAL
#define SDL_WinRTGetProtocolActivationURI SDL_WinRTGetProtocolActivationURI_REAL
+3
View File
@@ -985,3 +985,6 @@ SDL_DYNAPI_PROC(int,SDL_DestroyWindowSurface,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GDKGetDefaultUser,(XUserHandle *a),(a),return)
#endif
SDL_DYNAPI_PROC(Uint64,SDL_GameControllerGetSteamHandle,(SDL_GameController *a),(a),return)
#if defined(__WINRT__)
SDL_DYNAPI_PROC(char*,SDL_WinRTGetProtocolActivationURI,(void),(),return)
#endif
+4 -4
View File
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,32,11,0
PRODUCTVERSION 2,32,11,0
FILEVERSION 2,33,0,0
PRODUCTVERSION 2,33,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "2, 32, 11, 0\0"
VALUE "FileVersion", "2, 33, 0, 0\0"
VALUE "InternalName", "SDL\0"
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL2.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0"
VALUE "ProductVersion", "2, 32, 11, 0\0"
VALUE "ProductVersion", "2, 33, 0, 0\0"
END
END
BLOCK "VarFileInfo"
+42
View File
@@ -29,6 +29,12 @@
#include "software/SDL_render_sw_c.h"
#include "../video/SDL_pixels_c.h"
#if defined(__loongarch__)
#if SDL_VIDEO_OPENGL
#include "SDL_opengl.h"
#endif /* SDL_VIDEO_OPENGL */
#endif
#if defined(__ANDROID__)
#include "../core/android/SDL_android.h"
#endif
@@ -954,6 +960,34 @@ static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Wind
}
#endif /* !SDL_RENDER_DISABLED */
#if defined(__loongarch__)
static SDL_bool SDL_CheckIntegratedGraphics()
{
SDL_Window *window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32,
SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
SDL_bool has_lg100_or_lg110 = SDL_FALSE;
if (window) {
SDL_GLContext context = SDL_GL_CreateContext(window);
if (context) {
const GLubyte *(APIENTRY *glGetStringFunc)(GLenum) =
SDL_GL_GetProcAddress("glGetString");
if (glGetStringFunc) {
const char *renderer = (const char*)glGetStringFunc(GL_RENDERER);
if (renderer && (SDL_strstr(renderer, "LG110") ||
SDL_strstr(renderer, "LG100"))) {
has_lg100_or_lg110 = SDL_TRUE;
}
}
SDL_GL_DeleteContext(context);
}
SDL_DestroyWindow(window);
}
return has_lg100_or_lg110;
}
#endif
SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
{
#ifndef SDL_RENDER_DISABLED
@@ -967,6 +1001,14 @@ SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
Android_ActivityMutex_Lock_Running();
#endif
/* CPU acceleration runs faster than integrated graphics on Loongson at present. */
#if defined(__linux__) && defined(__loongarch__)
if (SDL_CheckIntegratedGraphics()) {
SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "0");
flags = SDL_RENDERER_SOFTWARE;
}
#endif
if (!window) {
SDL_InvalidParamError("window");
goto error;
+178 -16
View File
@@ -76,6 +76,24 @@ typedef struct
SDL_Texture *texture;
} PSP_BlendState;
typedef struct
{
SDL_Rect viewport;
SDL_bool viewport_dirty;
SDL_bool viewport_is_set;
SDL_bool cliprect_enabled_dirty;
SDL_bool cliprect_enabled;
SDL_bool cliprect_dirty;
SDL_Rect cliprect;
float draw_offset_x;
float draw_offset_y;
int drawablew;
int drawableh;
} PSP_DrawstateCache;
typedef struct
{
void *frontbuffer; /**< main screen buffer */
@@ -91,6 +109,7 @@ typedef struct
PSP_TextureData *most_recent_target; /**< start of render target LRU double linked list */
PSP_TextureData *least_recent_target; /**< end of the LRU list */
PSP_DrawstateCache drawstate;
SDL_bool vblank_not_reached; /**< whether vblank wasn't reached */
} PSP_RenderData;
@@ -1034,10 +1053,105 @@ static void PSP_SetBlendState(PSP_RenderData *data, PSP_BlendState *state)
*current = *state;
}
static void ClampCliprectToViewport(SDL_Rect *clip, const SDL_Rect *viewport)
{
int max_x_v, max_y_v, max_x_c, max_y_c;
if (clip->x < 0) {
clip->w += clip->x;
clip->x = 0;
}
if (clip->y < 0) {
clip->h += clip->y;
clip->y = 0;
}
max_x_c = clip->x + clip->w;
max_y_c = clip->y + clip->h;
max_x_v = viewport->x + viewport->w;
max_y_v = viewport->y + viewport->h;
if (max_x_c > max_x_v) {
clip->w -= (max_x_v - max_x_c);
}
if (max_y_c > max_y_v) {
clip->h -= (max_y_v - max_y_c);
}
}
static void SetDrawState(PSP_RenderData *data)
{
if (data->drawstate.viewport_dirty) {
SDL_Rect *viewport = &data->drawstate.viewport;
/* FIXME: Find a genuine way to make viewport work (right now calling these functions here give no effect) */
/*
sceGuOffset(2048 - (480 >> 1) + viewport->x, 2048 - (272 >> 1) + viewport->y);
sceGuViewport(2048, 2048, viewport->w, viewport->h);
*/
data->drawstate.draw_offset_x = viewport->x;
data->drawstate.draw_offset_y = viewport->y;
data->drawstate.viewport_dirty = SDL_FALSE;
}
if (data->drawstate.cliprect_enabled_dirty) {
if (!data->drawstate.cliprect_enabled && !data->drawstate.viewport_is_set) {
sceGuScissor(0, 0, data->drawstate.drawablew, data->drawstate.drawableh);
sceGuEnable(GU_SCISSOR_TEST);
}
data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
}
if ((data->drawstate.cliprect_enabled || data->drawstate.viewport_is_set) && data->drawstate.cliprect_dirty) {
SDL_Rect rect;
SDL_Rect *viewport = &data->drawstate.viewport;
SDL_copyp(&rect, &data->drawstate.cliprect);
if (data->drawstate.viewport_is_set) {
ClampCliprectToViewport(&rect, viewport);
rect.x += viewport->x;
rect.y += viewport->y;
}
sceGuEnable(GU_SCISSOR_TEST);
sceGuScissor(rect.x, rect.y, rect.w, rect.h);
data->drawstate.cliprect_dirty = SDL_FALSE;
}
}
#define PSP_VERTICES_FUNK(FunkName, Type) \
static const Type *FunkName(const PSP_DrawstateCache *drawstate, Uint8 *gpumem, SDL_RenderCommand *cmd, size_t count) \
{ \
size_t i; \
float off_x, off_y; \
Type *verts = (Type *)(gpumem + cmd->data.draw.first); \
\
if (!drawstate->viewport_is_set) { \
return verts; \
} \
\
off_x = drawstate->draw_offset_x; \
off_y = drawstate->draw_offset_y; \
\
for (i = 0; i < count; ++i) { \
verts[i].x += off_x; \
verts[i].y += off_y; \
} \
\
return verts;\
}
PSP_VERTICES_FUNK(PSP_GetVertV, VertV)
PSP_VERTICES_FUNK(PSP_GetVertTV, VertTV)
PSP_VERTICES_FUNK(PSP_GetVertCV, VertCV)
PSP_VERTICES_FUNK(PSP_GetVertTCV, VertTCV)
static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata;
Uint8 *gpumem = NULL;
int w = 0, h = 0;
StartDrawing(renderer);
/* note that before the renderer interface change, this would do extrememly small
@@ -1052,6 +1166,21 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
}
SDL_memcpy(gpumem, vertices, vertsize);
if (!data->boundTarget) {
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
} else {
PSP_TextureData *psp_texture = (PSP_TextureData *)data->boundTarget->driverdata;
w = psp_texture->width;
h = psp_texture->height;
}
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
data->drawstate.viewport_dirty = SDL_TRUE; /* if the window dimensions changed, invalidate the current viewport, etc. */
data->drawstate.cliprect_dirty = SDL_TRUE;
data->drawstate.drawablew = w;
data->drawstate.drawableh = h;
}
while (cmd) {
switch (cmd->command) {
case SDL_RENDERCMD_SETDRAWCOLOR:
@@ -1061,22 +1190,42 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
case SDL_RENDERCMD_SETVIEWPORT:
{
SDL_Rect *viewport = &cmd->data.viewport.rect;
sceGuOffset(2048 - (viewport->w >> 1), 2048 - (viewport->h >> 1));
sceGuViewport(2048, 2048, viewport->w, viewport->h);
sceGuScissor(viewport->x, viewport->y, viewport->w, viewport->h);
/* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */
SDL_Rect *viewport = &data->drawstate.viewport;
if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) {
SDL_copyp(viewport, &cmd->data.viewport.rect);
data->drawstate.viewport_dirty = SDL_TRUE;
data->drawstate.cliprect_dirty = SDL_TRUE;
data->drawstate.viewport_is_set = viewport->x != 0 || viewport->y != 0 || viewport->w != data->drawstate.drawablew || viewport->h != data->drawstate.drawableh;
if (!data->drawstate.cliprect_enabled) {
if (data->drawstate.viewport_is_set) {
SDL_copyp(&data->drawstate.cliprect, viewport);
data->drawstate.cliprect.x = 0;
data->drawstate.cliprect.y = 0;
} else {
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
}
}
}
break;
}
case SDL_RENDERCMD_SETCLIPRECT:
{
const SDL_Rect *rect = &cmd->data.cliprect.rect;
if (cmd->data.cliprect.enabled) {
sceGuEnable(GU_SCISSOR_TEST);
sceGuScissor(rect->x, rect->y, rect->w, rect->h);
} else {
sceGuDisable(GU_SCISSOR_TEST);
const SDL_Rect *viewport = &data->drawstate.viewport;
if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
if (!data->drawstate.cliprect_enabled && data->drawstate.viewport_is_set) {
SDL_copyp(&data->drawstate.cliprect, viewport);
data->drawstate.cliprect.x = 0;
data->drawstate.cliprect.y = 0;
}
}
if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) {
SDL_copyp(&data->drawstate.cliprect, rect);
data->drawstate.cliprect_dirty = SDL_TRUE;
}
break;
}
@@ -1087,6 +1236,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
const Uint8 g = cmd->data.color.g;
const Uint8 b = cmd->data.color.b;
const Uint8 a = cmd->data.color.a;
SetDrawState(data);
sceGuClearColor(GU_RGBA(r, g, b, a));
sceGuClearStencil(a);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT);
@@ -1096,7 +1246,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
case SDL_RENDERCMD_DRAW_POINTS:
{
const size_t count = cmd->data.draw.count;
const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
const VertV *verts; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
const Uint8 r = cmd->data.draw.r;
const Uint8 g = cmd->data.draw.g;
const Uint8 b = cmd->data.draw.b;
@@ -1107,6 +1257,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
.mode = cmd->data.draw.blend,
.shadeModel = GU_FLAT
};
SetDrawState(data);
verts = PSP_GetVertV(&data->drawstate, gpumem, cmd, count);
PSP_SetBlendState(data, &state);
sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
break;
@@ -1115,7 +1267,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
case SDL_RENDERCMD_DRAW_LINES:
{
const size_t count = cmd->data.draw.count;
const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
const VertV *verts; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
const Uint8 r = cmd->data.draw.r;
const Uint8 g = cmd->data.draw.g;
const Uint8 b = cmd->data.draw.b;
@@ -1126,6 +1278,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
.mode = cmd->data.draw.blend,
.shadeModel = GU_FLAT
};
SetDrawState(data);
verts = PSP_GetVertV(&data->drawstate, gpumem, cmd, count);
PSP_SetBlendState(data, &state);
sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
break;
@@ -1134,7 +1288,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
case SDL_RENDERCMD_FILL_RECTS:
{
const size_t count = cmd->data.draw.count;
const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
const VertV *verts; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
const Uint8 r = cmd->data.draw.r;
const Uint8 g = cmd->data.draw.g;
const Uint8 b = cmd->data.draw.b;
@@ -1145,6 +1299,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
.mode = cmd->data.draw.blend,
.shadeModel = GU_FLAT
};
SetDrawState(data);
verts = PSP_GetVertV(&data->drawstate, gpumem, cmd, 2 * count);
PSP_SetBlendState(data, &state);
sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2 * count, 0, verts);
break;
@@ -1153,7 +1309,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
case SDL_RENDERCMD_COPY:
{
const size_t count = cmd->data.draw.count;
const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first);
const VertTV *verts; /*= (VertTV *)(gpumem + cmd->data.draw.first);*/
const Uint8 a = cmd->data.draw.a;
const Uint8 r = cmd->data.draw.r;
const Uint8 g = cmd->data.draw.g;
@@ -1164,6 +1320,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
.mode = cmd->data.draw.blend,
.shadeModel = GU_SMOOTH
};
SetDrawState(data);
verts = PSP_GetVertTV(&data->drawstate, gpumem, cmd, 2 * count);
PSP_SetBlendState(data, &state);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2 * count, 0, verts);
break;
@@ -1182,6 +1340,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
.mode = cmd->data.draw.blend,
.shadeModel = GU_SMOOTH
};
SetDrawState(data);
verts = PSP_GetVertTV(&data->drawstate, gpumem, cmd, 4);
PSP_SetBlendState(data, &state);
sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 4, 0, verts);
break;
@@ -1190,14 +1350,15 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
case SDL_RENDERCMD_GEOMETRY:
{
const size_t count = cmd->data.draw.count;
SetDrawState(data);
if (!cmd->data.draw.texture) {
const VertCV *verts = (VertCV *)(gpumem + cmd->data.draw.first);
const VertCV *verts = PSP_GetVertCV(&data->drawstate, gpumem, cmd, count);
sceGuDisable(GU_TEXTURE_2D);
/* In GU_SMOOTH mode */
sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
sceGuEnable(GU_TEXTURE_2D);
} else {
const VertTCV *verts = (VertTCV *)(gpumem + cmd->data.draw.first);
const VertTCV *verts; /*= (VertTCV *)(gpumem + cmd->data.draw.first);*/
const Uint8 a = cmd->data.draw.a;
const Uint8 r = cmd->data.draw.r;
const Uint8 g = cmd->data.draw.g;
@@ -1208,6 +1369,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
.mode = cmd->data.draw.blend,
.shadeModel = GU_FLAT
};
verts = PSP_GetVertTCV(&data->drawstate, gpumem, cmd, count);
TextureActivate(cmd->data.draw.texture);
PSP_SetBlendState(data, &state);
sceGuDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
+1
View File
@@ -399,6 +399,7 @@ struct SDL_VideoDevice
int no_error;
int retained_backing;
int driver_loaded;
int HAS_GL_ARB_color_buffer_float;
char driver_path[256];
void *dll_handle;
} gl_config;
+13
View File
@@ -70,6 +70,10 @@
#include <dlfcn.h>
#endif
#ifndef GL_RGBA_FLOAT_MODE_ARB
#define GL_RGBA_FLOAT_MODE_ARB 0x8820
#endif /* GL_RGBA_FLOAT_MODE_ARB */
/* Available video drivers */
static VideoBootStrap *bootstrap[] = {
#ifdef SDL_VIDEO_DRIVER_COCOA
@@ -4036,6 +4040,15 @@ int SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
*value = _this->gl_config.no_error;
return 0;
}
case SDL_GL_FLOATBUFFERS:
{
if (_this->gl_config.HAS_GL_ARB_color_buffer_float) {
attrib = GL_RGBA_FLOAT_MODE_ARB;
break;
} else {
return 0;
}
}
default:
return SDL_SetError("Unknown OpenGL attribute");
}
+8 -1
View File
@@ -511,6 +511,10 @@ void WIN_GL_InitExtensions(_THIS)
_this->gl_data->HAS_WGL_ARB_create_context_no_error = SDL_TRUE;
}
/* Check for WGL_ARB_pixel_format_float */
_this->gl_data->HAS_WGL_ARB_pixel_format_float =
HasExtension("WGL_ARB_pixel_format_float", extensions);
_this->gl_data->wglMakeCurrent(hdc, NULL);
_this->gl_data->wglDeleteContext(hglrc);
ReleaseDC(hwnd, hdc);
@@ -641,7 +645,7 @@ static int WIN_GL_SetupWindowInternal(_THIS, SDL_Window *window)
*iAttr++ = _this->gl_config.multisamplesamples;
}
if (_this->gl_config.floatbuffers) {
if (_this->gl_data->HAS_WGL_ARB_pixel_format_float && _this->gl_config.floatbuffers) {
*iAttr++ = WGL_PIXEL_TYPE_ARB;
*iAttr++ = WGL_TYPE_RGBA_FLOAT_ARB;
}
@@ -825,6 +829,9 @@ SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window *window)
return NULL;
}
_this->gl_config.HAS_GL_ARB_color_buffer_float =
SDL_GL_ExtensionSupported("GL_ARB_color_buffer_float");
return context;
}
+1
View File
@@ -64,6 +64,7 @@ struct SDL_GLDriverData
SDL_bool HAS_WGL_ARB_context_flush_control;
SDL_bool HAS_WGL_ARB_create_context_robustness;
SDL_bool HAS_WGL_ARB_create_context_no_error;
SDL_bool HAS_WGL_ARB_pixel_format_float;
/* Max version of OpenGL ES context that can be created if the
implementation supports WGL_EXT_create_context_es2_profile.
+3
View File
@@ -67,6 +67,9 @@ static SDL_bool DriverIsProblematic(const char *driver)
*/
"dsp",
/* Jack isn't always configured properly on end user systems */
"jack",
/* OpenBSD sound API. Can be used on Linux, but very rare. */
"sndio",
+83 -33
View File
@@ -88,9 +88,19 @@ int hints_getHint(void *arg)
return TEST_COMPLETED;
}
typedef struct {
char *name;
char *value;
char *oldValue;
} HintCallbackContext;
static void SDLCALL hints_testHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
*(char **)userdata = hint ? SDL_strdup(hint) : NULL;
HintCallbackContext *context = userdata;
context->name = name ? SDL_strdup(name) : NULL;
context->value = hint ? SDL_strdup(hint) : NULL;
context->oldValue = oldValue ? SDL_strdup(oldValue) : NULL;
}
/**
@@ -102,7 +112,7 @@ int hints_setHint(void *arg)
const char *originalValue;
char *value;
const char *testValue;
char *callbackValue;
HintCallbackContext callback_data;
SDL_bool result;
int i, j;
@@ -152,8 +162,10 @@ int hints_setHint(void *arg)
SDLTest_AssertPass("Call to SDL_GetHint() after saving and restoring hint");
originalValue = SDL_GetHint(testHint);
value = (originalValue == NULL) ? NULL : SDL_strdup(originalValue);
SDL_SetHint(testHint, "temp");
SDL_SetHint(testHint, value);
result = SDL_SetHint(testHint, "temp");
SDLTest_AssertCheck(!result, "SDL_SetHint(\"%s\", \"temp\") should return false", testHint);
result = SDL_SetHint(testHint, value);
SDLTest_AssertCheck(!result, "SDL_SetHint(\"%s\", \"%s\" should return false", testHint, value);
SDL_free(value);
testValue = SDL_GetHint(testHint);
SDLTest_AssertCheck(
@@ -162,15 +174,26 @@ int hints_setHint(void *arg)
testValue);
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(NULL, SDL_HINT_DEFAULT)");
SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_DEFAULT);
result = SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_DEFAULT);
SDLTest_AssertCheck(!result, "SDL_SetHintWithPriority(\"%s\", NULL, SDL_HINT_DEFAULT) should return false", testHint);
testValue = SDL_GetHint(testHint);
SDLTest_AssertCheck(
testValue && SDL_strcmp(testValue, "original") == 0,
"testValue = %s, expected \"original\"",
testValue);
SDLTest_AssertPass("Call to SDL_SetHint(\"\", \"data\")");
result = SDL_SetHint("", "data");
SDLTest_AssertCheck(result, "SDL_SetHint(\"\", \"data\") should return true");
testValue = SDL_GetHint("");
SDLTest_AssertCheck(
testValue && SDL_strcmp(testValue, "data") == 0,
"testValue = %s, expected \"data\"",
testValue);
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE)");
SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
result = SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", \"temp\", SDL_HINT_OVERRIDE) should return true", testHint);
testValue = SDL_GetHint(testHint);
SDLTest_AssertCheck(
testValue && SDL_strcmp(testValue, "temp") == 0,
@@ -178,7 +201,8 @@ int hints_setHint(void *arg)
testValue);
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(NULL, SDL_HINT_OVERRIDE)");
SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_OVERRIDE);
result = SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_OVERRIDE);
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", NULL, SDL_HINT_OVERRIDE) should return true", testHint);
testValue = SDL_GetHint(testHint);
SDLTest_AssertCheck(
testValue == NULL,
@@ -194,49 +218,75 @@ int hints_setHint(void *arg)
testValue);
/* Make sure callback functionality works past a reset */
SDL_zero(callback_data);
SDLTest_AssertPass("Call to SDL_AddHintCallback()");
callbackValue = NULL;
SDL_AddHintCallback(testHint, hints_testHintChanged, &callbackValue);
SDL_AddHintCallback(testHint, hints_testHintChanged, &callback_data);
SDLTest_AssertCheck(
callbackValue && SDL_strcmp(callbackValue, "original") == 0,
"callbackValue = %s, expected \"original\"",
callbackValue);
SDL_free(callbackValue);
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE), using callback");
callbackValue = NULL;
SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
callback_data.name && SDL_strcmp(callback_data.name, testHint) == 0,
"callback_data.name = \"%s\", expected \"%s\"",
callback_data.name, testHint);
SDLTest_AssertCheck(
callbackValue && SDL_strcmp(callbackValue, "temp") == 0,
"callbackValue = %s, expected \"temp\"",
callbackValue);
SDL_free(callbackValue);
callback_data.value && SDL_strcmp(callback_data.value, "original") == 0,
"callback_data.value = \"%s\", expected \"%s\"",
callback_data.value, "original");
SDL_free(callback_data.name);
SDL_free(callback_data.value);
SDL_free(callback_data.oldValue);
SDLTest_AssertPass("Call to SDL_ResetHint(), using callback");
callbackValue = NULL;
SDL_zero(callback_data);
SDL_ResetHint(testHint);
SDLTest_AssertCheck(
callbackValue && SDL_strcmp(callbackValue, "original") == 0,
callback_data.value && SDL_strcmp(callback_data.value, "original") == 0,
"callbackValue = %s, expected \"original\"",
callbackValue);
callback_data.value);
SDL_free(callback_data.name);
SDL_free(callback_data.value);
SDL_free(callback_data.oldValue);
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE), using callback after reset");
callbackValue = NULL;
SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
SDL_zero(callback_data);
result = SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", \"temp\", SDL_HINT_OVERRIDE) should return true", testHint);
SDLTest_AssertCheck(
callbackValue && SDL_strcmp(callbackValue, "temp") == 0,
callback_data.value && SDL_strcmp(callback_data.value, "temp") == 0,
"callbackValue = %s, expected \"temp\"",
callbackValue);
SDL_free(callbackValue);
callback_data.value);
SDL_free(callback_data.name);
SDL_free(callback_data.value);
SDL_free(callback_data.oldValue);
SDLTest_AssertPass("Call to SDL_ResetHint(), after clearing callback");
callbackValue = NULL;
SDL_DelHintCallback(testHint, hints_testHintChanged, &callbackValue);
SDL_zero(callback_data);
SDL_DelHintCallback(testHint, hints_testHintChanged, &callback_data);
SDL_ResetHint(testHint);
SDLTest_AssertCheck(
callbackValue == NULL,
!callback_data.value,
"callbackValue = %s, expected \"(null)\"",
callbackValue);
callback_data.value);
SDL_free(callback_data.name);
SDL_free(callback_data.value);
SDL_free(callback_data.oldValue);
/* Make sure callback functionality work with hint renamed in sdl3 */
SDLTest_AssertPass("Call to SDL_AddHintCallback()");
SDL_AddHintCallback(SDL_HINT_ALLOW_TOPMOST, hints_testHintChanged, &callback_data);
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE), using callback");
SDL_zero(callback_data);
result = SDL_SetHintWithPriority(SDL_HINT_ALLOW_TOPMOST, "temp", SDL_HINT_OVERRIDE);
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", \"temp\", SDL_HINT_OVERRIDE) should return true", testHint);
SDLTest_AssertCheck(
callback_data.name && SDL_strcmp(callback_data.name, SDL_HINT_ALLOW_TOPMOST) == 0,
"callback_data.name = \"%s\", expected \"%s\"",
callback_data.name, SDL_HINT_ALLOW_TOPMOST);
SDLTest_AssertCheck(
callback_data.value && SDL_strcmp(callback_data.value, "temp") == 0,
"callback_data.value = \"%s\", expected \"%s\"",
callback_data.value, "temp");
SDL_free(callback_data.name);
SDL_free(callback_data.value);
SDL_free(callback_data.oldValue);
SDL_ResetHint(testHint);
return TEST_COMPLETED;
}
+279 -6
View File
@@ -12,6 +12,38 @@
/* Helper functions */
/* !
* \brief Private helper to check SDL_FRect equality
*/
static SDL_bool IsFRectEqual(const SDL_FRect *r1, const SDL_FRect *r2) {
static const float MAX_DELTA = 1e-5f;
SDL_FRect delta;
delta.x = r1->x - r2->x;
delta.y = r1->y - r2->y;
delta.w = r1->w - r2->w;
delta.h = r1->h - r2->h;
return -MAX_DELTA <= delta.x && delta.x <= MAX_DELTA
&& -MAX_DELTA <= delta.y && delta.y <= MAX_DELTA
&& -MAX_DELTA <= delta.w && delta.w <= MAX_DELTA
&& -MAX_DELTA <= delta.w && delta.h <= MAX_DELTA;
}
/* !
* \brief Private helper to check SDL_FPoint equality
*/
static SDL_bool IsFPointEqual(const SDL_FPoint *p1, const SDL_FPoint *p2) {
static const float MAX_DELTA = 1e-5f;
SDL_FPoint delta;
delta.x = p1->x - p2->x;
delta.y = p1->y - p2->y;
return -MAX_DELTA <= delta.x && delta.x <= MAX_DELTA
&& -MAX_DELTA <= delta.y && delta.y <= MAX_DELTA;
}
/* Helper functions */
/* !
* \brief Private helper to check SDL_IntersectRectAndLine results
*/
@@ -701,8 +733,8 @@ int rect_testIntersectRectEmpty(void *arg)
*/
int rect_testIntersectRectParam(void *arg)
{
SDL_Rect rectA;
SDL_Rect rectB = { 0 };
const SDL_Rect rectA = { 0, 0, 32, 32 };
const SDL_Rect rectB = { 0, 0, 32, 32 };
SDL_Rect result;
SDL_bool intersection;
@@ -956,8 +988,8 @@ int rect_testHasIntersectionEmpty(void *arg)
*/
int rect_testHasIntersectionParam(void *arg)
{
SDL_Rect rectA;
SDL_Rect rectB = { 0 };
const SDL_Rect rectA = { 0, 0, 32, 32 };
const SDL_Rect rectB = { 0, 0, 32, 32 };
SDL_bool intersection;
/* invalid parameter combinations */
@@ -1492,7 +1524,8 @@ int rect_testUnionRectInside(void *arg)
*/
int rect_testUnionRectParam(void *arg)
{
SDL_Rect rectA, rectB = { 0 };
const SDL_Rect rectA = { 0, 0, 32, 32 };
const SDL_Rect rectB = { 0, 0, 32, 32 };
SDL_Rect result;
/* invalid parameter combinations */
@@ -1698,6 +1731,226 @@ int rect_testFRectEqualsParam(void *arg)
return TEST_COMPLETED;
}
/* !
* \brief Test SDL_HasIntersectionF
*
* \sa
* http://wiki.libsdl.org/SDL2/SDL_HasIntersectionF
*/
int rect_testHasIntersectionF(void *arg)
{
const struct {
SDL_FRect r1;
SDL_FRect r2;
SDL_bool expected;
} cases[] = {
{ { 0, 0, 0, 0 }, {0, 0, 0, 0}, SDL_FALSE },
{ { 0, 0, -200, 200 }, {0, 0, -200, 200}, SDL_FALSE },
{ { 0, 0, 10, 10 }, {-5, 5, 10, 2}, SDL_TRUE },
{ { 0, 0, 10, 10 }, {-5, -5, 10, 2}, SDL_FALSE },
{ { 0, 0, 10, 10 }, {-5, -5, 2, 10}, SDL_FALSE },
{ { 0, 0, 10, 10 }, {-5, -5, 5, 5}, SDL_FALSE },
{ { 0, 0, 10, 10 }, {-5, -5, 5.1f, 5.1f}, SDL_TRUE },
{ { 0, 0, 10, 10 }, {-4.99f, -4.99f, 5, 5}, SDL_TRUE },
};
size_t i;
for (i = 0; i < SDL_arraysize(cases); i++) {
SDL_bool result;
SDLTest_AssertPass("About to call SDL_HasIntersectionF(&{ %g, %g, %g, %g }, &{ %g, %g, %g, %g })",
cases[i].r1.x, cases[i].r1.y, cases[i].r1.w, cases[i].r1.h,
cases[i].r2.x, cases[i].r2.y, cases[i].r2.w, cases[i].r2.h
);
result = SDL_HasIntersectionF(&cases[i].r1, &cases[i].r2);
SDLTest_AssertCheck(result == cases[i].expected, "Got %d, expected %d", result, cases[i].expected);
}
return TEST_COMPLETED;
}
/* !
* \brief Test SDL_IntersectFRect
*
* \sa
* http://wiki.libsdl.org/SDL2/SDL_IntersectFRect
*/
int rect_testIntersectFRect(void *arg)
{
const struct {
SDL_FRect r1;
SDL_FRect r2;
SDL_bool result;
SDL_FRect intersect;
} cases[] = {
{ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, SDL_FALSE },
{ { 0, 0, -200, 200 }, { 0, 0, -200, 200 }, SDL_FALSE },
{ { 0, 0, 10, 10 }, { -5, 5, 9.9f, 2 }, SDL_TRUE, { 0, 5, 4.9f, 2 } },
{ { 0, 0, 10, 10 }, { -5, -5, 10, 2 }, SDL_FALSE},
{ { 0, 0, 10, 10 }, { -5, -5, 2, 10 }, SDL_FALSE},
{ { 0, 0, 10, 10 }, { -5, -5, 5, 5 }, SDL_FALSE},
{ { 0, 0, 10, 10 }, { -5, -5, 5.5f, 6 }, SDL_TRUE, { 0, 0, 0.5f, 1 } }
};
size_t i;
for (i = 0; i < SDL_arraysize(cases); i++) {
SDL_bool result;
SDL_FRect intersect;
SDLTest_AssertPass("About to call SDL_IntersectFRect(&{ %g, %g, %g, %g }, &{ %g, %g, %g, %g })",
cases[i].r1.x, cases[i].r1.y, cases[i].r1.w, cases[i].r1.h,
cases[i].r2.x, cases[i].r2.y, cases[i].r2.w, cases[i].r2.h
);
result = SDL_IntersectFRect(&cases[i].r1, &cases[i].r2, &intersect);
SDLTest_AssertCheck(result == cases[i].result, "Got %d, expected %d", result, cases[i].result);
if (cases[i].result) {
SDLTest_AssertCheck(IsFRectEqual(&intersect, &cases[i].intersect),
"Got { %g, %g, %g, %g }, expected { %g, %g, %g, %g }",
intersect.x, intersect.y, intersect.w, intersect.h,
cases[i].intersect.x, cases[i].intersect.y, cases[i].intersect.w, cases[i].intersect.h);
}
}
return TEST_COMPLETED;
}
/* !
* \brief Test SDL_UnionFRect
*
* \sa
* http://wiki.libsdl.org/SDL2/SDL_UnionFRect
*/
int rect_testUnionFRect(void *arg)
{
const struct {
SDL_FRect r1;
SDL_FRect r2;
SDL_FRect expected;
} cases[] = {
{ { 0, 0, 10, 10 }, { 19.9f, 20, 10, 10 }, { 0, 0, 29.9f, 30 } },
{ { 0, 0, 0, 0 }, { 20, 20.1f, 10.1f, 10 }, { 20, 20.1f, 10.1f, 10 } },
{ { -200, -4.5f, 450, 33 }, { 20, 20, 10, 10 }, { -200, -4.5f, 450, 34.5f } },
{ { 0, 0, 15, 16.5f }, { 20, 20, 0, 0 }, { 0, 0, 15, 16.5f } }
};
size_t i;
for (i = 0; i < SDL_arraysize(cases); i++) {
SDL_FRect result;
SDLTest_AssertPass("About to call SDL_UnionFRect(&{ %g, %g, %g, %g }, &{ %g, %g, %g, %g })",
cases[i].r1.x, cases[i].r1.y, cases[i].r1.w, cases[i].r1.h,
cases[i].r2.x, cases[i].r2.y, cases[i].r2.w, cases[i].r2.h
);
SDL_UnionFRect(&cases[i].r1, &cases[i].r2, &result);
SDLTest_AssertCheck(IsFRectEqual(&result, &cases[i].expected),
"Got { %g, %g, %g, %g }, expected { %g, %g, %g, %g }",
result.x, result.y, result.w, result.h,
cases[i].expected.x, cases[i].expected.y, cases[i].expected.w, cases[i].expected.h);
}
return TEST_COMPLETED;
}
/* !
* \brief Test SDL_EncloseFPointsUnionFRect
*
* \sa
* http://wiki.libsdl.org/SDL2/SDL_EncloseFPoints
*/
int rect_testEncloseFPoints(void *arg)
{
const struct {
SDL_bool with_clip;
SDL_FRect clip;
SDL_bool result;
SDL_FRect enclosing;
} cases[] = {
{ SDL_TRUE, { 0, 0, 10, 10 }, SDL_TRUE, { 0.5f, 0.1f, 6, 8 }},
{ SDL_TRUE, { 1.2f, 1, 10, 10 }, SDL_TRUE, { 1.5f, 1.1f, 5, 7 }},
{ SDL_TRUE, { -10, -10, 3, 3 }, SDL_FALSE },
{ SDL_FALSE, { 0 }, SDL_TRUE, { 0.5, 0.1f, 6, 8 }}
};
const SDL_FPoint points[] = {
{ 0.5f, 0.1f },
{ 5.5f, 7.1f },
{ 1.5f, 1.1f }
};
char points_str[256];
size_t i;
SDL_strlcpy(points_str, "{", sizeof(points_str));
for (i = 0; i < SDL_arraysize(points); i++) {
char point_str[32];
SDL_snprintf(point_str, sizeof(point_str), "{ %g, %g }, ", points[i].x, points[i].y);
SDL_strlcat(points_str, point_str, sizeof(points_str));
}
SDL_strlcat(points_str, "}", sizeof(points_str));
for (i = 0; i < SDL_arraysize(cases); i++) {
char clip_str[64];
SDL_bool result;
SDL_FRect enclosing;
const SDL_FRect* clip_ptr = NULL;
if (cases[i].with_clip) {
SDL_snprintf(clip_str, sizeof(clip_str), "&{ %g, %g, %g, %g }",
cases[i].clip.x, cases[i].clip.y, cases[i].clip.w, cases[i].clip.h);
clip_ptr = &cases[i].clip;
} else {
SDL_strlcpy(clip_str, "NULL", sizeof(clip_str));
}
SDLTest_AssertPass("About to call SDL_EncloseFPoints(&%s, %d, %s)", points_str, (int)SDL_arraysize(points), clip_str);
result = SDL_EncloseFPoints(points, SDL_arraysize(points), clip_ptr, &enclosing);
SDLTest_AssertCheck(result == cases[i].result, "Got %d, expected %d", result, cases[i].result);
if (cases[i].result) {
SDLTest_AssertCheck(IsFRectEqual(&enclosing, &cases[i].enclosing),
"Got { %g, %g, %g, %g }, expected { %g, %g, %g, %g }",
enclosing.x, enclosing.y, enclosing.w, enclosing.h,
cases[i].enclosing.x, cases[i].enclosing.y, cases[i].enclosing.w, cases[i].enclosing.h);
}
}
return TEST_COMPLETED;
}
/* !
* \brief Test SDL_IntersectFRectAndLine
*
* \sa
* http://wiki.libsdl.org/SDL2/SDL_IntersectFRectAndLine
*/
int rect_testIntersectFRectAndLine(void *arg)
{
const struct {
SDL_FRect rect;
SDL_FPoint p1;
SDL_FPoint p2;
SDL_bool result;
SDL_FPoint expected1;
SDL_FPoint expected2;
} cases[] = {
{ { 0, 0, 0, 0 }, { -4.8f, -4.8f }, { 5.2f, 5.2f }, SDL_FALSE },
{ { 0, 0, 2, 2 }, { -1, -1 }, { 3.5f, 3.5f }, SDL_TRUE, { 0, 0 }, { 1, 1 } },
{ { -4, -4, 14, 14 }, { 8, 22 }, { 8, 33}, SDL_FALSE }
};
size_t i;
for (i = 0; i < SDL_arraysize(cases); i++) {
SDL_bool result;
SDL_FPoint p1 = cases[i].p1;
SDL_FPoint p2 = cases[i].p2;
SDLTest_AssertPass("About to call SDL_IntersectFRectAndLine(&{%g, %g, %g, %g}, &%g, &%g, &%g, &%g)",
cases[i].rect.x, cases[i].rect.y, cases[i].rect.w, cases[i].rect.h,
p1.x, p1.y, p2.x, p2.y);
result = SDL_IntersectFRectAndLine(&cases[i].rect, &p1.x, &p1.y, &p2.x, &p2.y);
SDLTest_AssertCheck(result == cases[i].result, "Got %d, expected %d", result, cases[i].result);
if (cases[i].result) {
SDLTest_AssertCheck(IsFPointEqual(&p1, &cases[i].expected1),
"Got p1={ %g, %g }, expected p1={ %g, %g }",
p1.x, p1.y,
cases[i].expected1.x, cases[i].expected1.y);
SDLTest_AssertCheck(IsFPointEqual(&p2, &cases[i].expected2),
"Got p2={ %g, %g }, expected p2={ %g, %g }",
p2.x, p2.y,
cases[i].expected2.x, cases[i].expected2.y);
}
}
return TEST_COMPLETED;
}
/* ================= Test References ================== */
/* Rect test cases */
@@ -1836,6 +2089,26 @@ static const SDLTest_TestCaseReference rectTest31 = {
(SDLTest_TestCaseFp)rect_testFRectEqualsParam, "rect_testFRectEqualsParam", "Negative tests against SDL_FRectEquals with invalid parameters", TEST_ENABLED
};
static const SDLTest_TestCaseReference rectTest32 = {
(SDLTest_TestCaseFp)rect_testHasIntersectionF, "rect_testHasIntersectionF", "Tests SDL_HasIntersectionF", TEST_ENABLED
};
static const SDLTest_TestCaseReference rectTest33 = {
(SDLTest_TestCaseFp)rect_testIntersectFRect, "rect_testIntersectFRect", "Tests SDL_IntersectFRect", TEST_ENABLED
};
static const SDLTest_TestCaseReference rectTest34 = {
(SDLTest_TestCaseFp)rect_testUnionFRect, "rect_testUnionFRect", "Tests SDL_UnionFRect", TEST_ENABLED
};
static const SDLTest_TestCaseReference rectTest35 = {
(SDLTest_TestCaseFp)rect_testEncloseFPoints, "rect_testEncloseFPoints", "Tests SDL_EncloseFPoints", TEST_ENABLED
};
static const SDLTest_TestCaseReference rectTest36 = {
(SDLTest_TestCaseFp)rect_testIntersectFRectAndLine, "rect_testIntersectFRectAndLine", "Tests SDL_IntersectFRectAndLine", TEST_ENABLED
};
/* !
* \brief Sequence of Rect test cases; functions that handle simple rectangles including overlaps and merges.
*
@@ -1845,7 +2118,7 @@ static const SDLTest_TestCaseReference rectTest31 = {
static const SDLTest_TestCaseReference *rectTests[] = {
&rectTest1, &rectTest2, &rectTest3, &rectTest4, &rectTest5, &rectTest6, &rectTest7, &rectTest8, &rectTest9, &rectTest10, &rectTest11, &rectTest12, &rectTest13, &rectTest14,
&rectTest15, &rectTest16, &rectTest17, &rectTest18, &rectTest19, &rectTest20, &rectTest21, &rectTest22, &rectTest23, &rectTest24, &rectTest25, &rectTest26, &rectTest27,
&rectTest28, &rectTest29, &rectTest30, &rectTest31, NULL
&rectTest28, &rectTest29, &rectTest30, &rectTest31, &rectTest32, &rectTest33, &rectTest34, &rectTest35, &rectTest36, NULL
};
/* Rect test suite (global) */
+139 -1
View File
@@ -811,6 +811,136 @@ int render_testBlitBlend(void *arg)
return TEST_COMPLETED;
}
static Uint32 read_surface_pixel32(SDL_Surface *surface, int x, int y) {
Uint32 result;
if (x >= surface->w || y >= surface->h) {
SDLTest_AssertCheck(x < surface->w, "x (%d) < surface->w (%d)", x, surface->w);
SDLTest_AssertCheck(y < surface->h, "y (%d) < surface->h (%d)", y, surface->h);
result = 0xdeadbabe;
} else {
SDL_memcpy(&result, (Uint8 *)surface->pixels + surface->pitch * y + surface->format->BytesPerPixel * x, sizeof(Uint32));
}
return result;
}
static int render_testRGBSurfaceNoAlpha(void* arg)
{
SDL_Surface *surface;
SDL_Renderer *software_renderer;
SDL_Surface *surface2;
SDL_Texture *texture2;
int result;
SDL_Rect dest_rect;
SDL_Point point;
Uint32 pixel;
SDLTest_AssertPass("About to call SDL_CreateRGBSurface(0, 128, 128, 32, 0xff0000, 0xff00, 0xff, 0)");
surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0xff0000, 0xff00, 0xff, 0);
SDLTest_AssertCheck(surface != NULL, "Returned surface must be not NULL");
SDLTest_AssertCheck(surface->format->BitsPerPixel == 32, "surface->format->BitsPerPixel should be 32, actual value is %d", surface->format->BitsPerPixel);
SDLTest_AssertCheck(surface->format->BytesPerPixel == 4, "surface->format->BytesPerPixels should be 4, actual value is %d", surface->format->BytesPerPixel);
SDLTest_AssertPass("About to call SDL_CreateSoftwareRenderer(surface)");
software_renderer = SDL_CreateSoftwareRenderer(surface);
SDLTest_AssertCheck(software_renderer != NULL, "Returned renderer must be not NULL");
SDLTest_AssertPass("About to call SDL_CreateRGBSurface(0, 16, 16, 32, 0xff0000, 0xff00, 0xff, 0)");
surface2 = SDL_CreateRGBSurface(0, 16, 16, 32, 0xff0000, 0xff00, 0xff, 0);
SDLTest_AssertCheck(surface2 != NULL, "Returned surface must be not NULL");
SDLTest_AssertPass("About to call SDL_FillRect(surface2, NULL, 0)");
result = SDL_FillRect(surface2, NULL, SDL_MapRGB(surface2->format, 0, 0, 0));
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
SDLTest_AssertPass("About to call SDL_CreateTextureFromSurface(software_renderer, surface2)");
texture2 = SDL_CreateTextureFromSurface(software_renderer, surface2);
SDLTest_AssertCheck(texture2 != NULL, "Returned texture is not NULL");
SDLTest_AssertPass("About to call SDL_SetRenderDrawColor(renderer, 0xaa, 0xbb, 0xcc, 0x0)");
result = SDL_SetRenderDrawColor(software_renderer, 0xaa, 0xbb, 0xcc, 0x0);
SDLTest_AssertPass("About to call SDL_RenderClear(renderer)");
result = SDL_RenderClear(software_renderer);
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
SDLTest_AssertPass("About to call SDL_SetRenderDrawColor(renderer, 0x0, 0x0, 0x0, 0x0)");
result = SDL_SetRenderDrawColor(software_renderer, 0x0, 0x0, 0x0, 0x0);
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
dest_rect.x = 32;
dest_rect.y = 32;
dest_rect.w = surface2->w;
dest_rect.h = surface2->h;
point.x = 0;
point.y = 0;
SDLTest_AssertPass("About to call SDL_RenderCopy(software_renderer, texture, NULL, &{%d, %d, %d, %d})",
dest_rect.x, dest_rect.h, dest_rect.w, dest_rect.h);
result = SDL_RenderCopyEx(software_renderer, texture2, NULL, &dest_rect, 180, &point, SDL_FLIP_NONE);
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
SDLTest_AssertPass("About to call SDL_RenderPresent(software_renderer)");
SDL_RenderPresent(software_renderer);
pixel = read_surface_pixel32(surface, 0, 0);
SDLTest_AssertCheck(pixel == 0xAABBCCu, "Pixel at (0, 0) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xAABBCCu, pixel);
pixel = read_surface_pixel32(surface, 15, 15);
SDLTest_AssertCheck(pixel == 0xAABBCCu, "Pixel at (15, 15) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xAABBCCu, pixel);
pixel = read_surface_pixel32(surface, 16, 16);
SDLTest_AssertCheck(pixel == 0xFF000000u, "Pixel at (16, 16) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xFF000000u, pixel);
pixel = read_surface_pixel32(surface, 31, 31);
SDLTest_AssertCheck(pixel == 0xFF000000u, "Pixel at (31, 31) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xFF000000u, pixel);
pixel = read_surface_pixel32(surface, 32, 32);
SDLTest_AssertCheck(pixel == 0xAABBCCu, "Pixel at (32, 32) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xAABBCCu, pixel);
SDL_DestroyTexture(texture2);
SDL_FreeSurface(surface2);
SDL_DestroyRenderer(software_renderer);
SDL_FreeSurface(surface);
return TEST_COMPLETED;
}
/**
* @brief Tests setting and getting texture scale mode.
*
* \sa
* http://wiki.libsdl.org/SDL2/SDL_SetTextureScaleMode
* http://wiki.libsdl.org/SDL2/SDL_GetTextureScaleMode
*/
int render_testGetSetTextureScaleMode(void *arg)
{
const struct {
const char *name;
SDL_ScaleMode mode;
} modes[] = {
{ "SDL_ScaleModeNearest", SDL_ScaleModeNearest },
{ "SDL_ScaleModeLinear", SDL_ScaleModeLinear },
{ "SDL_ScaleModeBest", SDL_ScaleModeBest }
};
size_t i;
for (i = 0; i < SDL_arraysize(modes); i++) {
SDL_Texture *texture;
int result;
SDL_ScaleMode actual_mode = SDL_ScaleModeNearest;
SDL_ClearError();
SDLTest_AssertPass("About to call SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 16, 16)");
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 16, 16);
SDLTest_AssertCheck(texture != NULL, "SDL_CreateTexture must return a non-NULL texture");
SDLTest_AssertPass("About to call SDL_SetTextureScaleMode(texture, %s)", modes[i].name);
result = SDL_SetTextureScaleMode(texture, modes[i].mode);
SDLTest_AssertCheck(result == 0, "SDL_SetTextureScaleMode must return 0, actual %d", result);
SDLTest_AssertPass("About to call SDL_GetTextureScaleMode(texture)");
result = SDL_GetTextureScaleMode(texture, &actual_mode);
SDLTest_AssertCheck(result == 0, "SDL_SetTextureScaleMode must return 0, actual %d", result);
SDLTest_AssertCheck(actual_mode == modes[i].mode, "SDL_GetTextureScaleMode must return %s (%d), actual=%d",
modes[i].name, modes[i].mode, actual_mode);
}
return TEST_COMPLETED;
}
/**
* @brief Checks to see if functionality is supported. Helper function.
*/
@@ -1161,9 +1291,17 @@ static const SDLTest_TestCaseReference renderTest7 = {
(SDLTest_TestCaseFp)render_testBlitBlend, "render_testBlitBlend", "Tests blitting with blending", TEST_DISABLED
};
static const SDLTest_TestCaseReference renderTest8 = {
(SDLTest_TestCaseFp)render_testGetSetTextureScaleMode, "render_testGetSetTextureScaleMode", "Tests setting/getting texture scale mode", TEST_ENABLED
};
static const SDLTest_TestCaseReference renderTest9 = {
(SDLTest_TestCaseFp)render_testRGBSurfaceNoAlpha, "render_testRGBSurfaceNoAlpha", "Tests RGB surface with no alpha using software renderer", TEST_ENABLED
};
/* Sequence of Render test cases */
static const SDLTest_TestCaseReference *renderTests[] = {
&renderTest1, &renderTest2, &renderTest3, &renderTest4, &renderTest5, &renderTest6, &renderTest7, NULL
&renderTest1, &renderTest2, &renderTest3, &renderTest4, &renderTest5, &renderTest6, &renderTest7, &renderTest8, &renderTest9, NULL
};
/* Render test suite (global) */
+41 -1
View File
@@ -208,6 +208,42 @@ static int subsystems_dependRefCountWithExtraInit(void)
return TEST_COMPLETED;
}
/**
* \brief Inits and Quits timers subsystem, which cannot be explicitly initialized in SDL3
*
* \sa SDL_InitSubSystem
* \sa SDL_QuitSubSystem
*
*/
static int subsystems_timersSubsystem(void)
{
int result;
/* Ensure that we start with reset subsystems. */
SDLTest_AssertCheck(SDL_WasInit(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS) == 0,
"Check result from SDL_WasInit(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS)");
SDLTest_AssertPass("About to call SDL_WasInit(0)");
result = SDL_WasInit(0);
SDLTest_AssertCheck(result == 0, "SDL_WasInit(0) should return 0, actual 0x%x", result);
SDLTest_AssertPass("About to call SDL_InitSubSystem(SDL_INIT_TIMER)");
result = SDL_InitSubSystem(SDL_INIT_TIMER);
SDLTest_AssertCheck(result == 0, "Must return 0, actually %d", result);
SDLTest_AssertPass("About to call SDL_WasInit(SDL_INIT_TIMER)");
result = SDL_WasInit(SDL_INIT_TIMER);
SDLTest_AssertCheck(result == SDL_INIT_TIMER, "Must return SDL_INIT_TIMER (=%d), actually %d", SDL_INIT_TIMER, result);
SDLTest_AssertPass("About to call SDL_WasInit(0)");
result = SDL_WasInit(0);
SDLTest_AssertCheck(result == SDL_INIT_TIMER, "SDL_WasInit(0) should return SDL_INIT_TIMER, actual 0x%x", result);
SDLTest_AssertPass("About to call SDL_QuitSubSystem(SDL_INIT_TIMER)");
SDL_QuitSubSystem(SDL_INIT_TIMER);
SDLTest_AssertPass("SDL_QuitSubSystem finished");
return TEST_COMPLETED;
}
/* ================= Test References ================== */
/* Subsystems test cases */
@@ -227,9 +263,13 @@ static const SDLTest_TestCaseReference subsystemsTest4 = {
(SDLTest_TestCaseFp)subsystems_dependRefCountWithExtraInit, "subsystems_dependRefCountWithExtraInit", "Check reference count of subsystem dependencies.", TEST_ENABLED
};
static const SDLTest_TestCaseReference subsystemsTest5 = {
(SDLTest_TestCaseFp)subsystems_timersSubsystem, "subsystems_timersSubsystem", "Check timer subsystem, removed in SDL3.", TEST_ENABLED
};
/* Sequence of Events test cases */
static const SDLTest_TestCaseReference *subsystemsTests[] = {
&subsystemsTest1, &subsystemsTest2, &subsystemsTest3, &subsystemsTest4, NULL
&subsystemsTest1, &subsystemsTest2, &subsystemsTest3, &subsystemsTest4, &subsystemsTest5, NULL
};
/* Events test suite (global) */
+57 -1
View File
@@ -798,6 +798,56 @@ int surface_testOverflow(void *arg)
return TEST_COMPLETED;
}
static int surface_testSetGetClipRect(void *args)
{
const struct {
SDL_Rect r;
SDL_bool clipsetval;
SDL_bool cmpval;
} rect_list[] = {
{ { 0, 0, 0, 0}, SDL_FALSE, SDL_TRUE},
{ { 2, 2, 0, 0}, SDL_FALSE, SDL_TRUE},
{ { 2, 2, 5, 1}, SDL_TRUE, SDL_TRUE},
{ { 6, 5, 10, 3}, SDL_TRUE, SDL_FALSE},
{ { 0, 0, 10, 10}, SDL_TRUE, SDL_TRUE},
{ { 0, 0, -10, 10}, SDL_FALSE, SDL_TRUE},
{ { 0, 0, -10, -10}, SDL_FALSE, SDL_TRUE},
{ { -10, -10, 10, 10}, SDL_FALSE, SDL_FALSE},
{ { 10, -10, 10, 10}, SDL_FALSE, SDL_FALSE},
{ { 10, 10, 10, 10}, SDL_TRUE, SDL_FALSE}
};
SDL_Surface *s;
SDL_Rect r;
int i;
SDLTest_AssertPass("About to call SDL_CreateRGBSurface(0, 15, 15, 32, 0, 0, 0, 0)");
s = SDL_CreateRGBSurface(0, 15, 15, 32, 0, 0, 0, 0);
SDLTest_AssertCheck(s != NULL, "SDL_CreateRGBSurface returned non-null surface");
SDL_zero(r);
SDL_GetClipRect(s, &r);
SDLTest_AssertCheck(r.x == 0 && r.y == 0 && r.w == 15 && r.h == 15,
"SDL_GetClipRect of just-created surface. Got {%d, %d, %d, %d}. (Expected {%d, %d, %d, %d})",
r.x, r.y, r.w, r.h, 0, 0, 15, 15);
for (i = 0; i < SDL_arraysize(rect_list); i++) {
SDL_bool b;
const SDL_Rect *r_in = &rect_list[i].r;
SDL_Rect r_out;
SDLTest_AssertPass("About to do SDL_SetClipRect({%d, %d, %d, %d})", r_in->x, r_in->y, r_in->w, r_in->h);
b = SDL_SetClipRect(s, r_in);
SDLTest_AssertCheck(b == rect_list[i].clipsetval, "SDL_SetClipRect returned %d (expected %d)", b, rect_list[i].clipsetval);
SDL_zero(r_out);
SDL_GetClipRect(s, &r_out);
SDLTest_AssertPass("SDL_GetClipRect returned {%d, %d, %d, %d}", r_out.x, r_out.y, r_out.w, r_out.h);
b = r_out.x == r_in->x && r_out.y == r_in->y && r_out.w == r_in->w && r_out.h == r_in->h;
SDLTest_AssertCheck(b == rect_list[i].cmpval, "Current clipping rect is identical to input clipping rect: %d (expected %d)",
b, rect_list[i].cmpval);
}
SDL_FreeSurface(s);
return TEST_COMPLETED;
};
/* ================= Test References ================== */
/* Surface test cases */
@@ -856,11 +906,17 @@ static const SDLTest_TestCaseReference surfaceTestOverflow = {
surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTestSetGetClipRect = {
surface_testSetGetClipRect, "surface_testSetGetClipRect", "Test SDL_(Set|Get)ClipRect.", TEST_ENABLED
};
/* Sequence of Surface test cases */
static const SDLTest_TestCaseReference *surfaceTests[] = {
&surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5,
&surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10,
&surfaceTest11, &surfaceTest12, &surfaceTestOverflow, NULL
&surfaceTest11, &surfaceTest12, &surfaceTestOverflow,
&surfaceTestSetGetClipRect,
NULL
};
/* Surface test suite (global) */
+31 -1
View File
@@ -2251,6 +2251,33 @@ static int video_getWindowSurface(void *arg)
return TEST_COMPLETED;
}
/**
* Tests SDL_SetWindowInputFocus
*/
static int video_setWindowInputFocus(void *arg)
{
int result;
SDL_Window *window;
SDLTest_AssertPass("SDL_SetWindowInputFocus is not supported on dummy and SDL2 wayland driver");
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "dummy") == 0 || SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
return TEST_SKIPPED;
}
window = _createVideoSuiteTestWindow("video_setWindowInputFocus");
if (!window) {
return TEST_ABORTED;
}
SDLTest_AssertPass("About to call SDL_SetWindowInputFocus(window)");
result = SDL_SetWindowInputFocus(window);
SDLTest_AssertCheck(result == 0, "Result is %d, expected 0", result);
_destroyVideoSuiteTestWindow(window);
return TEST_COMPLETED;
}
/* ================= Test References ================== */
/* Video test cases */
@@ -2338,6 +2365,9 @@ static const SDLTest_TestCaseReference videoTest24 =
static const SDLTest_TestCaseReference videoTest25 = {
(SDLTest_TestCaseFp)video_getWindowSurface, "video_getWindowSurface", "Checks window surface functionality", TEST_ENABLED
};
static const SDLTest_TestCaseReference videoTest26 = {
(SDLTest_TestCaseFp)video_setWindowInputFocus, "video_setWindowInputFocus", "Checks window input focus", TEST_ENABLED
};
/* Sequence of Video test cases */
static const SDLTest_TestCaseReference *videoTests[] = {
@@ -2345,7 +2375,7 @@ static const SDLTest_TestCaseReference *videoTests[] = {
&videoTest7, &videoTest8, &videoTest9, &videoTest10, &videoTest11, &videoTest12,
&videoTest13, &videoTest14, &videoTest15, &videoTest16, &videoTest17,
&videoTest18, &videoTest19, &videoTest20, &videoTest21, &videoTest22,
&videoTest23, &videoTest24, &videoTest25, NULL
&videoTest23, &videoTest24, &videoTest25, &videoTest26, NULL
};
/* Video test suite (global) */