This fixes rounding errors with coordinate scaling and gives more flexibility in the presentation, as well as making it easy to maintain device independent resolution as windows move between different pixel density displays.
By default when a renderer is created, it will match the window size so window coordinates and render coordinates are 1-1.
Mouse and touch events are no longer filtered to change their coordinates, instead you can call SDL_ConvertEventToRenderCoordinates() to explicitly map event coordinates into the rendering viewport.
SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SDL_RenderCoordinatesFromWindow() and SDL_RenderCoordinatesToWindow() and take floating point coordinates in both directions.
The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active.
Rather than iterating over display modes using an index, there is a new function SDL_GetFullscreenDisplayModes() to get the list of available fullscreen modes on a display.
{
SDL_DisplayID display = SDL_GetPrimaryDisplay();
int num_modes = 0;
SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes);
if (modes) {
for (i = 0; i < num_modes; ++i) {
SDL_DisplayMode *mode = modes[i];
SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gHz, %d%% scale\n",
display, i, mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f));
}
SDL_free(modes);
}
}
SDL_GetDesktopDisplayMode() and SDL_GetCurrentDisplayMode() return pointers to display modes rather than filling in application memory.
Windows now have an explicit fullscreen mode that is set, using SDL_SetWindowFullscreenMode(). The fullscreen mode for a window can be queried with SDL_GetWindowFullscreenMode(), which returns a pointer to the mode, or NULL if the window will be fullscreen desktop. SDL_SetWindowFullscreen() just takes a boolean value, setting the correct fullscreen state based on the selected mode.
SDL_DisplayMode now includes the pixel size, the screen size and the relationship between the two. For example, a 4K display at 200% scale could have a pixel size of 3840x2160, a screen size of 1920x1080, and a display scale of 2.0.
* SDL 3.0 is going to be high DPI aware and officially separates screen coordinates from client pixel area
The public APIs to disable high DPI support have been removed
Work in progress on https://github.com/libsdl-org/SDL/issues/7134
This fixes the clang warning "Cast between pointer-to-function and pointer-to-object is an extension"
You can define SDL_FUNCTION_POINTER_IS_VOID_POINTER in your project to restore the previous behavior.
Fixes https://github.com/libsdl-org/SDL/issues/2866
This simplifies the API and removes a level of API translation between the int variants of the functions and the float implementation
Fixes https://github.com/libsdl-org/SDL/issues/6656
Also cleaned up logic for whether we need to poll for events:
- We need to periodically poll for joysticks to handle hotplug.
- We need to frequently poll for joysticks and sensors when they're open so their state can be updated
This function is useful for accumulating relative mouse motion if you want to only handle whole pixel movement.
e.g.
static float dx_frac, dy_frac;
float dx, dy;
/* Accumulate new motion with previous sub-pixel motion */
dx = event.motion.xrel + dx_frac;
dy = event.motion.yrel + dy_frac;
/* Split the integral and fractional motion, dx and dy will contain whole pixel deltas */
dx_frac = SDL_modff(dx, &dx);
dy_frac = SDL_modff(dy, &dy);
if (dx != 0.0f || dy != 0.0f) {
...
}
Feedback from @icculus:
"IsTablet" uses "is" as a form of "to be" ...like, the actual question is of its nature.
The rest is just a superfluous word in the question and it flows as better English with if (RectEmpty) than if (IsRectEmpty)
Fixes https://github.com/libsdl-org/SDL/issues/6932
`SDL_QUERY`, `SDL_IGNORE`, `SDL_ENABLE`, and `SDL_DISABLE` have been removed.
SDL_EventState() has been replaced with SDL_SetEventEnabled()
SDL_GetEventState() has been replaced with SDL_EventEnabled()
SDL_GameControllerEventState has been replaced with SDL_SetGamepadEventsEnabled() and SDL_GamepadEventsEnabled()
SDL_JoystickEventState has been replaced with SDL_SetJoystickEventsEnabled() and SDL_JoystickEventsEnabled()
SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
Fixes https://github.com/libsdl-org/SDL/issues/6929
Instead of indexing into an internal list of devices which requires locking, we return a list of device IDs which can then be queried individually.
Reference: https://github.com/libsdl-org/SDL/issues/6889
As the implementation requires C++, the user will have to include
SDL_main.h in a C++ source file (that needs to be compiled with /ZW).
It's ok to keep the standard main() implementation in plain C and use
an otherwise empty C++ source file for the SDL_main implementation part,
if both source files #include <SDL3/SDL_main.h>
Including SDL_main.h in a C source file will print a message at
compilation (when building for WinRT or possibly other not yet implemented
platforms that require C++ for main), to remind the user of also
including it in a .cpp source file. This message/warning can be disabled
with #define SDL_MAIN_NOIMPL before including SDL_main.h in the C file.
When including it in a .cpp file, there will be a compiler error with
helpful message if it's not compiled with /ZW
For this I renamend _SDL_MAIN_NOIMPL to SDL_MAIN_NOIMPL, because now it's
not for internal use only anymore, but also useful for users (that want
their main() function in a different file than the SDL_main implementation)
Add a project for the testdraw2.c test to the WinRT solution to at least
get some minimal testing on WinRT.
I won't add all tests because it's a lot of manual clicking per test,
but this should be better than nothing :)
This simplifies some things, clarifies some things, and also allows
for the possibility of RWops that offer non-blocking i/o (although
none of the current built-in ones do, intentionally, we could add this
later if we choose, or people could provide things like network socket
RWops implementations now, etc.
Fixes#6729.
* N3DS: Make Sem waits cooperative friendly.
The 3DS has a cooperative threading model. Sleeping after TryWait and
WaitTimeout avoid starving other threads. It inccurs a runtime penalty,
but it's better than having to hard reset your console to recover from
a deadlock.
I updated .clang-format and ran clang-format 14 over the src and test directories to standardize the code base.
In general I let clang-format have it's way, and added markup to prevent formatting of code that would break or be completely unreadable if formatted.
The script I ran for the src directory is added as build-scripts/clang-format-src.sh
This fixes:
#6592#6593#6594
* Remove depth field from SDL_CreateRGBSurfaceWithFormat and SDL_CreateRGBSurfaceWithFormatFrom
* Removed unused 'flags' parameter from SDL_CreateRGBSurface and SDL_CreateRGBSurfaceWithFormat
* Removed unused 'flags' parameter from SDL_ConvertSurface and SDL_ConvertSurfaceFormat
* Add braces after if conditions
* More add braces after if conditions
* Add braces after while() conditions
* Fix compilation because of macro being modified
* Add braces to for loop
* Add braces after if/goto
* Move comments up
* Remove extra () in the 'return ...;' statements
* More remove extra () in the 'return ...;' statements
* More remove extra () in the 'return ...;' statements after merge
* Fix inconsistent patterns are xxx == NULL vs !xxx
* More "{}" for "if() break;" and "if() continue;"
* More "{}" after if() short statement
* More "{}" after "if () return;" statement
* More fix inconsistent patterns are xxx == NULL vs !xxx
* Revert some modificaion on SDL_RLEaccel.c
* SDL_RLEaccel: no short statement
* Cleanup 'if' where the bracket is in a new line
* Cleanup 'while' where the bracket is in a new line
* Cleanup 'for' where the bracket is in a new line
* Cleanup 'else' where the bracket is in a new line
I ran this script in the include directory:
```sh
sed -i '' -e 's,#include "\(SDL.*\)",#include <SDL3/\1>,' *.h
```
I ran this script in the src directory:
```sh
for i in ../include/SDL3/SDL*.h
do hdr=$(basename $i)
if [ x"$(echo $hdr | egrep 'SDL_main|SDL_name|SDL_test|SDL_syswm|SDL_opengl|SDL_egl|SDL_vulkan')" != x ]; then
find . -type f -exec sed -i '' -e 's,#include "\('$hdr'\)",#include <SDL3/\1>,' {} \;
else
find . -type f -exec sed -i '' -e '/#include "'$hdr'"/d' {} \;
fi
done
```
Fixes https://github.com/libsdl-org/SDL/issues/6575
- TODO: update INSTALL.txt to replace the autotools configure
instructions with cmake.
- TODO: update make build system to provide an equivalent to
autotools' `make dist` ?
- TODO: update / revise github actions, replace autotools-only
ones with cmake (e.g.: vmactions.yml for FreeBSD.)
Reference issue: https://github.com/libsdl-org/SDL/issues/6571
* The header is no longer dependent on SDL build configuration
* The structures are versioned separately from the rest of SDL
* SDL_GetWindowWMInfo() now returns a standard result code and is passed the version expected by the application
* Updated WhatsNew.txt and docs/README-migration.md with the first API changes in SDL 3.0
Instead of using a URL and git sha1, this uses `git describe` to
describe the version relative to the nearest previous git tag, which
gives a better indication of whether this is a release, a prerelease,
a slightly patched prerelease, or a long way after the last release
during active development.
This serves two purposes: it makes those APIs more informative, and it
also puts this information into the binary in a form that is easy to
screen-scrape using strings(1). For instance, if the bundled version of
SDL in a game has this, we can see at a glance what version it is.
It's also shorter than using the web address of the origin git
repository and the full git commit sha1.
Also write the computed version into a file ./VERSION in `make dist`
tarballs, so that when we build from a tarball on a system that doesn't
have git available, we still get the version details.
For the Perforce code path in showrev.sh, output the version number
followed by the Perforce revision, in a format reminiscent of
`git describe` (with p instead of g to indicate Perforce).
For the code path with no VCS available at all, put a suffix on the
version number to indicate that this is just a guess (we can't know
whether this SDL version is actually a git snapshot or has been
patched locally or similar).
Resolves: https://github.com/libsdl-org/SDL/issues/6418
Signed-off-by: Simon McVittie <smcv@collabora.com>
If this assertion fails on some platform (unlikely), we will need a
third implementation for SwapLongLE().
Signed-off-by: Simon McVittie <smcv@collabora.com>
The check for whether to use a 32- or 64-bit swap for an array of long
values always took the 64-bit path, because <limits.h> wasn't included
and therefore ULONG_MAX wasn't defined. Turn this into a runtime check,
which a reasonable compiler will optimize into a constant.
This fixes testevdev failures on 32-bit big-endian platforms such as hppa
and older powerpc. Little-endian and/or 64-bit platforms are unaffected.
[smcv: Added commit message]
Bug-Debian: https://bugs.debian.org/1021310
Co-authored-by: Simon McVittie <smcv@collabora.com>
Emitted by MinGW:
In function 'WatchJoystick',
inlined from 'SDL_main' at D:/a/SDL/SDL/test/controllermap.c:802:9:
D:/a/SDL/SDL/test/controllermap.c:437:9: warning: 'marker' may be used uninitialized [-Wmaybe-uninitialized]
437 | SDL_SetTextureAlphaMod(marker, alpha);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:/a/SDL/SDL/test/controllermap.c: In function 'SDL_main':
D:/a/SDL/SDL/test/controllermap.c:355:71: note: 'marker' was declared here
355 | SDL_Texture *background_front, *background_back, *button, *axis, *marker;
X11 has a so-called primary selection, which you can use by marking text and middle-clicking elsewhere to copy the marked text.
There are 3 new API functions in `SDL_clipboard.h`, which work exactly like their clipboard equivalents.
## Test Instructions
* Run the tests (just a copy of the clipboard tests): `$ ./test/testautomation --filter Clipboard`
* Build and run this small application:
<details>
```C
#include <SDL.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_error(const char *where)
{
const char *errstr = SDL_GetError();
if (errstr == NULL || errstr[0] == '\0')
return;
fprintf(stderr, "SDL Error after '%s': %s\n", where, errstr);
SDL_ClearError();
}
int main()
{
char text_buf[256];
srand(time(NULL));
SDL_Init(SDL_INIT_VIDEO);
print_error("SDL_INIT()");
SDL_Window *window = SDL_CreateWindow("Primary Selection Test", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 400, 400, SDL_WINDOW_SHOWN);
print_error("SDL_CreateWindow()");
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
print_error("SDL_CreateRenderer()");
bool quit = false;
unsigned int do_render = 0;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
print_error("SDL_PollEvent()");
switch (event.type) {
case SDL_QUIT: {
quit = true;
break;
} case SDL_KEYDOWN: {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_q:
quit = true;
break;
case SDLK_c:
snprintf(text_buf, sizeof(text_buf), "foo%d", rand());
SDL_SetClipboardText(text_buf);
print_error("SDL_SetClipboardText()");
printf("clipboard: set_to=\"%s\"\n", text_buf);
break;
case SDLK_v: {
printf("clipboard: has=%d, ", SDL_HasClipboardText());
print_error("SDL_HasClipboardText()");
char *text = SDL_GetClipboardText();
print_error("SDL_GetClipboardText()");
printf("text=\"%s\"\n", text);
SDL_free(text);
break;
} case SDLK_d:
snprintf(text_buf, sizeof(text_buf), "bar%d", rand());
SDL_SetPrimarySelectionText(text_buf);
print_error("SDL_SetPrimarySelectionText()");
printf("primselec: set_to=\"%s\"\n", text_buf);
break;
case SDLK_f: {
printf("primselec: has=%d, ", SDL_HasPrimarySelectionText());
print_error("SDL_HasPrimarySelectionText()");
char *text = SDL_GetPrimarySelectionText();
print_error("SDL_GetPrimarySelectionText()");
printf("text=\"%s\"\n", text);
SDL_free(text);
break;
} default:
break;
}
break;
} default: {
break;
}}
}
// create less noise with WAYLAND_DEBUG=1
if (do_render == 0) {
SDL_RenderPresent(renderer);
print_error("SDL_RenderPresent()");
}
do_render += 1;
usleep(12000);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
print_error("quit");
return 0;
}
```
</details>
* Use c,v,d,f to get and set the clipboard and primary selection.
* Mark text and middle-click also in other applications.
* For wayland under x:
* `$ mutter --wayland --no-x11 --nested`
* `$ XDG_SESSION_TYPE=wayland SDL_VIDEODRIVER=wayland ./<path_to_test_appl_binary>`
This is now used as a crc field in the mapping rather than directly in mapping guids, for better mapping compatibility between versions of SDL.
Added SDL_GetJoystickGUIDInfo() to get device information encoded in a joystick GUID, so that mapping programs can clear the CRC from the GUID when generating mappings.
sort_controllers.py has been updated to extract the CRC from mappings created by older mapping programs and convert it into the new crc field. It will also take the CRC into account when checking for duplicate mappings.
Also regenerated the GUIDs for the PS2/PSP/Vita controller mappings, fixing https://github.com/libsdl-org/SDL/issues/6151
* Added support for mini-gamepad mode for Joy-Con controllers, matching the mapping for hid-nintendo on Linux and iOS 16
* Added the ability to merge left and right Joy-Con controllers into a single Pro-style controller
* Added the hint SDL_HINT_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS to control this merging functionality
* Removed the hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS
Also added test functions for multi-line debug text display
Currently this only supports ASCII, as the font doesn't have the correct Latin-1 characters
Instead of using `trunc` to check the first ten digits, inexact test now
relies on an epsilon defining an acceptable range for the expected
result to be in.
Many tests were using the same underlying routine, as such three helper
functions were added:
- A wrapper to test double -> double functions.
- A wrapper to test (double, double) -> double functions,
- A wrapper for range tests on double -> double functions.
Split infinity and zero checks in their own functions.
The result of NAN tests is now logged.
The SDL_TestCaseReference structure were renamed to be more explicit.
Fixes bug with viewport not updating when moving window between monitors with different scale
factors on Windows (this should also fix the same issue on other OS'es, though untested)
- SDL_JoystickGUID -> SDL_GUID (though we retain a type alias)
- Operations for GUID <-> String ops are now in
src/SDL_guid.c and include/SDL_guid.h
- The corresponding Joystick operations delegate to SDL_guid.c
- Added test/testguid.c
I had assumed that only Linux users would be interested in GNOME-style
installed-tests, but in principle there's no reason why they can't be
used on non-Linux.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Added the ability to specify a name and the product VID/PID for a virtual controller
Also added a test case to testgamecontroller, if you pass --virtual as a parameter
This makes it more convenient to compile them alongside SDL, install
them in an optional package and use them as smoke-tests or diagnostic
tools. The default installation directory is taken from GNOME's
installed-tests, which seems as good a convention as any other:
https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests
Signed-off-by: Simon McVittie <smcv@collabora.com>
As well as reducing duplication, this lets the tests load their resources
from the SDL_GetBasePath() on platforms that support it, which is useful
if the tests are compiled along with the rest of SDL and installed below
/usr as manual tests, similar to GNOME's installed-tests convention.
Thanks to Ozkan Sezer for the OS/2 build glue.
Co-authored-by: Ozkan Sezer <sezeroz@gmail.com>
Signed-off-by: Simon McVittie <smcv@collabora.com>
In Autotools, these are run by `make -C ${builddir}/test check`.
In CMake, they're run by `make -C ${builddir} test` or
`ninja -C ${builddir} test` or `ctest --test-dir ${builddir}`.
Signed-off-by: Simon McVittie <smcv@collabora.com>
At the time I contributed this unit test, SDL had a relatively narrow
definition of what is a keyboard, approximately matching udev
ID_INPUT_KEYBOARD. Now it uses the equivalent of udev ID_INPUT_KEY,
which matches anything with keyboard keys, and not just reasonably
complete alphanumeric keyboards.
Fixes: 040bd7a9 "Fix udev not detecting ID_INPUT_KEY devices when udev is not running"
Signed-off-by: Simon McVittie <smcv@collabora.com>
At the time I contributed this unit test, SDL didn't understand Linux
touchpads, but now it does.
Fixes: 373216ae "Added support for touchpads in the Linux evdev code"
Signed-off-by: Simon McVittie <smcv@collabora.com>
Call SDL_RenderPresent after calling SDL_RenderReadPixels.
From "include/SDL_render.h":
"If you're using this on the main rendering target, it should be called after rendering and before SDL_RenderPresent()."
GLES2 always has them, and they work without hacks on Emscripten, unlike
client-side arrays.
I cleaned it up slightly, but this patch was mostly written by @bing2008.
Fixes#5258.
Case fallthrough warnings can be suppressed using the __fallthrough__
compiler attribute. Unfortunately, not all compilers have this
attribute, or even have __has_attribute to check if they have the
__fallthrough__ attribute. [[fallthrough]] is also available in C++17
and the next C2x, but not everyone uses C++17 or C2x.
So define the SDL_FALLTHROUGH macro to deal with those problems - if we
are using C++17 or C2x, it expands to [[fallthrough]]; else if the
compiler has __has_attribute and has the __fallthrough__ attribute, then
it expands to __attribute__((__fallthrough__)); else it expands to an
empty statement, with a /* fallthrough */ comment (it's a do {} while
(0) statement, because users of this macro need to use a semicolon,
because [[fallthrough]] and __attribute__((__fallthrough__)) require a
semicolon).
Clang before Clang 10 and GCC before GCC 7 have problems with using
__attribute__ as a sole statement and warn about a "declaration not
declaring anything", so fall back to using the /* fallthrough */ comment
if we are using those older compiler versions.
Applications using SDL are also free to use this macro (because it is
defined in begin_code.h).
All existing /* fallthrough */ comments have been replaced with this
macro. Some of them were unnecessary because they were the last case in
a switch; using SDL_FALLTHROUGH in those cases would result in a compile
error on compilers that support __fallthrough__, for having a
__attribute__((__fallthrough__)) statement that didn't immediately
precede a case label.
Case fallthrough warnings can be suppressed using the __fallthrough__
compiler attribute. Unfortunately, not all compilers have this
attribute, or even have __has_attribute to check if they have the
__fallthrough__ attribute. [[fallthrough]] is also available in C++17
and the next C2x, but not everyone uses C++17 or C2x.
So define the SDL_FALLTHROUGH macro to deal with those problems - if we
are using C++17 or C2x, it expands to [[fallthrough]]; else if the
compiler has __has_attribute and has the __fallthrough__ attribute, then
it expands to __attribute__((__fallthrough__)); else it expands to an
empty statement, with a /* fallthrough */ comment (it's a do {} while
(0) statement, because users of this macro need to use a semicolon,
because [[fallthrough]] and __attribute__((__fallthrough__)) require a
semicolon).
Applications using SDL are also free to use this macro (because it is
defined in begin_code.h).
All existing /* fallthrough */ comments have been replaced with this
macro. Some of them were unnecessary because they were the last case in
a switch; using SDL_FALLTHROUGH in those cases would result in a compile
error on compilers that support __fallthrough__, for having a
__attribute__((__fallthrough__)) statement that didn't immediately
precede a case label.
* SDLTest_CommonDrawWindowInfo: log SDL_RenderGetScale, SDL_RenderGetLogicalSize
* testwm2: fix video modes menu hit detection in High DPI cases
- also when logical size is specified, e.g.
`--logical 640x480 --resizable --allow-highdpi`
* add function to determine logical coordinates of renderer point when given window point
* change since to the targeted milestone
* fix typo
* rename for consistency
* Change logical coordinate type to float, since we can render with floating point precision.
* add function to convert logical to window coordinates
* testwm2: use new SDL_RenderWindowToLogical
* SDL_render.c: alternate SDL_RenderWindowToLogical/SDL_RenderLogicalToWindow
Co-authored-by: John Blat <johnblat64@protonmail.com>
Co-authored-by: John Blat <47202511+johnblat64@users.noreply.github.com>