Compare commits

...

39 Commits

Author SHA1 Message Date
Kyler "Félix" Eastridge 4f4c007621
Merge 656b5cd042 into 9ed83e71f6 2025-06-23 08:37:09 +02:00
Sam Lantinga 9ed83e71f6 Fixed memory leaks in KMSDRM property handling
Also cleaned up the code for consistency so it's easy to see memory leaks here.
2025-06-22 21:33:52 -07:00
SDL Wiki Bot 603118c340 Sync SDL3 wiki -> header
[ci skip]
2025-06-23 04:18:24 +00:00
Sam Lantinga aa4f916b71 Renamed SDL_PROP_AUDIOSTREAM_KEEP_ON_SHUTDOWN_BOOLEAN to SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN 2025-06-22 21:17:06 -07:00
SDL Wiki Bot 6cfe211142 Sync SDL3 wiki -> header
[ci skip]
2025-06-23 04:07:09 +00:00
Ryan C. Gordon 274aa0242e
audio: Let apps save an audio stream from destruction during SDL_Quit(). (#13244)
This is a special-case piece of functionality, generally these are expected
to go away during shutdown, but maybe someone is switching between audio
subsystems or something...
2025-06-22 21:06:15 -07:00
Ozkan Sezer af8bee2dd1 alsa: change an SDL_LogError into SDL_LogDebug.
it is informational only and seeing ERROR on the terminal was confusing
2025-06-22 21:04:44 -07:00
Marcin Serwin bbc674b9e7 test: Fix resource paths in testtray
Signed-off-by: Marcin Serwin <marcin@serwin.dev>
2025-06-22 21:03:37 -07:00
mitchellcairns 796961acec
Resolve bug for calibration Nintendo Switch Pro Controller (#13260)
Resolves a bug which prevents the stored calibration data from loading, only allowing loading of factory-installed calibration data
2025-06-22 20:59:15 -07:00
Mitch Cairns 3a6f9e01f8 Fixed Nintendo Switch thumbstick calibration 2025-06-22 15:26:49 -07:00
Sam Lantinga 038a3806eb Fixed Nintendo Switch Pro thumbstick calibration
Fixes https://github.com/libsdl-org/SDL/issues/13246
2025-06-21 19:55:05 -07:00
Sam Lantinga e6c2649afc Updated testffmpeg for ffmpeg 7.1 2025-06-21 08:48:40 -07:00
Sasha Szpakowski e80d084766 expose events originating from a live-resize set the data1 field to 1.
Fixes #13243.
2025-06-21 07:33:25 -07:00
Josh Dowell 6aedc488d3 win32: Invalidate window message mouse button flags when reading buttons from raw input or GameInput
SDL2 would set a high bit in the mouse button flags to indicate when raw input had been read from, without this, if you hold down a mouse button and left raw input mode (leaving relative mode) the button would remain partially stuck, and would require two clicks to start producing mouse down events again.
SDL3's raw input code was refactored to not use the mouse button flags, but forgot to invalidate the flags, causing this bug to manifest.
2025-06-21 07:28:14 -07:00
Ozkan Sezer 81e3066303 hidapi/libusb: disable C5287 warning in MSVC builds
A quick search implies that it is a bogus warning:
https://www.google.com/search?q=visual+studio+C5287
2025-06-21 07:15:53 -07:00
Sam Lantinga 7d9fd48557 alsa: recover from snd_pcm_avail() returning -EPIPE 2025-06-20 16:33:30 -07:00
Sam Lantinga e68f5ca99a alsa: use udev if available instead of a hotplug thread
This makes detecting audio device changes more responsive.
2025-06-20 19:19:31 -04:00
Sam Lantinga 051ce0ff89 alsa: fixed disconnecting the microphone when opened
Some devices take some time for data to become available, so we'll keep waiting as long as necessary for them to provide data.
2025-06-20 19:19:31 -04:00
Wohlstand 5fcc83d93b Vita Render: Limit the scope of cliprect to viewport
Don't allow cliprect be larger than viewport's scope

(cherry picked from commit 6701f938f7)

# Conflicts:
#	src/render/vitagxm/SDL_render_vita_gxm.c
2025-06-20 14:51:16 -07:00
Wohlstand 1bd5110ff0 Vita: Fixed absence of clipping when viewport is set
#13034

(cherry picked from commit 1c09a7117a)

# Conflicts:
#	src/render/vitagxm/SDL_render_vita_gxm.c
#	src/render/vitagxm/SDL_render_vita_gxm_types.h
2025-06-20 14:51:16 -07:00
Ryan C. Gordon eb04219efe
audio: Enumerating audio devices will skip zombie devices still in the hash. 2025-06-20 17:37:39 -04:00
SDL Wiki Bot d06b6e42d2 Sync SDL3 wiki -> header
[ci skip]
2025-06-20 21:02:26 +00:00
Sam Lantinga c19ad189dc Clarify that SDL_GetAudioStreamDevice() returns the logical device. 2025-06-20 14:01:16 -07:00
Sam Lantinga 7882e60f0e Don't log an error for disconnected audio devices 2025-06-20 11:05:08 -07:00
Lilian Gimenez e4e29b8601 Fix support for F21 to F24 scancodes on Linux 2025-06-20 09:06:57 -07:00
Sam Lantinga d7939abf42 Use consistent style for pointer declarations and casts 2025-06-18 10:03:44 -07:00
Frank Praznik 390fe65323
test: Fix a window parenting bug in testmodal 2025-06-18 09:26:09 -04:00
Frank Praznik ca9b7c8ea3
video: Explicitly disallow setting the parent of a window to itself
Doing so causes a cycle in the window hierarchy tree graph, which leads to infinite recursion when destroying the windows.
2025-06-18 09:26:08 -04:00
Ryan C. Gordon c04624972e
alsa: Simplify ALSA_WaitDevice.
- Check for specific availability instead of waiting for "device ready."
- Don't use snd_pcm_wait, just use a simple SDL_Delay (nothing to recover).
- Fixed SDL_max call that should have been SDL_min (now using SDL_clamp).
- ALSA_RecordDevice() now returns 0 if no availability, which kicks us back
  to WaitDevice to try again, as an extra safety check.
2025-06-17 20:40:00 -04:00
Ryan C. Gordon b4ac5f43f5
include: Fixed copy/paste error in endian-specific SDL_Read function docs. 2025-06-17 16:41:24 -04:00
Ryan C. Gordon 3896b1b3f4
wikiheaders: Let each subproject specify how to find their property symbols. 2025-06-17 16:41:24 -04:00
Sam Lantinga efed3c63b3 Added support for an alternate version of the Vader 4 Pro 2025-06-17 10:02:10 -07:00
Sam Lantinga d6bae53341 Added support for an alternate version of the Vader 4 Pro 2025-06-17 08:07:12 -07:00
Sam Lantinga f62c982bcf Reverted Accelerometer and Gyro displays to throttled display (10hz)
Also made accelerometer threshold for drift calibration more lenient for very noisy accelerometers.

The testcontroller tool could eventually be used to come up with a better way to profile an IMU's "stationary" noise so that this threshold can be as tight as necessary for the sake of automatic drift calibration.

(thanks @HilariousCow!)
2025-06-16 11:14:22 -07:00
Sam Lantinga b833c618a9 Improved reliability detecting FlyDigi Vader controllers 2025-06-16 11:07:50 -07:00
SDL Wiki Bot 0e262dfd44 Sync SDL3 wiki -> header
[ci skip]
2025-06-16 02:13:37 +00:00
Ryan C. Gordon 6c406dd122
include: a couple of documentation tweaks and typo fixes. 2025-06-15 22:12:21 -04:00
SDL Wiki Bot 42c9fe119d Sync SDL3 wiki -> header
[ci skip]
2025-06-16 00:36:13 +00:00
Kyler Eastridge 656b5cd042 (N3DS) Add support for 3D rendering 2024-11-16 05:47:37 -05:00
131 changed files with 824 additions and 653 deletions

View File

@ -9,6 +9,7 @@ versionfname = include/SDL3/SDL_version.h
versionmajorregex = \A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z
versionminorregex = \A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z
versionmicroregex = \A\#define\s+SDL_MICRO_VERSION\s+(\d+)\Z
apipropertyregex = \A\s*\#\s*define\s+SDL_PROP_
selectheaderregex = \ASDL.*?\.h\Z
projecturl = https://libsdl.org/
wikiurl = https://wiki.libsdl.org

View File

@ -32,6 +32,7 @@ my $wikisubdir = '';
my $incsubdir = 'include';
my $readmesubdir = undef;
my $apiprefixregex = undef;
my $apipropertyregex = undef;
my $versionfname = 'include/SDL_version.h';
my $versionmajorregex = '\A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z';
my $versionminorregex = '\A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z';
@ -110,6 +111,7 @@ if (defined $optionsfname) {
$srcpath = $val, next if $key eq 'srcpath';
$wikipath = $val, next if $key eq 'wikipath';
$apiprefixregex = $val, next if $key eq 'apiprefixregex';
$apipropertyregex = $val, next if $key eq 'apipropertyregex';
$projectfullname = $val, next if $key eq 'projectfullname';
$projectshortname = $val, next if $key eq 'projectshortname';
$wikisubdir = $val, next if $key eq 'wikisubdir';
@ -1366,7 +1368,7 @@ while (my $d = readdir(DH)) {
# update strings now that we know everything pending is to be applied to this declaration. Add pending blank lines and the new text.
# At Sam's request, don't list property defines with functions. (See #9440)
my $is_property = /\A\s*\#\s*define\s+SDL_PROP_/;
my $is_property = (defined $apipropertyregex) ? /$apipropertyregex/ : 0;
if (!$is_property) {
if ($blank_lines > 0) {
while ($blank_lines > 0) {

View File

@ -1021,7 +1021,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
/**
* Query an audio stream for its currently-bound device.
*
* This reports the audio device that an audio stream is currently bound to.
* This reports the logical audio device that an audio stream is currently
* bound to.
*
* If not bound, or invalid, this returns zero, which is not a valid device
* ID.
@ -1063,6 +1064,17 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au
/**
* Get the properties associated with an audio stream.
*
* The application can hang any data it wants here, but the following
* properties are understood by SDL:
*
* - `SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN`: if true (the default), the
* stream be automatically cleaned up when the audio subsystem quits. If set
* to false, the streams will persist beyond that. This property is ignored
* for streams created through SDL_OpenAudioDeviceStream(), and will always
* be cleaned up. Streams that are not cleaned up will still be unbound from
* devices when the audio subsystem quits. This property was added in SDL
* 3.4.0.
*
* \param stream the SDL_AudioStream to query.
* \returns a valid property ID on success or 0 on failure; call
* SDL_GetError() for more information.
@ -1073,6 +1085,9 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au
*/
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetAudioStreamProperties(SDL_AudioStream *stream);
#define SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN "SDL.audiostream.auto_cleanup"
/**
* Query the current format of an audio stream.
*
@ -1149,14 +1164,14 @@ extern SDL_DECLSPEC float SDLCALL SDL_GetAudioStreamFrequencyRatio(SDL_AudioStre
*
* The frequency ratio is used to adjust the rate at which input data is
* consumed. Changing this effectively modifies the speed and pitch of the
* audio. A value greater than 1.0 will play the audio faster, and at a higher
* pitch. A value less than 1.0 will play the audio slower, and at a lower
* pitch.
* audio. A value greater than 1.0f will play the audio faster, and at a
* higher pitch. A value less than 1.0f will play the audio slower, and at a
* lower pitch. 1.0f means play at normal speed.
*
* This is applied during SDL_GetAudioStreamData, and can be continuously
* changed to create various effects.
*
* \param stream the stream the frequency ratio is being changed.
* \param stream the stream on which the frequency ratio is being changed.
* \param ratio the frequency ratio. 1.0 is normal speed. Must be between 0.01
* and 100.
* \returns true on success or false on failure; call SDL_GetError() for more
@ -1332,7 +1347,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamInputChannelMap(SDL_AudioStre
* Channel maps are optional; most things do not need them, instead passing
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
*
* The output channel map reorders data that leaving a stream via
* The output channel map reorders data that is leaving a stream via
* SDL_GetAudioStreamData.
*
* Each item in the array represents an input channel, and its value is the

View File

@ -135,7 +135,8 @@ typedef enum SDL_EventType
/* 0x201 was SDL_SYSWMEVENT, reserve the number for sdl2-compat */
SDL_EVENT_WINDOW_SHOWN = 0x202, /**< Window has been shown */
SDL_EVENT_WINDOW_HIDDEN, /**< Window has been hidden */
SDL_EVENT_WINDOW_EXPOSED, /**< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event */
SDL_EVENT_WINDOW_EXPOSED, /**< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event.
data1 is 1 for live-resize expose events, 0 otherwise. */
SDL_EVENT_WINDOW_MOVED, /**< Window has been moved to data1, data2 */
SDL_EVENT_WINDOW_RESIZED, /**< Window has been resized to data1xdata2 */
SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,/**< The pixel size of the window has changed to data1xdata2 */

View File

@ -823,7 +823,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS8(SDL_IOStream *src, Sint8 *value);
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -846,7 +846,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU16LE(SDL_IOStream *src, Uint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -869,7 +869,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS16LE(SDL_IOStream *src, Sint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -892,7 +892,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU16BE(SDL_IOStream *src, Uint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -915,7 +915,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS16BE(SDL_IOStream *src, Sint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -938,7 +938,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU32LE(SDL_IOStream *src, Uint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -961,7 +961,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS32LE(SDL_IOStream *src, Sint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -984,7 +984,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU32BE(SDL_IOStream *src, Uint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -1007,7 +1007,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS32BE(SDL_IOStream *src, Sint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -1030,7 +1030,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU64LE(SDL_IOStream *src, Uint64 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -1053,7 +1053,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS64LE(SDL_IOStream *src, Sint64 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
@ -1076,7 +1076,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU64BE(SDL_IOStream *src, Uint64 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.

View File

@ -1894,7 +1894,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetWindowSafeArea(SDL_Window *window, SDL_R
extern SDL_DECLSPEC bool SDLCALL SDL_SetWindowAspectRatio(SDL_Window *window, float min_aspect, float max_aspect);
/**
* Get the size of a window's client area.
* Get the aspect ratio of a window's client area.
*
* \param window the window to query the width and height from.
* \param min_aspect a pointer filled in with the minimum aspect ratio of the

View File

@ -1073,9 +1073,16 @@ void SDL_QuitAudio(void)
current_audio.impl.DeinitializeStart();
// Destroy any audio streams that still exist...
while (current_audio.existing_streams) {
SDL_DestroyAudioStream(current_audio.existing_streams);
// Destroy any audio streams that still exist...unless app asked to keep it.
SDL_AudioStream *next = NULL;
for (SDL_AudioStream *i = current_audio.existing_streams; i; i = next) {
next = i->next;
if (i->simplified || SDL_GetBooleanProperty(i->props, SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN, true)) {
SDL_DestroyAudioStream(i);
} else {
i->prev = NULL;
i->next = NULL;
}
}
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
@ -1415,6 +1422,7 @@ static int SDLCALL RecordingAudioThread(void *devicep) // thread entry point
typedef struct CountAudioDevicesData
{
int devs_seen;
int devs_skipped;
const int num_devices;
SDL_AudioDeviceID *result;
const bool recording;
@ -1430,8 +1438,14 @@ static bool SDLCALL CountAudioDevices(void *userdata, const SDL_HashTable *table
const bool isphysical = !!(devid & (1<<1));
if (isphysical && (devid_recording == data->recording)) {
SDL_assert(data->devs_seen < data->num_devices);
SDL_AudioDevice *device = (SDL_AudioDevice *) value; // this is normally risky, but we hold the device_hash_lock here.
const bool zombie = SDL_GetAtomicInt(&device->zombie) != 0;
if (zombie) {
data->devs_skipped++;
} else {
data->result[data->devs_seen++] = devid;
}
}
return true; // keep iterating.
}
@ -1446,10 +1460,11 @@ static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
num_devices = SDL_GetAtomicInt(recording ? &current_audio.recording_device_count : &current_audio.playback_device_count);
result = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
if (result) {
CountAudioDevicesData data = { 0, num_devices, result, recording };
CountAudioDevicesData data = { 0, 0, num_devices, result, recording };
SDL_IterateHashTable(current_audio.device_hash, CountAudioDevices, &data);
SDL_assert(data.devs_seen == num_devices);
result[data.devs_seen] = 0; // null-terminated.
SDL_assert((data.devs_seen + data.devs_skipped) == num_devices);
num_devices = data.devs_seen; // might be less if we skipped any.
result[num_devices] = 0; // null-terminated.
}
}
SDL_UnlockRWLock(current_audio.device_hash_lock);

View File

@ -38,6 +38,7 @@
#include "../SDL_sysaudio.h"
#include "SDL_alsa_audio.h"
#include "../../core/linux/SDL_udev.h"
#if SDL_ALSA_DEBUG
#define LOGDEBUG(...) SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "ALSA: " __VA_ARGS__)
@ -348,28 +349,25 @@ static char *get_pcm_str(void *handle)
// This function waits until it is possible to write a full sound buffer
static bool ALSA_WaitDevice(SDL_AudioDevice *device)
{
const int fulldelay = (int) ((((Uint64) device->sample_frames) * 1000) / device->spec.freq);
const int delay = SDL_max(fulldelay, 10);
const int sample_frames = device->sample_frames;
const int fulldelay = (int) ((((Uint64) sample_frames) * 1000) / device->spec.freq);
const int delay = SDL_clamp(fulldelay, 1, 5);
while (!SDL_GetAtomicInt(&device->shutdown)) {
const int rc = ALSA_snd_pcm_wait(device->hidden->pcm, delay);
if (rc < 0 && (rc != -EAGAIN)) {
const int rc = ALSA_snd_pcm_avail(device->hidden->pcm);
if (rc < 0) {
const int status = ALSA_snd_pcm_recover(device->hidden->pcm, rc, 0);
if (status < 0) {
// Hmm, not much we can do - abort
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "ALSA: snd_pcm_wait failed (unrecoverable): %s", ALSA_snd_strerror(rc));
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "ALSA wait failed (unrecoverable): %s", ALSA_snd_strerror(rc));
return false;
}
continue;
}
if (rc > 0) {
break; // ready to go!
if (rc >= sample_frames) {
break;
}
// Timed out! Make sure we aren't shutting down and then wait again.
SDL_Delay(delay);
}
return true;
}
@ -431,8 +429,11 @@ static int ALSA_RecordDevice(SDL_AudioDevice *device, void *buffer, int buflen)
SDL_assert((buflen % frame_size) == 0);
const snd_pcm_sframes_t total_available = ALSA_snd_pcm_avail(device->hidden->pcm);
const int total_frames = SDL_min(buflen / frame_size, total_available);
if (total_available == 0) {
return 0; // go back to WaitDevice and try again.
}
const int total_frames = SDL_min(buflen / frame_size, total_available);
const int rc = ALSA_snd_pcm_readi(device->hidden->pcm, buffer, total_frames);
SDL_assert(rc != -EAGAIN); // assuming this can't happen if we used snd_pcm_wait and queried for available space. snd_pcm_recover won't handle it!
@ -1156,7 +1157,7 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device)
#if SDL_ALSA_DEBUG
snd_pcm_uframes_t bufsize;
ALSA_snd_pcm_hw_params_get_buffer_size(cfg_ctx.hwparams, &bufsize);
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO,
"ALSA: period size = %ld, periods = %u, buffer size = %lu",
cfg_ctx.persize, cfg_ctx.periods, bufsize);
#endif
@ -1445,6 +1446,65 @@ static int SDLCALL ALSA_HotplugThread(void *arg)
}
#endif
#ifdef SDL_USE_LIBUDEV
static bool udev_initialized;
static void ALSA_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
{
if (!devpath) {
return;
}
switch (udev_type) {
case SDL_UDEV_DEVICEADDED:
ALSA_HotplugIteration(NULL, NULL);
break;
case SDL_UDEV_DEVICEREMOVED:
ALSA_HotplugIteration(NULL, NULL);
break;
default:
break;
}
}
static bool ALSA_start_udev()
{
udev_initialized = SDL_UDEV_Init();
if (udev_initialized) {
// Set up the udev callback
if (!SDL_UDEV_AddCallback(ALSA_udev_callback)) {
SDL_UDEV_Quit();
udev_initialized = false;
}
}
return udev_initialized;
}
static void ALSA_stop_udev()
{
if (udev_initialized) {
SDL_UDEV_DelCallback(ALSA_udev_callback);
SDL_UDEV_Quit();
udev_initialized = false;
}
}
#else
static bool ALSA_start_udev()
{
return false;
}
static void ALSA_stop_udev()
{
}
#endif // SDL_USE_LIBUDEV
static void ALSA_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
{
ALSA_guess_device_prefix();
@ -1460,12 +1520,14 @@ static void ALSA_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDevi
*default_recording = SDL_AddAudioDevice(/*recording=*/true, "ALSA default recording device", NULL, (void *)&default_recording_handle);
}
if (!ALSA_start_udev()) {
#if SDL_ALSA_HOTPLUG_THREAD
SDL_SetAtomicInt(&ALSA_hotplug_shutdown, 0);
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL);
// if the thread doesn't spin, oh well, you just don't get further hotplug events.
#endif
}
}
static void ALSA_DeinitializeStart(void)
{
@ -1479,6 +1541,7 @@ static void ALSA_DeinitializeStart(void)
ALSA_hotplug_thread = NULL;
}
#endif
ALSA_stop_udev();
// Shutting down! Clean up any data we've gathered.
for (dev = hotplug_devices; dev; dev = next) {

View File

@ -371,10 +371,10 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
/* 188, 0x0bc */ SDL_SCANCODE_F18, // XF86Launch9
/* 189, 0x0bd */ SDL_SCANCODE_F19, // NoSymbol
/* 190, 0x0be */ SDL_SCANCODE_F20, // XF86AudioMicMute
/* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadToggle
/* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOn
/* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOff
/* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 191, 0x0bf */ SDL_SCANCODE_F21, // XF86TouchpadToggle
/* 192, 0x0c0 */ SDL_SCANCODE_F22, // XF86TouchpadOn
/* 193, 0x0c1 */ SDL_SCANCODE_F23, // XF86TouchpadOff
/* 194, 0x0c2 */ SDL_SCANCODE_F24, // NoSymbol
/* 195, 0x0c3 */ SDL_SCANCODE_MODE, // Mode_switch
/* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, // NoSymbol

View File

@ -71,6 +71,11 @@ extern "C" {
#define DETACH_KERNEL_DRIVER
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:5287) /* operands are different enum types */
#endif
/* Uncomment to enable the retrieval of Usage and Usage Page in
hid_enumerate(). Warning, on platforms different from FreeBSD
this is very invasive as it requires the detach
@ -2144,6 +2149,10 @@ uint16_t get_usb_code_for_current_locale(void)
return 0x0;
}
#if defined(_MSC_VER)
#pragma warning (pop)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -841,6 +841,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
case 80:
case 81:
case 85:
case 105:
// Vader series of controllers have C/Z buttons
SDL_strlcat(mapping_string, "misc2:b15,misc3:b16,", sizeof(mapping_string));
break;

View File

@ -95,19 +95,18 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
{
SDL_DriverFlydigi_Context *ctx = (SDL_DriverFlydigi_Context *)device->context;
for (int attempt = 0; ctx->deviceID == 0 && attempt < 3; ++attempt) {
// Detecting the Vader 2 can take over 1000 read retries, so be generous here
for (int attempt = 0; ctx->deviceID == 0 && attempt < 30; ++attempt) {
const Uint8 request[] = { FLYDIGI_CMD_REPORT_ID, FLYDIGI_GET_INFO_COMMAND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int size = SDL_hid_write(device->dev, request, sizeof(request));
if (size < 0) {
break;
}
// This write will occasionally return -1, so ignore failure here and try again
(void)SDL_hid_write(device->dev, request, sizeof(request));
// Read the reply
for (int i = 0; i < 100; ++i) {
SDL_Delay(1);
Uint8 data[USB_PACKET_LENGTH];
size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0);
int size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0);
if (size < 0) {
break;
}
@ -211,6 +210,7 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
ctx->sensor_timestamp_step_ns = ctx->wireless ? SENSOR_INTERVAL_VADER4_PRO_DONGLE_NS : SENSOR_INTERVAL_VADER_PRO4_WIRED_NS;
break;
case 85:
case 105:
HIDAPI_SetDeviceName(device, "Flydigi Vader 4 Pro");
ctx->has_cz = true;
ctx->sensors_supported = true;
@ -218,6 +218,7 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
ctx->sensor_timestamp_step_ns = ctx->wireless ? SENSOR_INTERVAL_VADER4_PRO_DONGLE_NS : SENSOR_INTERVAL_VADER_PRO4_WIRED_NS;
break;
default:
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "Unknown FlyDigi controller with ID %d, name '%s'", ctx->deviceID, device->name);
break;
}
}

View File

@ -928,13 +928,14 @@ static bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, bool enabled)
static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
{
Uint8 *pLeftStickCal;
Uint8 *pRightStickCal;
Uint8 *pLeftStickCal = NULL;
Uint8 *pRightStickCal = NULL;
size_t stick, axis;
SwitchSubcommandInputPacket_t *user_reply = NULL;
SwitchSubcommandInputPacket_t *factory_reply = NULL;
SwitchSPIOpData_t readUserParams;
SwitchSPIOpData_t readFactoryParams;
Uint8 userParamsReadSuccessCount = 0;
// Read User Calibration Info
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
@ -947,6 +948,23 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
// Automatically select the user calibration if magic bytes are set
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
userParamsReadSuccessCount += 1;
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
}
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
userParamsReadSuccessCount += 1;
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
}
// Only read the factory calibration info if we failed to receive the correct magic bytes
if (userParamsReadSuccessCount < 2) {
// Read Factory Calibration Info
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
const int MAX_ATTEMPTS = 3;
for (int attempt = 0;; ++attempt) {
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
@ -955,6 +973,8 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
// We successfully read the calibration data
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
break;
}
@ -962,18 +982,12 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
return false;
}
}
// Automatically select the user calibration if magic bytes are set
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
} else {
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
}
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
} else {
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
// If we still don't have calibration data, return false
if (pLeftStickCal == NULL || pRightStickCal == NULL)
{
return false;
}
/* Stick calibration values are 12-bits each and are packed by bit
@ -1109,14 +1123,17 @@ static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, i
{
sRawValue -= ctx->m_StickCalData[nStick].axis[nAxis].sCenter;
if (sRawValue >= 0) {
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_StickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
} else {
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
}
}
static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue)
@ -1126,14 +1143,17 @@ static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nSt
sRawValue -= usJoystickCenter;
if (sRawValue >= 0) {
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
} else {
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
}
}
static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)

View File

@ -820,6 +820,35 @@ static SceGxmTextureAddrMode TranslateAddressMode(SDL_TextureAddressMode mode)
}
}
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 bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
{
SDL_Texture *texture = cmd->data.draw.texture;
@ -862,9 +891,13 @@ static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd
data->drawstate.cliprect_enabled_dirty = false;
}
if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
const SDL_Rect *rect = &data->drawstate.cliprect;
set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
if ((data->drawstate.cliprect_enabled || data->drawstate.viewport_is_set) && data->drawstate.cliprect_dirty) {
SDL_Rect rect;
SDL_copyp(&rect, &data->drawstate.cliprect);
if (data->drawstate.viewport_is_set) {
ClampCliprectToViewport(&rect, &data->drawstate.viewport);
}
set_clip_rectangle(data, rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
data->drawstate.cliprect_dirty = false;
}
@ -952,19 +985,30 @@ static void VITA_GXM_InvalidateCachedState(SDL_Renderer *renderer)
static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->internal;
int w, h;
StartDrawing(renderer);
data->drawstate.target = renderer->target;
if (!data->drawstate.target) {
int w, h;
SDL_GetWindowSizeInPixels(renderer->window, &w, &h);
} else {
float fw, fh;
if (!SDL_GetTextureSize(renderer->target, &fw, &fh)) {
w = data->drawstate.drawablew;
h = data->drawstate.drawableh;
} else {
w = (int)SDL_roundf(fw);
h = (int)SDL_roundf(fh);
}
}
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
data->drawstate.viewport_dirty = true; // if the window dimensions changed, invalidate the current viewport, etc.
data->drawstate.cliprect_dirty = true;
data->drawstate.drawablew = w;
data->drawstate.drawableh = h;
}
}
while (cmd) {
switch (cmd->command) {
@ -976,6 +1020,16 @@ static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *
SDL_copyp(viewport, &cmd->data.viewport.rect);
data->drawstate.viewport_dirty = true;
data->drawstate.cliprect_dirty = 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 = true;
}
}
}
break;
}
@ -983,9 +1037,15 @@ static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *
case SDL_RENDERCMD_SETCLIPRECT:
{
const SDL_Rect *rect = &cmd->data.cliprect.rect;
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 = 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) {

View File

@ -105,6 +105,7 @@ typedef struct
{
SDL_Rect viewport;
bool viewport_dirty;
bool viewport_is_set;
SDL_Texture *texture;
SDL_Texture *target;
SDL_FColor color;

View File

@ -3672,6 +3672,10 @@ bool SDL_SetWindowParent(SDL_Window *window, SDL_Window *parent)
CHECK_WINDOW_NOT_POPUP(parent, false);
}
if (window == parent) {
return SDL_SetError("Cannot set the parent of a window to itself.");
}
if (!_this->SetWindowParent) {
return SDL_Unsupported();
}
@ -4135,7 +4139,7 @@ void SDL_OnWindowLiveResizeUpdate(SDL_Window *window)
SDL_IterateMainCallbacks(false);
} else {
// Send an expose event so the application can redraw
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0);
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 1, 0);
}
SDL_PumpEventMaintenance();

View File

@ -110,8 +110,7 @@ void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForAndroid[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME

View File

@ -161,8 +161,7 @@ void Cocoa_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
char const* const* Cocoa_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *Cocoa_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForCocoa[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME

View File

@ -588,88 +588,51 @@ static void KMSDRM_DeinitDisplays(SDL_VideoDevice *_this)
}
}
static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd,
drmModeObjectPropertiesPtr props,
char const *name)
static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd, uint32_t output_id)
{
uint32_t i, prop_id = 0;
for (i = 0; !prop_id && i < props->count_props; ++i) {
drmModePropertyPtr drm_prop =
KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!drm_prop) {
continue;
}
if (SDL_strcmp(drm_prop->name, name) == 0) {
prop_id = drm_prop->prop_id;
}
KMSDRM_drmModeFreeProperty(drm_prop);
}
return prop_id;
}
static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
{
drmModeObjectPropertiesPtr drm_props;
drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!drm_props) {
return false;
}
*vrr_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
drm_props,
"VRR_ENABLED");
KMSDRM_drmModeFreeObjectProperties(drm_props);
return true;
}
static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd,
uint32_t output_id,
char const *name)
{
uint32_t i;
bool found = false;
uint64_t prop_value = 0;
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd,
output_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!props) {
return false;
}
for (i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!drm_prop) {
continue;
}
if (SDL_strcasecmp(drm_prop->name, name) == 0) {
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, output_id, DRM_MODE_OBJECT_CONNECTOR);
if (props) {
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (prop) {
if (SDL_strcasecmp(prop->name, "VRR_CAPABLE") == 0) {
prop_value = props->prop_values[i];
found = true;
}
KMSDRM_drmModeFreeProperty(drm_prop);
KMSDRM_drmModeFreeProperty(prop);
}
}
KMSDRM_drmModeFreeObjectProperties(props);
}
if (found) {
return prop_value ? true : false;
}
return false;
}
static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
{
bool found = false;
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
if (props) {
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (prop) {
if (SDL_strcmp(prop->name, "VRR_ENABLED") == 0) {
*vrr_prop_id = prop->prop_id;
found = true;
}
KMSDRM_drmModeFreeProperty(prop);
}
}
KMSDRM_drmModeFreeObjectProperties(props);
}
return found;
}
static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
{
uint32_t vrr_prop_id;
@ -677,119 +640,67 @@ static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
return;
}
KMSDRM_drmModeObjectSetProperty(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CRTC,
vrr_prop_id,
enabled);
KMSDRM_drmModeObjectSetProperty(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC, vrr_prop_id, enabled);
}
static bool KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id)
{
uint32_t object_prop_id, vrr_prop_id;
drmModeObjectPropertiesPtr props;
bool object_prop_value;
int i;
uint32_t vrr_prop_id = 0;
bool found = false;
uint64_t prop_value = 0;
if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) {
return false;
}
props = KMSDRM_drmModeObjectGetProperties(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!props) {
return false;
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
if (props) {
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (prop) {
if (prop->prop_id == vrr_prop_id) {
prop_value = props->prop_values[i];
found = true;
}
for (i = 0; i < props->count_props; ++i) {
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!drm_prop) {
continue;
KMSDRM_drmModeFreeProperty(prop);
}
object_prop_id = drm_prop->prop_id;
object_prop_value = props->prop_values[i] ? true : false;
KMSDRM_drmModeFreeProperty(drm_prop);
if (object_prop_id == vrr_prop_id) {
return object_prop_value;
}
KMSDRM_drmModeFreeObjectProperties(props);
}
if (found) {
return prop_value ? true : false;
}
return false;
}
static bool KMSDRM_OrientationPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *orientation_prop_id)
{
drmModeObjectPropertiesPtr drm_props;
drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!drm_props) {
return false;
}
*orientation_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
drm_props,
"panel orientation");
KMSDRM_drmModeFreeObjectProperties(drm_props);
return true;
}
static int KMSDRM_CrtcGetOrientation(uint32_t drm_fd, uint32_t crtc_id)
{
uint32_t orientation_prop_id;
drmModeObjectPropertiesPtr props;
int i;
bool done = false;
bool found = false;
int orientation = 0;
if (!KMSDRM_OrientationPropId(drm_fd, crtc_id, &orientation_prop_id)) {
return orientation;
}
props = KMSDRM_drmModeObjectGetProperties(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!props) {
return orientation;
}
for (i = 0; i < props->count_props && !done; ++i) {
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!drm_prop) {
continue;
}
if (drm_prop->prop_id == orientation_prop_id && (drm_prop->flags & DRM_MODE_PROP_ENUM)) {
if (drm_prop->count_enums) {
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CONNECTOR);
if (props) {
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (prop) {
if (SDL_strcasecmp(prop->name, "panel orientation") == 0 && (prop->flags & DRM_MODE_PROP_ENUM)) {
if (prop->count_enums) {
// "Normal" is the default of no rotation (0 degrees)
if (SDL_strcmp(drm_prop->enums[0].name, "Left Side Up") == 0) {
if (SDL_strcmp(prop->enums[0].name, "Left Side Up") == 0) {
orientation = 90;
} else if (SDL_strcmp(drm_prop->enums[0].name, "Upside Down") == 0) {
} else if (SDL_strcmp(prop->enums[0].name, "Upside Down") == 0) {
orientation = 180;
} else if (SDL_strcmp(drm_prop->enums[0].name, "Right Side Up") == 0) {
} else if (SDL_strcmp(prop->enums[0].name, "Right Side Up") == 0) {
orientation = 270;
}
}
done = true;
found = true;
}
KMSDRM_drmModeFreeProperty(prop);
}
KMSDRM_drmModeFreeProperty(drm_prop);
}
KMSDRM_drmModeFreeObjectProperties(props);
}
return orientation;
}
@ -964,7 +875,7 @@ static void KMSDRM_AddDisplay(SDL_VideoDevice *_this, drmModeConnector *connecto
// save previous vrr state
dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id);
// try to enable vrr
if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) {
if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id)) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, true);
}

View File

@ -140,8 +140,7 @@ void KMSDRM_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
// members of the VkInstanceCreateInfo struct passed to
// vkCreateInstance().
/*********************************************************************/
char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForKMSDRM[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME

View File

@ -39,7 +39,7 @@ static void CopyFramebuffertoN3DS_24(u8 *dest, const Dimensions dest_dim, const
static void CopyFramebuffertoN3DS_32(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim);
static int GetDestOffset(int x, int y, int dest_width);
static int GetSourceOffset(int x, int y, int source_width);
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen);
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen, bool swap);
bool SDL_N3DS_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch)
@ -67,6 +67,7 @@ bool SDL_N3DS_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window
bool SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects)
{
SDL_VideoData *internal = (SDL_VideoData *)_this->internal;
SDL_WindowData *drv_data = window->internal;
SDL_Surface *surface;
u16 width, height;
@ -79,7 +80,7 @@ bool SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window
}
// Get the N3DS internal framebuffer and its size
framebuffer = gfxGetFramebuffer(drv_data->screen, GFX_LEFT, &width, &height);
framebuffer = gfxGetFramebuffer(drv_data->screen, drv_data->side, &width, &height);
bufsize = width * height * 4;
if (SDL_BYTESPERPIXEL(surface->format) == 2)
@ -91,7 +92,32 @@ bool SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window
else
CopyFramebuffertoN3DS_32(framebuffer, (Dimensions){ width, height },
surface->pixels, (Dimensions){ surface->w, surface->h });
FlushN3DSBuffer(framebuffer, bufsize, drv_data->screen);
if(gfxIs3D() == false || drv_data->screen == GFX_BOTTOM)
FlushN3DSBuffer(framebuffer, bufsize, drv_data->screen, true);
else if(drv_data->screen == GFX_TOP) {
// We have to check if both screens are ready because if we can only
// swap both at the same time.
if(drv_data->side == GFX_LEFT)
internal->top_left_ready = true;
else if(drv_data->side == GFX_RIGHT)
internal->top_right_ready = true;
if(internal->top_left_ready && internal->top_right_ready) {
internal->top_left_ready = false;
internal->top_right_ready = false;
// This is safe because both screens share the same size
framebuffer = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &width, &height);
FlushN3DSBuffer(framebuffer, bufsize, GFX_TOP, false);
framebuffer = gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, &width, &height);
FlushN3DSBuffer(framebuffer, bufsize, GFX_TOP, true);
}
}
return true;
}
@ -147,10 +173,11 @@ static int GetSourceOffset(int x, int y, int source_width)
return x + y * source_width;
}
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen)
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen, bool swap)
{
GSPGPU_FlushDataCache(buffer, bufsize);
gfxScreenSwapBuffers(screen, false);
if(swap)
gfxScreenSwapBuffers(screen, gfxIs3D());
}
void SDL_N3DS_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window)

View File

@ -31,7 +31,7 @@
#define N3DSVID_DRIVER_NAME "n3ds"
static bool AddN3DSDisplay(gfxScreen_t screen);
static bool AddN3DSDisplay(gfxScreen_t screen, gfx3dSide_t side);
static bool N3DS_VideoInit(SDL_VideoDevice *_this);
static void N3DS_VideoQuit(SDL_VideoDevice *_this);
@ -44,6 +44,7 @@ static void N3DS_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
struct SDL_DisplayData
{
gfxScreen_t screen;
gfx3dSide_t side;
};
struct SDL_DisplayModeData
@ -127,8 +128,9 @@ static bool N3DS_VideoInit(SDL_VideoDevice *_this)
gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false);
hidInit();
internal->top_display = AddN3DSDisplay(GFX_TOP);
internal->touch_display = AddN3DSDisplay(GFX_BOTTOM);
internal->top_left_display = AddN3DSDisplay(GFX_TOP, GFX_LEFT);
internal->top_right_display = AddN3DSDisplay(GFX_TOP, GFX_RIGHT);
internal->touch_display = AddN3DSDisplay(GFX_BOTTOM, GFX_LEFT); // Bottom screen is always left
N3DS_InitTouch();
N3DS_SwkbInit();
@ -136,7 +138,7 @@ static bool N3DS_VideoInit(SDL_VideoDevice *_this)
return true;
}
static bool AddN3DSDisplay(gfxScreen_t screen)
static bool AddN3DSDisplay(gfxScreen_t screen, gfx3dSide_t side)
{
SDL_DisplayMode mode;
SDL_DisplayModeData *modedata;
@ -150,6 +152,7 @@ static bool AddN3DSDisplay(gfxScreen_t screen)
SDL_zero(display);
display_driver_data->screen = screen;
display_driver_data->side = side;
modedata = SDL_malloc(sizeof(SDL_DisplayModeData));
if (!modedata) {
@ -163,7 +166,7 @@ static bool AddN3DSDisplay(gfxScreen_t screen)
mode.internal = modedata;
modedata->fmt = GSP_RGBA8_OES;
display.name = (screen == GFX_TOP) ? "N3DS top screen" : "N3DS bottom screen";
display.name = (screen == GFX_BOTTOM) ? "N3DS bottom screen" : (side == GFX_LEFT) ? "N3DS top screen" : "N3DS right screen";
display.desktop_mode = mode;
display.internal = display_driver_data;
@ -228,7 +231,12 @@ static bool N3DS_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *disp
}
rect->x = 0;
rect->y = (driver_data->screen == GFX_TOP) ? 0 : GSP_SCREEN_WIDTH;
rect->y = 0;
if(driver_data->screen == GFX_BOTTOM)
rect->y = GSP_SCREEN_WIDTH;
if(driver_data->screen == GFX_TOP && driver_data->side == GFX_RIGHT)
rect->y = GSP_SCREEN_WIDTH * 2;
rect->w = display->current_mode->w;
rect->h = display->current_mode->h;
return true;
@ -243,6 +251,7 @@ static bool N3DS_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Pr
}
display_data = SDL_GetDisplayDriverDataForWindow(window);
window_data->screen = display_data->screen;
window_data->side = display_data->side;
window->internal = window_data;
SDL_SetKeyboardFocus(window);
return true;

View File

@ -29,13 +29,19 @@
struct SDL_VideoData
{
int top_display;
int top_left_display;
int top_right_display;
int touch_display;
// The following two variables keep track of if it is ready to swap the buffers
bool top_left_ready;
bool top_right_ready;
};
struct SDL_WindowData
{
gfxScreen_t screen; /**< Keeps track of which N3DS screen is targeted */
gfx3dSide_t side;
};
#endif // SDL_n3dsvideo_h_

View File

@ -167,8 +167,7 @@ void UIKit_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
char const* const* UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForUIKit[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME

View File

@ -117,8 +117,7 @@ void VIVANTE_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
char const* const* VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForVivante[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME

View File

@ -701,6 +701,10 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
float fAmount = (float)amount / WHEEL_DELTA;
SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
}
/* Invalidate the mouse button flags. If we don't do this then disabling raw input
will cause held down mouse buttons to persist when released. */
windowdata->mouse_button_flags = (WPARAM)-1;
}
}

View File

@ -279,6 +279,9 @@ static void GAMEINPUT_InitialMouseReading(WIN_GameInputData *data, SDL_Window *w
bool down = ((state.buttons & mask) != 0);
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
}
// Invalidate mouse button flags
window->internal->mouse_button_flags = (WPARAM)-1;
}
}
@ -308,6 +311,9 @@ static void GAMEINPUT_HandleMouseDelta(WIN_GameInputData *data, SDL_Window *wind
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
}
}
// Invalidate mouse button flags
window->internal->mouse_button_flags = (WPARAM)-1;
}
if (delta.wheelX || delta.wheelY) {
float fAmountX = (float)delta.wheelX / WHEEL_DELTA;

View File

@ -110,8 +110,7 @@ void WIN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
static const char *const extensionsForWin32[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME

View File

@ -144,8 +144,7 @@ void X11_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
}
}
char const* const* X11_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
char const * const *X11_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count)
{
SDL_VideoData *videoData = _this->internal;
if (videoData->vulkan_xlib_xcb_library) {

View File

@ -420,7 +420,7 @@ add_sdl_test_executable(testdialog SOURCES testdialog.c)
add_sdl_test_executable(testtime SOURCES testtime.c)
add_sdl_test_executable(testmanymouse SOURCES testmanymouse.c)
add_sdl_test_executable(testmodal SOURCES testmodal.c)
add_sdl_test_executable(testtray SOURCES testtray.c)
add_sdl_test_executable(testtray NEEDS_RESOURCES TESTUTILS SOURCES testtray.c)
add_sdl_test_executable(testprocess

View File

@ -1611,8 +1611,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
has_gyro = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO);
if (has_accel || has_gyro) {
const float gyro_sensor_rate = has_gyro ? SDL_GetGamepadSensorDataRate(gamepad, SDL_SENSOR_GYRO) : 0;
const int SENSOR_UPDATE_INTERVAL_MS = gyro_sensor_rate > 0.0f ? (int)( 1000.0f / gyro_sensor_rate ) : 100;
const int SENSOR_UPDATE_INTERVAL_MS = 100;
Uint64 now = SDL_GetTicks();
if (now >= ctx->last_sensor_update + SENSOR_UPDATE_INTERVAL_MS) {
@ -1622,6 +1621,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
if (has_gyro) {
SDL_GetGamepadSensorData(gamepad, SDL_SENSOR_GYRO, ctx->gyro_data, SDL_arraysize(ctx->gyro_data));
}
ctx->last_sensor_update = now;
}
if (has_accel) {
@ -1639,8 +1639,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
SDLTest_DrawString(ctx->renderer, x + center + 2.0f, y, text);
/* Display a smoothed version of the above for the sake of turntable tests */
/* Display the testcontroller tool's evaluation of drift. This is also useful to get an average rate of turn in calibrated turntable tests. */
if (ctx->gyro_drift_correction_data[0] != 0.0f && ctx->gyro_drift_correction_data[2] != 0.0f && ctx->gyro_drift_correction_data[2] != 0.0f )
{
y += ctx->button_height + 2.0f;
@ -1652,7 +1651,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
}
ctx->last_sensor_update = now;
}
}
SDL_free(mapping);

View File

@ -143,7 +143,7 @@ extern void DestroyGamepadButton(GamepadButton *ctx);
/* Gyro element Display */
/* If you want to calbirate against a known rotation (i.e. a turn table test) Increase ACCELEROMETER_NOISE_THRESHOLD to about 5, or drift correction will be constantly reset.*/
#define ACCELEROMETER_NOISE_THRESHOLD 0.125f
#define ACCELEROMETER_NOISE_THRESHOLD 0.5f
typedef struct Quaternion Quaternion;
typedef struct GyroDisplay GyroDisplay;

View File

@ -1409,11 +1409,13 @@ static void UpdateGamepadOrientation( Uint64 delta_time_ns )
static void HandleGamepadSensorEvent( SDL_Event* event )
{
if (!controller)
if (!controller) {
return;
}
if (controller->id != event->gsensor.which)
if (controller->id != event->gsensor.which) {
return;
}
if (event->gsensor.sensor == SDL_SENSOR_GYRO) {
HandleGamepadGyroEvent(event);

View File

@ -679,6 +679,16 @@ void SetupVulkanRenderProperties(VulkanVideoContext *context, SDL_PropertiesID p
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER, context->graphicsQueueFamilyIndex);
}
#if LIBAVUTIL_VERSION_MAJOR >= 59
static void AddQueueFamily(AVVulkanDeviceContext *ctx, int idx, int num, VkQueueFlagBits flags)
{
AVVulkanDeviceQueueFamily *entry = &ctx->qf[ctx->nb_qf++];
entry->idx = idx;
entry->num = num;
entry->flags = flags;
}
#endif /* LIBAVUTIL_VERSION_MAJOR */
void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceContext *ctx)
{
ctx->get_proc_addr = context->vkGetInstanceProcAddr;
@ -690,6 +700,12 @@ void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceCon
ctx->nb_enabled_inst_extensions = context->instanceExtensionsCount;
ctx->enabled_dev_extensions = context->deviceExtensions;
ctx->nb_enabled_dev_extensions = context->deviceExtensionsCount;
#if LIBAVUTIL_VERSION_MAJOR >= 59
AddQueueFamily(ctx, context->graphicsQueueFamilyIndex, context->graphicsQueueCount, VK_QUEUE_GRAPHICS_BIT);
AddQueueFamily(ctx, context->transferQueueFamilyIndex, context->transferQueueCount, VK_QUEUE_TRANSFER_BIT);
AddQueueFamily(ctx, context->computeQueueFamilyIndex, context->computeQueueCount, VK_QUEUE_COMPUTE_BIT);
AddQueueFamily(ctx, context->decodeQueueFamilyIndex, context->decodeQueueCount, VK_QUEUE_VIDEO_DECODE_BIT_KHR);
#else
ctx->queue_family_index = context->graphicsQueueFamilyIndex;
ctx->nb_graphics_queues = context->graphicsQueueCount;
ctx->queue_family_tx_index = context->transferQueueFamilyIndex;
@ -700,6 +716,7 @@ void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceCon
ctx->nb_encode_queues = 0;
ctx->queue_family_decode_index = context->decodeQueueFamilyIndex;
ctx->nb_decode_queues = context->decodeQueueCount;
#endif /* LIBAVUTIL_VERSION_MAJOR */
}
static int CreateCommandBuffers(VulkanVideoContext *context, SDL_Renderer *renderer)

View File

@ -97,7 +97,7 @@ int main(int argc, char *argv[])
}
if (e.key.key == SDLK_M) {
if (SDL_SetWindowParent(w2, w2)) {
if (SDL_SetWindowParent(w2, w1)) {
if (SDL_SetWindowModal(w2, true)) {
SDL_SetWindowTitle(w2, "Modal Window");
}

View File

@ -1,3 +1,4 @@
#include "testutils.h"
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
@ -520,14 +521,17 @@ int main(int argc, char **argv)
goto quit;
}
/* TODO: Resource paths? */
SDL_Surface *icon = SDL_LoadBMP("../test/sdl-test_round.bmp");
char *icon1filename = GetResourceFilename(NULL, "sdl-test_round.bmp");
SDL_Surface *icon = SDL_LoadBMP(icon1filename);
SDL_free(icon1filename);
if (!icon) {
SDL_Log("Couldn't load icon 1, proceeding without: %s", SDL_GetError());
}
SDL_Surface *icon2 = SDL_LoadBMP("../test/speaker.bmp");
char *icon2filename = GetResourceFilename(NULL, "speaker.bmp");
SDL_Surface *icon2 = SDL_LoadBMP(icon2filename);
SDL_free(icon2filename);
if (!icon2) {
SDL_Log("Couldn't load icon 2, proceeding without: %s", SDL_GetError());