update sdl2 to 2.32.10

This commit is contained in:
AzaezelX 2025-12-24 13:35:39 -06:00
parent a181f488b2
commit 4823dee76e
44 changed files with 439 additions and 182 deletions

View file

@ -83,6 +83,12 @@ static int (*ALSA_snd_device_name_hint)(int, const char *, void ***);
static char *(*ALSA_snd_device_name_get_hint)(const void *, const char *);
static int (*ALSA_snd_device_name_free_hint)(void **);
static snd_pcm_sframes_t (*ALSA_snd_pcm_avail)(snd_pcm_t *);
static int (*ALSA_snd_pcm_info)(snd_pcm_t *, snd_pcm_info_t *);
static const char *(*ALSA_snd_pcm_info_get_name)(const snd_pcm_info_t *);
static int (*ALSA_snd_pcm_info_get_card)(const snd_pcm_info_t *);
static int (*ALSA_snd_card_get_name)(int, char **);
static int (*ALSA_snd_pcm_info_malloc)(snd_pcm_info_t **);
static int (*ALSA_snd_pcm_info_free)(snd_pcm_info_t *);
#ifdef SND_CHMAP_API_VERSION
static snd_pcm_chmap_t *(*ALSA_snd_pcm_get_chmap)(snd_pcm_t *);
static int (*ALSA_snd_pcm_chmap_print)(const snd_pcm_chmap_t *map, size_t maxlen, char *buf);
@ -152,6 +158,12 @@ static int load_alsa_syms(void)
SDL_ALSA_SYM(snd_device_name_get_hint);
SDL_ALSA_SYM(snd_device_name_free_hint);
SDL_ALSA_SYM(snd_pcm_avail);
SDL_ALSA_SYM(snd_pcm_info);
SDL_ALSA_SYM(snd_pcm_info_get_card);
SDL_ALSA_SYM(snd_pcm_info_get_name);
SDL_ALSA_SYM(snd_card_get_name);
SDL_ALSA_SYM(snd_pcm_info_malloc);
SDL_ALSA_SYM(snd_pcm_info_free);
#ifdef SND_CHMAP_API_VERSION
SDL_ALSA_SYM(snd_pcm_get_chmap);
SDL_ALSA_SYM(snd_pcm_chmap_print);
@ -466,6 +478,58 @@ static void ALSA_CloseDevice(_THIS)
SDL_free(this->hidden);
}
static int ALSA_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
{
const char *device = "default";
snd_pcm_t *pcm_handle;
snd_pcm_info_t *pcm_info;
snd_pcm_stream_t stream;
int card_index;
const char *dev_name;
char *card_name = NULL;
char final_name[256];
SDL_zero(final_name);
stream = iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK;
if (ALSA_snd_pcm_open(&pcm_handle, device, stream, SND_PCM_NONBLOCK) < 0) {
return SDL_SetError("ALSA: Couldn't open default device");
}
if (ALSA_snd_pcm_info_malloc(&pcm_info) < 0) {
ALSA_snd_pcm_close(pcm_handle);
return SDL_SetError("ALSA: Couldn't allocate pcm_info");
}
if (ALSA_snd_pcm_info(pcm_handle, pcm_info) < 0) {
ALSA_snd_pcm_info_free(pcm_info);
ALSA_snd_pcm_close(pcm_handle);
return SDL_SetError("ALSA: Couldn't get PCM info");
}
card_index = ALSA_snd_pcm_info_get_card(pcm_info);
dev_name = ALSA_snd_pcm_info_get_name(pcm_info);
if (card_index >= 0 && ALSA_snd_card_get_name(card_index, &card_name) >= 0) {
SDL_snprintf(final_name, sizeof(final_name), "%s, %s", card_name, dev_name);
*name = SDL_strdup(final_name);
} else {
*name = SDL_strdup(dev_name ? dev_name : "Unknown ALSA Device");
}
if (spec) {
SDL_zero(*spec);
spec->freq = 48000;
spec->format = AUDIO_S16SYS;
spec->channels = 2;
spec->samples = 512;
}
ALSA_snd_pcm_info_free(pcm_info);
ALSA_snd_pcm_close(pcm_handle);
return 0;
}
static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
{
int status;
@ -975,6 +1039,7 @@ static SDL_bool ALSA_Init(SDL_AudioDriverImpl *impl)
impl->Deinitialize = ALSA_Deinitialize;
impl->CaptureFromDevice = ALSA_CaptureFromDevice;
impl->FlushCapture = ALSA_FlushCapture;
impl->GetDefaultAudioInfo = ALSA_GetDefaultAudioInfo;
impl->HasCaptureSupport = SDL_TRUE;
impl->SupportsNonPow2Samples = SDL_TRUE;

View file

@ -383,7 +383,8 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec
hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY);
if (hint) {
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) {
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0 ||
SDL_strcasecmp(hint, "ambient") == 0) {
category = AVAudioSessionCategoryAmbient;
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) {
category = AVAudioSessionCategorySoloAmbient;

View file

@ -413,27 +413,32 @@ static int openslES_CreatePCMPlayer(_THIS)
SLresult result;
int i;
/* If we want to add floating point audio support (requires API level 21)
it can be done as described here:
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
*/
/* according to https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android,
Android's OpenSL ES only supports Uint8 and _littleendian_ Sint16.
(and float32, with an extension we use, below.) */
if (SDL_GetAndroidSDKVersion() >= 21) {
SDL_AudioFormat test_format;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (SDL_AUDIO_ISSIGNED(test_format)) {
switch (test_format) {
case AUDIO_U8:
case AUDIO_S16LSB:
case AUDIO_F32LSB:
break;
default:
continue;
}
break;
}
if (!test_format) {
/* Didn't find a compatible format : */
LOGI("No compatible audio format, using signed 16-bit audio");
test_format = AUDIO_S16SYS;
LOGI("No compatible audio format, using signed 16-bit LE audio");
test_format = AUDIO_S16LSB;
}
this->spec.format = test_format;
} else {
/* Just go with signed 16-bit audio as it's the most compatible */
this->spec.format = AUDIO_S16SYS;
this->spec.format = AUDIO_S16LSB;
}
/* Update the fragment size as size in bytes */

View file

@ -574,6 +574,25 @@ static SDL_bool get_int_param(const struct spa_pod *param, Uint32 key, int *val)
return SDL_FALSE;
}
static SDL_AudioFormat SPAFormatToSDL(enum spa_audio_format spafmt)
{
switch (spafmt) {
#define CHECKFMT(spa,sdl) case SPA_AUDIO_FORMAT_##spa: return AUDIO_##sdl
CHECKFMT(U8, U8);
CHECKFMT(S8, S8);
CHECKFMT(S16_LE, S16LSB);
CHECKFMT(S16_BE, S16MSB);
CHECKFMT(S32_LE, S32LSB);
CHECKFMT(S32_BE, S32MSB);
CHECKFMT(F32_LE, F32LSB);
CHECKFMT(F32_BE, F32MSB);
#undef CHECKFMT
default: break;
}
return 0;
}
/* Interface node callbacks */
static void node_event_info(void *object, const struct pw_node_info *info)
{
@ -602,6 +621,15 @@ static void node_event_param(void *object, int seq, uint32_t id, uint32_t index,
struct node_object *node = object;
struct io_node *io = node->userdata;
if ((id == SPA_PARAM_Format) && (io->spec.format == 0)) {
struct spa_audio_info_raw info;
SDL_zero(info);
if (spa_format_audio_raw_parse(param, &info) == 0) {
/*SDL_Log("Sink Format: %d, Rate: %d Hz, Channels: %d", info.format, info.rate, info.channels);*/
io->spec.format = SPAFormatToSDL(info.format);
}
}
/* Get the default frequency */
if (io->spec.freq == 0) {
get_range_param(param, SPA_FORMAT_AUDIO_rate, &io->spec.freq, NULL, NULL);
@ -719,7 +747,9 @@ static void registry_event_global_callback(void *object, uint32_t id, uint32_t p
/* Begin setting the node properties */
io->id = id;
io->is_capture = is_capture;
io->spec.format = AUDIO_F32; /* Pipewire uses floats internally, other formats require conversion. */
if (io->spec.format == 0) {
io->spec.format = AUDIO_S16; /* we'll go conservative here if for some reason the format isn't known. */
}
io->name = io->buf;
io->path = io->buf + desc_buffer_len;
SDL_strlcpy(io->buf, node_desc, desc_buffer_len);

View file

@ -24,18 +24,12 @@
/* Allow access to a raw mixing buffer */
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#ifdef __NETBSD__
#include <sys/ioctl.h>
#include <sys/audioio.h>
#endif
#ifdef __SVR4
#include <sys/audioio.h>
#else
#include <sys/time.h>
#include <sys/types.h>
#endif
#include <unistd.h>
#include "SDL_timer.h"

View file

@ -127,7 +127,11 @@
#define CPU_CFG2_LSX (1 << 6)
#define CPU_CFG2_LASX (1 << 7)
#if defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) && !defined(__MACOSX__) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
#if !defined(SDL_CPUINFO_DISABLED) && \
!((defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))) && \
!(defined(__FreeBSD__) && defined(__powerpc__)) && \
!(defined(__LINUX__) && defined(__powerpc__) && defined(HAVE_GETAUXVAL)) && \
defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
/* This is the brute force way of detecting instruction sets...
the idea is borrowed from the libmpeg2 library - thanks!
*/
@ -356,6 +360,8 @@ static int CPU_haveAltiVec(void)
elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures));
altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
return altivec;
#elif defined(__LINUX__) && defined(__powerpc__) && defined(HAVE_GETAUXVAL)
altivec = getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC;
#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
void (*handler)(int sig);
handler = signal(SIGILL, illegal_instruction);

View file

@ -738,21 +738,17 @@ static void SDL_CutEvent(SDL_EventEntry *entry)
static int SDL_SendWakeupEvent(void)
{
SDL_Window *wakeup_window;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (_this == NULL || !_this->SendWakeupEvent) {
return 0;
}
SDL_LockMutex(_this->wakeup_lock);
{
if (_this->wakeup_window) {
_this->SendWakeupEvent(_this, _this->wakeup_window);
/* No more wakeup events needed until we enter a new wait */
_this->wakeup_window = NULL;
}
/* We only want to do this once while waiting for an event, so set it to NULL atomically here */
wakeup_window = (SDL_Window *)SDL_AtomicSetPtr(&_this->wakeup_window, NULL);
if (wakeup_window) {
_this->SendWakeupEvent(_this, wakeup_window);
}
SDL_UnlockMutex(_this->wakeup_lock);
return 0;
}
@ -1009,18 +1005,7 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve
int status;
SDL_PumpEventsInternal(SDL_TRUE);
SDL_LockMutex(_this->wakeup_lock);
{
status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
/* If status == 0 we are going to block so wakeup will be needed. */
if (status == 0) {
_this->wakeup_window = wakeup_window;
} else {
_this->wakeup_window = NULL;
}
}
SDL_UnlockMutex(_this->wakeup_lock);
status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
if (status < 0) {
/* Got an error: return */
break;
@ -1033,8 +1018,6 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve
if (timeout > 0) {
Uint32 elapsed = SDL_GetTicks() - start;
if (elapsed >= (Uint32)timeout) {
/* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL;
return 0;
}
loop_timeout = (int)((Uint32)timeout - elapsed);
@ -1049,9 +1032,9 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve
}
}
SDL_AtomicSetPtr(&_this->wakeup_window, wakeup_window);
status = _this->WaitEventTimeout(_this, loop_timeout);
/* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL;
SDL_AtomicSetPtr(&_this->wakeup_window, NULL);
if (status == 0 && poll_interval != SDL_MAX_SINT16 && loop_timeout == poll_interval) {
/* We may have woken up to poll. Try again */
continue;

View file

@ -630,11 +630,9 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL;
#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX
#define HAVE_DRIVER_BACKEND 1
#else
#define HAVE_DRIVER_BACKEND 0
#endif
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
/* DRIVER HIDAPI Implementation */
@ -905,7 +903,7 @@ IsInWhitelist(Uint16 vendor, Uint16 product)
return SDL_FALSE;
}
#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND)
#define use_libusb_whitelist_default SDL_TRUE
#else
#define use_libusb_whitelist_default SDL_FALSE
@ -951,7 +949,7 @@ static const struct hidapi_backend PLATFORM_Backend = {
};
#endif /* HAVE_PLATFORM_BACKEND */
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
static const struct hidapi_backend DRIVER_Backend = {
(void *)DRIVER_hid_write,
(void *)DRIVER_hid_read_timeout,
@ -993,7 +991,7 @@ struct SDL_hid_device_
};
static char device_magic;
#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
{
@ -1019,7 +1017,7 @@ static void DeleteHIDDeviceWrapper(SDL_hid_device *device)
}
#ifndef SDL_HIDAPI_DISABLED
#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
#define COPY_IF_EXISTS(var) \
if (pSrc->var != NULL) { \
@ -1249,12 +1247,12 @@ Uint32 SDL_hid_device_change_count(void)
struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
#ifdef HAVE_LIBUSB
struct SDL_hid_device_info *usb_devs = NULL;
struct SDL_hid_device_info *usb_dev;
#endif
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
struct SDL_hid_device_info *driver_devs = NULL;
struct SDL_hid_device_info *driver_dev;
#endif
@ -1309,7 +1307,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
}
#endif /* HAVE_LIBUSB */
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
driver_devs = DRIVER_hid_enumerate(vendor_id, product_id);
for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) {
new_dev = (struct SDL_hid_device_info *)SDL_malloc(sizeof(struct SDL_hid_device_info));
@ -1347,7 +1345,7 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
}
}
#endif
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) {
if (raw_dev->vendor_id == driver_dev->vendor_id &&
raw_dev->product_id == driver_dev->product_id &&
@ -1412,7 +1410,7 @@ void SDL_hid_free_enumeration(struct SDL_hid_device_info *devs)
SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
{
#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
void *pDevice = NULL;
if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) {
@ -1428,7 +1426,7 @@ SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id
}
#endif /* HAVE_PLATFORM_BACKEND */
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
pDevice = DRIVER_hid_open(vendor_id, product_id, serial_number);
if (pDevice != NULL) {
return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
@ -1451,7 +1449,7 @@ SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id
SDL_hid_device *SDL_hid_open_path(const char *path, int bExclusive /* = false */)
{
#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB)
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
void *pDevice = NULL;
if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) {
@ -1467,7 +1465,7 @@ SDL_hid_device *SDL_hid_open_path(const char *path, int bExclusive /* = false */
}
#endif /* HAVE_PLATFORM_BACKEND */
#if HAVE_DRIVER_BACKEND
#ifdef HAVE_DRIVER_BACKEND
pDevice = DRIVER_hid_open_path(path, bExclusive);
if (pDevice != NULL) {
return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);

View file

@ -62,9 +62,7 @@
#define SWITCH_GYRO_SCALE 14.2842f
#define SWITCH_ACCEL_SCALE 4096.f
#define SWITCH_GYRO_SCALE_OFFSET 13371.0f
#define SWITCH_GYRO_SCALE_MULT 936.0f
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
#define SWITCH_ACCEL_SCALE_MULT 4.0f
typedef enum
@ -819,7 +817,7 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
SwitchSPIOpData_t readFactoryParams;
const int MAX_ATTEMPTS = 3;
int attempt;
/* Read User Calibration Info */
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
readUserParams.ucLength = k_unSPIStickUserCalibrationLength;
@ -925,6 +923,8 @@ static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) {
Uint8 *pIMUScale;
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
Sint16 sAccelSensCoeffX, sAccelSensCoeffY, sAccelSensCoeffZ;
Sint16 sGyroSensCoeffX, sGyroSensCoeffY, sGyroSensCoeffZ;
/* IMU scale gives us multipliers for converting raw values to real world values */
pIMUScale = reply->spiReadData.rgucReadData;
@ -933,10 +933,18 @@ static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
sAccelRawY = (pIMUScale[3] << 8) | pIMUScale[2];
sAccelRawZ = (pIMUScale[5] << 8) | pIMUScale[4];
sAccelSensCoeffX = (pIMUScale[7] << 8) | pIMUScale[6];
sAccelSensCoeffY = (pIMUScale[9] << 8) | pIMUScale[8];
sAccelSensCoeffZ = (pIMUScale[11] << 8) | pIMUScale[10];
sGyroRawX = (pIMUScale[13] << 8) | pIMUScale[12];
sGyroRawY = (pIMUScale[15] << 8) | pIMUScale[14];
sGyroRawZ = (pIMUScale[17] << 8) | pIMUScale[16];
sGyroSensCoeffX = (pIMUScale[19] << 8) | pIMUScale[18];
sGyroSensCoeffY = (pIMUScale[21] << 8) | pIMUScale[20];
sGyroSensCoeffZ = (pIMUScale[23] << 8) | pIMUScale[22];
/* Check for user calibration data. If it's present and set, it'll override the factory settings */
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
readParams.ucLength = k_unSPIIMUUserScaleLength;
@ -953,14 +961,14 @@ static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
}
/* Accelerometer scale */
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffX - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffY - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffZ - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
/* Gyro scale */
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffX - (float)sGyroRawX) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffY - (float)sGyroRawY) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffZ - (float)sGyroRawZ) * (float)M_PI / 180.0f;
} else {
/* Use default values */
@ -982,15 +990,17 @@ static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, i
{
sRawValue -= ctx->m_StickCalData[nStick].axis[nAxis].sCenter;
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
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, 0, SDL_MIN_SINT16, 0);
}
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);
}
static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue)
@ -1000,15 +1010,17 @@ static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nSt
sRawValue -= usJoystickCenter;
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
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, 0, SDL_MIN_SINT16, 0);
}
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);
}
static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)

