Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 32;
private static final int SDL_MICRO_VERSION = 0;
private static final int SDL_MICRO_VERSION = 2;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
Expand Down
2 changes: 1 addition & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ pub fn build(b: *std.Build) void {
.style = .{ .cmake = b.path("include/SDL_revision.h.cmake") },
.include_path = "SDL_revision.h",
}, .{
.SDL_REVISION = "SDL-2.32.0",
.SDL_REVISION = "SDL-2.32.2",
.SDL_VENDOR_INFO = "allyourcodebase.com",
});
lib.addConfigHeader(revision_header);
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.{
.name = "SDL",
.version = "2.32.0",
.version = "2.32.2",
.minimum_zig_version = "0.13.0",
.dependencies = .{},
.paths = .{
Expand Down
21 changes: 21 additions & 0 deletions include/SDL_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,27 @@ extern "C" {
*/
#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE"


/**
* A variable containing a list of devices and their desired number of haptic
* (force feedback) enabled axis.
*
* The format of the string is a comma separated list of USB VID/PID pairs in
* hexadecimal form plus the number of desired axes, e.g.
*
* `0xAAAA/0xBBBB/1,0xCCCC/0xDDDD/3`
*
* This hint supports a "wildcard" device that will set the number of haptic
* axes on all initialized haptic devices which were not defined explicitly in
* this hint.
*
* `0xFFFF/0xFFFF/1`
*
* This hint should be set before a controller is opened. The number of haptic
* axes won't exceed the number of real axes found on the device.
*/
#define SDL_HINT_JOYSTICK_HAPTIC_AXES "SDL_JOYSTICK_HAPTIC_AXES"

/**
* A variable controlling whether joysticks on Linux will always treat 'hat'
* axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking
Expand Down
2 changes: 1 addition & 1 deletion include/SDL_keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name);
* On some platforms using this function activates the screen keyboard.
*
* On desktop platforms, SDL_StartTextInput() is implicitly called on SDL
* window creation which will cause events SDL_TextInputEvent and
* video subsystem initialization which will cause SDL_TextInputEvent and
* SDL_TextEditingEvent to begin emitting.
*
* \since This function is available since SDL 2.0.0.
Expand Down
2 changes: 1 addition & 1 deletion include/SDL_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ typedef struct SDL_version
*/
#define SDL_MAJOR_VERSION 2
#define SDL_MINOR_VERSION 32
#define SDL_PATCHLEVEL 0
#define SDL_PATCHLEVEL 2

/**
* Macro to determine SDL version program was compiled against.
Expand Down
8 changes: 4 additions & 4 deletions src/audio/emscripten/SDL_emscriptenaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; }
audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0);
SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
dynCall('vi', $2, [$3]);
dynCall('vp', $2, [$3]);
};
SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
Expand All @@ -326,7 +326,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0);
var silence_callback = function() {
SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
dynCall('vi', $2, [$3]);
dynCall('vp', $2, [$3]);
};

SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
Expand All @@ -351,7 +351,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
SDL2.audio.silenceBuffer = undefined;
}
SDL2.audio.currentOutputBuffer = e['outputBuffer'];
dynCall('vi', $2, [$3]);
dynCall('vp', $2, [$3]);
};

SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);
Expand All @@ -369,7 +369,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
// the buffer that gets filled here just gets ignored, so the app can make progress
// and/or avoid flooding audio queues until we can actually play audio.
SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer;
dynCall('vi', $2, [$3]);
dynCall('vp', $2, [$3]);
SDL2.audio.currentOutputBuffer = undefined;
};

Expand Down
16 changes: 8 additions & 8 deletions src/audio/pulseaudio/SDL_pulseaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ static void PULSEAUDIO_FlushCapture(_THIS)
{
struct SDL_PrivateAudioData *h = this->hidden;
const void *data = NULL;
size_t nbytes = 0;
size_t nbytes = 0, buflen = 0;

PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);

Expand All @@ -507,19 +507,19 @@ static void PULSEAUDIO_FlushCapture(_THIS)
h->capturelen = 0;
}

while (SDL_AtomicGet(&this->enabled) && (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0)) {
buflen = PULSEAUDIO_pa_stream_readable_size(h->stream);
while (SDL_AtomicGet(&this->enabled) && (buflen > 0)) {
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
/*printf("PULSEAUDIO DEVICE FAILURE IN FLUSHCAPTURE!\n");*/
SDL_OpenedAudioDeviceDisconnected(this);
break;
}

if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) {
/* a new fragment is available! Just dump it. */
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
}
/* a fragment of audio present before FlushCapture was call is
available! Just drop it. */
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
PULSEAUDIO_pa_stream_drop(h->stream);
buflen -= nbytes;
}

PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
Expand Down
11 changes: 8 additions & 3 deletions src/dynapi/SDL_dynapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,19 +440,24 @@ extern SDL_NORETURN void SDL_ExitProcess(int exitcode);

static void SDL_InitDynamicAPILocked(void)
{
SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
SDL_bool use_internal = SDL_TRUE;

/* this can't use SDL_getenv_REAL, because it might allocate memory before the app can set their allocator */
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
/* We've always used LoadLibraryA for this, so this has never worked with Unicode paths on Windows. Sorry. */
char envbuf[512]; /* overflows will just report as environment variable being unset, but LoadLibraryA has a MAX_PATH of 260 anyhow, apparently. */
const DWORD rc = GetEnvironmentVariableA(SDL_DYNAMIC_API_ENVVAR, envbuf, (DWORD) sizeof (envbuf));
char *libname = ((rc != 0) && (rc < sizeof (envbuf))) ? envbuf : NULL;
#elif defined(__OS2__)
char * libname;
if (DosScanEnv(SDL_DYNAMIC_API_ENVVAR, &libname) != NO_ERROR) {
libname = NULL;
}
#else
char *libname = getenv(SDL_DYNAMIC_API_ENVVAR);
#endif

SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
SDL_bool use_internal = SDL_TRUE;

if (libname) {
while (*libname && !entry) {
char *ptr = libname;
Expand Down
93 changes: 93 additions & 0 deletions src/haptic/SDL_haptic.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,85 @@
#include "SDL_syshaptic.h"
#include "SDL_haptic_c.h"
#include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */
#include "SDL_hints.h"
#include "../SDL_hints_c.h"

typedef struct SDL_Haptic_VIDPID_Naxes {
Uint16 vid;
Uint16 pid;
Uint16 naxes;
} SDL_Haptic_VIDPID_Naxes;

static void SDL_HapticLoadAxesList(SDL_Haptic_VIDPID_Naxes **entries, int *num_entries)
{
SDL_Haptic_VIDPID_Naxes entry;
const char *spot;
int length = 0;

spot = SDL_GetHint(SDL_HINT_JOYSTICK_HAPTIC_AXES);
if (!spot)
return;

while (SDL_sscanf(spot, "0x%hx/0x%hx/%hu%n", &entry.vid, &entry.pid, &entry.naxes, &length) == 3) {
SDL_assert(length > 0);
spot += length;
length = 0;

if ((*num_entries % 8) == 0) {
int new_max = *num_entries + 8;
SDL_Haptic_VIDPID_Naxes *new_entries =
(SDL_Haptic_VIDPID_Naxes *)SDL_realloc(*entries, new_max * sizeof(**entries));

// Out of memory, go with what we have already
if (!new_entries)
break;

*entries = new_entries;
}
(*entries)[(*num_entries)++] = entry;

if (spot[0] == ',')
spot++;
}
}

// /* Return -1 if not found */
static int SDL_HapticNaxesListIndex(struct SDL_Haptic_VIDPID_Naxes *entries, int num_entries, Uint16 vid, Uint16 pid)
{
int i;
if (!entries)
return -1;

for (i = 0; i < num_entries; ++i) {
if (entries[i].vid == vid && entries[i].pid == pid)
return i;
}

return -1;
}

// Check if device needs a custom number of naxes
static int SDL_HapticGetNaxes(Uint16 vid, Uint16 pid)
{
int num_entries = 0, index = 0, naxes = -1;
SDL_Haptic_VIDPID_Naxes *naxes_list = NULL;

SDL_HapticLoadAxesList(&naxes_list, &num_entries);
if (!num_entries || !naxes_list)
return -1;

// Perform "wildcard" pass
index = SDL_HapticNaxesListIndex(naxes_list, num_entries, 0xffff, 0xffff);
if (index >= 0)
naxes = naxes_list[index].naxes;

index = SDL_HapticNaxesListIndex(naxes_list, num_entries, vid, pid);
if (index >= 0)
naxes = naxes_list[index].naxes;

SDL_free(naxes_list);
return naxes;
}

/* Global for SDL_windowshaptic.c */
#if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT)
Expand Down Expand Up @@ -258,6 +337,8 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
{
SDL_Haptic *haptic;
SDL_Haptic *hapticlist;
int naxes, general_axes;
Uint16 vid, pid;

/* Make sure there is room. */
if (SDL_NumHaptics() <= 0) {
Expand Down Expand Up @@ -314,6 +395,18 @@ SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
}
SDL_UnlockJoysticks();

vid = SDL_JoystickGetVendor(joystick);
pid = SDL_JoystickGetProduct(joystick);
general_axes = SDL_JoystickNumAxes(joystick);

naxes = SDL_HapticGetNaxes(vid, pid);
if (naxes > 0)
haptic->naxes = naxes;

// Limit to the actual number of axes found on the device
if (general_axes >= 0 && naxes > general_axes)
haptic->naxes = general_axes;

/* Add haptic to list */
++haptic->ref_count;
/* Link the haptic in the list */
Expand Down
2 changes: 1 addition & 1 deletion src/hidapi/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ case $host in
backend="mac"
os="darwin"
threads="pthreads"
LIBS="${LIBS} -framework IOKit -framework CoreFoundation"
LIBS="${LIBS} -framework IOKit -framework CoreFoundation -framework AppKit"
;;
*-freebsd*)
AC_MSG_RESULT([ (FreeBSD back-end)])
Expand Down
2 changes: 1 addition & 1 deletion src/hidapi/mac/Makefile-manual
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ COBJS=hid.o
CPPOBJS=../hidtest/hidtest.o
OBJS=$(COBJS) $(CPPOBJS)
CFLAGS+=-I../hidapi -Wall -g -c
LIBS=-framework IOKit -framework CoreFoundation
LIBS=-framework IOKit -framework CoreFoundation -framework AppKit


hidtest: $(OBJS)
Expand Down
21 changes: 17 additions & 4 deletions src/hidapi/mac/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@

#define VALVE_USB_VID 0x28DE

/* As defined in AppKit.h, but we don't need the entire AppKit for a single constant. */
extern const double NSAppKitVersionNumber;

/* Barrier implementation because Mac OSX doesn't have pthread_barrier.
It also doesn't have clock_gettime(). So much for POSIX and SUSv2.
This implementation came from Brent Priddy and was posted on
Expand Down Expand Up @@ -131,6 +134,7 @@ struct hid_device_list_node
};

static IOHIDManagerRef hid_mgr = 0x0;
static int is_macos_10_10_or_greater = 0;
static struct hid_device_list_node *device_list = 0x0;

static hid_device *new_hid_device(void)
Expand Down Expand Up @@ -485,6 +489,7 @@ static int init_hid_manager(void)
int HID_API_EXPORT hid_init(void)
{
if (!hid_mgr) {
is_macos_10_10_or_greater = (NSAppKitVersionNumber >= 1343); /* NSAppKitVersionNumber10_10 */
return init_hid_manager();
}

Expand Down Expand Up @@ -1138,8 +1143,10 @@ void HID_API_EXPORT hid_close(hid_device *dev)
if (!dev)
return;

/* Disconnect the report callback before close. */
if (!dev->disconnected) {
/* Disconnect the report callback before close.
See comment below.
*/
if (is_macos_10_10_or_greater || !dev->disconnected) {
IOHIDDeviceRegisterInputReportCallback(
dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
NULL, dev);
Expand All @@ -1162,8 +1169,14 @@ void HID_API_EXPORT hid_close(hid_device *dev)

/* Close the OS handle to the device, but only if it's not
been unplugged. If it's been unplugged, then calling
IOHIDDeviceClose() will crash. */
if (!dev->disconnected) {
IOHIDDeviceClose() will crash.

UPD: The crash part was true in/until some version of macOS.
Starting with macOS 10.15, there is an opposite effect in some environments:
crash happenes if IOHIDDeviceClose() is not called.
Not leaking a resource in all tested environments.
*/
if (is_macos_10_10_or_greater || !dev->disconnected) {
IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/windows/version.rc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,32,0,0
PRODUCTVERSION 2,32,0,0
FILEVERSION 2,32,2,0
PRODUCTVERSION 2,32,2,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
Expand All @@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "2, 32, 0, 0\0"
VALUE "FileVersion", "2, 32, 2, 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, 0, 0\0"
VALUE "ProductVersion", "2, 32, 2, 0\0"
END
END
BLOCK "VarFileInfo"
Expand Down
Loading
Loading