View file

@ -822,11 +822,12 @@ SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJo
++SDL_HIDAPI_numjoysticks;
SDL_PrivateJoystickAdded(joystickID);
if (pJoystickID) {
*pJoystickID = joystickID;
}
SDL_PrivateJoystickAdded(joystickID);
return SDL_TRUE;
}

View file

@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,32,6,0
PRODUCTVERSION 2,32,6,0
FILEVERSION 2,32,10,0
PRODUCTVERSION 2,32,10,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "2, 32, 6, 0\0"
VALUE "FileVersion", "2, 32, 10, 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, 6, 0\0"
VALUE "ProductVersion", "2, 32, 10, 0\0"
END
END
BLOCK "VarFileInfo"

View file

@ -2221,8 +2221,8 @@ SDL_RenderDriver GLES2_RenderDriver = {
{ "opengles2",
(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
4,
{ SDL_PIXELFORMAT_BGRA32,
SDL_PIXELFORMAT_ABGR32,
{ SDL_PIXELFORMAT_RGBA32,
SDL_PIXELFORMAT_BGRA32,
SDL_PIXELFORMAT_BGRX32,
SDL_PIXELFORMAT_RGBX32 },
0,

View file

@ -55,7 +55,7 @@ typedef struct
static int vsync_sema_id = 0;
/* PRIVATE METHODS */
static int vsync_handler(void)
static int vsync_handler(int reason)
{
iSignalSema(vsync_sema_id);

View file

@ -826,6 +826,35 @@ static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
return 0;
}
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 int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
{
SDL_Texture *texture = cmd->data.draw.texture;
@ -868,9 +897,13 @@ static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
data->drawstate.cliprect_enabled_dirty = SDL_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 = SDL_FALSE;
}
@ -925,20 +958,27 @@ static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
int w, h;
StartDrawing(renderer);
data->drawstate.target = renderer->target;
if (!data->drawstate.target) {
int w, h;
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
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;
} else {
if (SDL_QueryTexture(renderer->target, NULL, NULL, &w, &h) < 0) {
w = data->drawstate.drawablew;
h = data->drawstate.drawableh;
}
}
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) {
@ -949,6 +989,16 @@ static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *c
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;
}
@ -956,9 +1006,15 @@ static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *c
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 = 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) {

View file

@ -106,6 +106,7 @@ typedef struct
{
SDL_Rect viewport;
SDL_bool viewport_dirty;
SDL_bool viewport_is_set;
SDL_Texture *texture;
SDL_Texture *target;
SDL_Color color;

View file

@ -34,6 +34,8 @@
#include <pspkerneltypes.h>
#include <pspthreadman.h>
#define PSP_THREAD_NAME_MAX 32
static int ThreadEntry(SceSize args, void *argp)
{
SDL_RunThread(*(SDL_Thread **)argp);
@ -44,6 +46,7 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)
{
SceKernelThreadInfo status;
int priority = 32;
char thread_name[PSP_THREAD_NAME_MAX];
/* Set priority of new thread to the same as the current thread */
status.size = sizeof(SceKernelThreadInfo);
@ -51,7 +54,12 @@ int SDL_SYS_CreateThread(SDL_Thread *thread)
priority = status.currentPriority;
}
thread->handle = sceKernelCreateThread(thread->name, ThreadEntry,
SDL_strlcpy(thread_name, "SDL thread", PSP_THREAD_NAME_MAX);
if (thread->name) {
SDL_strlcpy(thread_name, thread->name, PSP_THREAD_NAME_MAX);
}
thread->handle = sceKernelCreateThread(thread_name, ThreadEntry,
priority, thread->stacksize ? ((int)thread->stacksize) : 0x8000,
PSP_THREAD_ATTR_VFPU, NULL);
if (thread->handle < 0) {

View file

@ -355,8 +355,7 @@ struct SDL_VideoDevice
SDL_bool checked_texture_framebuffer;
SDL_bool is_dummy;
SDL_bool suspend_screensaver;
SDL_Window *wakeup_window;
SDL_mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */
void *wakeup_window;
int num_displays;
SDL_VideoDisplay *displays;
SDL_Window *windows;

View file

@ -3368,9 +3368,7 @@ void SDL_DestroyWindow(SDL_Window *window)
_this->current_glwin = NULL;
}
if (_this->wakeup_window == window) {
_this->wakeup_window = NULL;
}
SDL_AtomicCASPtr(&_this->wakeup_window, window, NULL);
/* Now invalidate magic */
window->magic = NULL;

View file

@ -287,9 +287,19 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
/* The menu bar of SDL apps which don't have the typical .app bundle
* structure fails to work the first time a window is created (until it's
* de-focused and re-focused), if this call is in Cocoa_RegisterApp instead
* of here. https://bugzilla.libsdl.org/show_bug.cgi?id=3051
* of here. https://github.com/libsdl-org/SDL/issues/1913
*/
if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) {
/* this apparently became unnecessary on macOS 14.0, and will addition pop up a
hidden dock if you're moving the mouse during launch, so change the default
behaviour there. https://github.com/libsdl-org/SDL/issues/10340
(13.6 still needs it, presumably 13.7 does, too.) */
SDL_bool background_app_default = SDL_FALSE;
if (@available(macOS 14.0, *)) {
background_app_default = SDL_TRUE; /* by default, don't explicitly activate the dock and then us again to force to foreground */
}
if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, background_app_default)) {
/* Get more aggressive for Catalina: activate the Dock first so we definitely reset all activation state. */
for (NSRunningApplication *i in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) {
[i activateWithOptions:NSApplicationActivateIgnoringOtherApps];

View file

@ -48,9 +48,6 @@ static void Cocoa_VideoQuit(_THIS);
static void Cocoa_DeleteDevice(SDL_VideoDevice * device)
{ @autoreleasepool
{
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
}
CFBridgingRelease(device->driverdata);
SDL_free(device);
}}
@ -76,7 +73,6 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void)
return NULL;
}
device->driverdata = (void *)CFBridgingRetain(data);
device->wakeup_lock = SDL_CreateMutex();
/* Set the function pointers */
device->VideoInit = Cocoa_VideoInit;

View file

@ -855,6 +855,11 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
/* The OS can resize the window automatically if the display density
changes while the window is miniaturized or hidden */
if (![nswindow isVisible])
return;
/* isZoomed always returns true if the window is not resizable */
if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
zoomed = YES;

View file

@ -79,7 +79,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect
if (!Module['SDL2']) Module['SDL2'] = {};
var SDL2 = Module['SDL2'];
if (SDL2.ctxCanvas !== Module['canvas']) {
SDL2.ctx = Module['createContext'](Module['canvas'], false, true);
SDL2.ctx = Browser.createContext(Module['canvas'], false, true);
SDL2.ctxCanvas = Module['canvas'];
}
if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) {

View file

@ -40,6 +40,48 @@
*/
#define PIPE_MS_TIMEOUT 14
/* sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it.
* Based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation
*/
#ifndef HAVE_SIGTIMEDWAIT
#include <errno.h>
#include <time.h>
static int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
{
struct timespec elapsed = { 0 }, rem = { 0 };
sigset_t pending;
int signo;
do {
/* Check the pending signals, and call sigwait if there is at least one of interest in the set. */
sigpending(&pending);
for (signo = 1; signo < NSIG; ++signo) {
if (sigismember(set, signo) && sigismember(&pending, signo)) {
if (!sigwait(set, &signo)) {
if (info) {
SDL_memset(info, 0, sizeof *info);
info->si_signo = signo;
}
return signo;
} else {
return -1;
}
}
}
if (timeout->tv_sec || timeout->tv_nsec) {
long ns = 20000000L; // 2/100ths of a second
nanosleep(&(struct timespec){ 0, ns }, &rem);
ns -= rem.tv_nsec;
elapsed.tv_sec += (elapsed.tv_nsec + ns) / 1000000000L;
elapsed.tv_nsec = (elapsed.tv_nsec + ns) % 1000000000L;
}
} while (elapsed.tv_sec < timeout->tv_sec || (elapsed.tv_sec == timeout->tv_sec && elapsed.tv_nsec < timeout->tv_nsec));
errno = EAGAIN;
return -1;
}
#endif
static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_t *pos)
{
int ready = 0;
@ -75,7 +117,7 @@ static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_
}
}
sigtimedwait(&sig_set, 0, &zerotime);
sigtimedwait(&sig_set, NULL, &zerotime);
#ifdef SDL_THREADS_DISABLED
sigprocmask(SIG_SETMASK, &old_sig_set, NULL);

View file

@ -162,9 +162,6 @@ static void Wayland_DeleteDevice(SDL_VideoDevice *device)
WAYLAND_wl_display_flush(data->display);
WAYLAND_wl_display_disconnect(data->display);
}
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
}
SDL_free(data);
SDL_free(device);
SDL_WAYLAND_UnloadSymbols();
@ -233,7 +230,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
}
device->driverdata = data;
device->wakeup_lock = SDL_CreateMutex();
/* Set the function pointers */
device->VideoInit = Wayland_VideoInit;

View file

@ -93,9 +93,6 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device)
SDL_UnloadObject(data->shcoreDLL);
}
#endif
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
}
SDL_free(device->driverdata);
SDL_free(device);
}
@ -120,7 +117,6 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
return NULL;
}
device->driverdata = data;
device->wakeup_lock = SDL_CreateMutex();
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
data->userDLL = SDL_LoadObject("USER32.DLL");

View file

@ -108,9 +108,6 @@ static void X11_DeleteDevice(SDL_VideoDevice *device)
X11_XCloseDisplay(data->request_display);
}
SDL_free(data->windowlist);
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
}
SDL_free(device->driverdata);
SDL_free(device);
@ -204,8 +201,6 @@ static SDL_VideoDevice *X11_CreateDevice(void)
return NULL;
}
device->wakeup_lock = SDL_CreateMutex();
#ifdef X11_DEBUG
X11_XSynchronize(data->display, True);
#endif