Compare commits

...

10 Commits

Author SHA1 Message Date
Colin Sames
f4255e15bb add SDL3 repository to game engine
Some checks failed
Build (All) / Create test plan (push) Has been cancelled
Build (All) / level1 (push) Has been cancelled
Build (All) / level2 (push) Has been cancelled
2026-04-03 16:14:58 +02:00
nilFinx
f3a3b4b95a haiku: Always assume that the URL is encoded (required on nightly) (#15305) 2026-04-03 00:01:21 -07:00
Cameron Gutman
1674a04b01 kmsdrm: Add missing KMSDRM_FBFromBO() failure check 2026-04-02 22:02:18 -05:00
Christian Semmler
be8643f739 emscripten: Fix navigator.getGamepads crash in worker threads
The three EM_JS functions (SDL_GetEmscriptenJoystickVendor,
SDL_GetEmscriptenJoystickProduct, SDL_IsEmscriptenJoystickXInput)
call navigator.getGamepads() which is only available on the main
browser thread. With PROXY_TO_PTHREAD, the joystick callbacks are
dispatched to a worker where the Gamepad API is not available,
causing a TypeError.

Convert these from EM_JS to static functions using
MAIN_THREAD_EM_ASM_INT, which proxies the JavaScript execution to
the main browser thread. This matches the pattern already used by
other navigator.getGamepads() calls in the same file.
2026-04-02 19:36:01 -07:00
Cameron Gutman
3c11b43e59 kmsdrm: Initialize kms_in_fence_fd to -1
Prior to this fix, we closed stdin on the first call to drm_atomic_commit().
2026-04-02 20:46:53 -05:00
Ryan C. Gordon
f423a2ae34 kmsdrm: Disable atomic mouse code for now.
The rest of the atomic codepath is still enabled and usable.

This fixes missing and weird mouse cursors. We'll debug this code later on.

Reference Issue #15242.
2026-04-02 20:41:26 -04:00
Sanjay Govind
c58a61fdd4 Update to GameInput V3 (#15302) 2026-04-02 17:10:42 -07:00
Sam Lantinga
e21f7d77f3 Fixed unaligned 16-bit memory access
The previous code technically works on platforms with SSE2, but this fixes an ubsan warning.
2026-04-02 14:08:20 -07:00
Anonymous Maarten
03f74f3ad3 testyuv: make test params static const 2026-04-02 21:25:41 +02:00
Anonymous Maarten
b77fdcc638 Disable UB sanitizer in signed shift test 2026-04-02 21:25:41 +02:00
2038 changed files with 949261 additions and 949208 deletions

View File

@@ -31,7 +31,9 @@
#define GAMEINPUT_API_VERSION 0
#endif
#if GAMEINPUT_API_VERSION == 2
#if GAMEINPUT_API_VERSION == 3
using namespace GameInput::v3;
#elif GAMEINPUT_API_VERSION == 2
using namespace GameInput::v2;
#elif GAMEINPUT_API_VERSION == 1
using namespace GameInput::v1;

View File

@@ -0,0 +1,2 @@
PlatformToolSet=v143:VCToolArchitecture=Native32Bit:VCToolsVersion=14.44.35207:TargetPlatformVersion=10.0.26100.0:VcpkgTriplet=x86-windows:
Debug|Win32|C:\Users\Colin\source\repos\cross-compilation-cmake\external\SDL\src\hidapi\windows\|

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
PlatformToolSet=v143:VCToolArchitecture=Native32Bit:VCToolsVersion=14.44.35207:TargetPlatformVersion=10.0.26100.0:VcpkgTriplet=x86-windows:
Debug|Win32|C:\Users\Colin\source\repos\cross-compilation-cmake\external\SDL\src\hidapi\windows\|

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -35,9 +35,11 @@ static SDL_joylist_item *SDL_joylist = NULL;
static SDL_joylist_item *SDL_joylist_tail = NULL;
static int numjoysticks = 0;
EM_JS(int, SDL_GetEmscriptenJoystickVendor, (int device_index), {
static int SDL_GetEmscriptenJoystickVendor(int device_index)
{
// Let's assume that if we're calling these function then the gamepad object definitely exists
let gamepad = navigator['getGamepads']()[device_index];
return MAIN_THREAD_EM_ASM_INT({
let gamepad = navigator['getGamepads']()[$0];
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
let vendor_str = 'Vendor: ';
@@ -53,10 +55,13 @@ EM_JS(int, SDL_GetEmscriptenJoystickVendor, (int device_index), {
}
return 0;
});
}, device_index);
}
EM_JS(int, SDL_GetEmscriptenJoystickProduct, (int device_index), {
let gamepad = navigator['getGamepads']()[device_index];
static int SDL_GetEmscriptenJoystickProduct(int device_index)
{
return MAIN_THREAD_EM_ASM_INT({
let gamepad = navigator['getGamepads']()[$0];
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
let product_str = 'Product: ';
@@ -72,16 +77,20 @@ EM_JS(int, SDL_GetEmscriptenJoystickProduct, (int device_index), {
}
return 0;
});
}, device_index);
}
EM_JS(int, SDL_IsEmscriptenJoystickXInput, (int device_index), {
let gamepad = navigator['getGamepads']()[device_index];
static int SDL_IsEmscriptenJoystickXInput(int device_index)
{
return MAIN_THREAD_EM_ASM_INT({
let gamepad = navigator['getGamepads']()[$0];
// Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD)
// Firefox: xinput
// TODO: Safari
return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0;
});
}, device_index);
}
static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
{

View File

@@ -542,9 +542,15 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
}
#endif // GAMEINPUT_API_VERSION >= 1
} else {
#if GAMEINPUT_API_VERSION >= 3
joystick->naxes = info->controllerInfo->controllerAxisCount;
joystick->nbuttons = info->controllerInfo->controllerButtonCount;
joystick->nhats = info->controllerInfo->controllerSwitchCount;
#else
joystick->naxes = info->controllerAxisCount;
joystick->nbuttons = info->controllerButtonCount;
joystick->nhats = info->controllerSwitchCount;
#endif // GAMEINPUT_API_VERSION >= 3
}
if (info->supportedRumbleMotors & (GameInputRumbleLowFrequency | GameInputRumbleHighFrequency)) {
@@ -676,13 +682,13 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
#undef CONVERT_TRIGGER
}
} else {
bool *button_state = SDL_stack_alloc(bool, info->controllerButtonCount);
float *axis_state = SDL_stack_alloc(float, info->controllerAxisCount);
GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, info->controllerSwitchCount);
bool *button_state = SDL_stack_alloc(bool, joystick->nbuttons);
float *axis_state = SDL_stack_alloc(float, joystick->naxes);
GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, joystick->nhats);
if (button_state) {
uint32_t i;
uint32_t button_count = reading->GetControllerButtonState(info->controllerButtonCount, button_state);
uint32_t button_count = reading->GetControllerButtonState(joystick->nbuttons, button_state);
for (i = 0; i < button_count; ++i) {
SDL_SendJoystickButton(timestamp, joystick, (Uint8)i, button_state[i]);
}
@@ -692,7 +698,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
#define CONVERT_AXIS(v) (Sint16)((v)*65535.0f - 32768.0f)
if (axis_state) {
uint32_t i;
uint32_t axis_count = reading->GetControllerAxisState(info->controllerAxisCount, axis_state);
uint32_t axis_count = reading->GetControllerAxisState(joystick->naxes, axis_state);
for (i = 0; i < axis_count; ++i) {
SDL_SendJoystickAxis(timestamp, joystick, (Uint8)i, CONVERT_AXIS(axis_state[i]));
}
@@ -702,7 +708,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
if (switch_state) {
uint32_t i;
uint32_t switch_count = reading->GetControllerSwitchState(info->controllerSwitchCount, switch_state);
uint32_t switch_count = reading->GetControllerSwitchState(joystick->nhats, switch_state);
for (i = 0; i < switch_count; ++i) {
Uint8 hat;
switch (switch_state[i]) {

View File

@@ -25,7 +25,11 @@
bool SDL_SYS_OpenURL(const char *url)
{
#if B_BEOS_VERSION <= B_HAIKU_VERSION_1_BETA_5
BUrl burl(url);
#else
BUrl burl(url, true);
#endif
const status_t rc = burl.OpenWithPreferredApplication(false);
if (rc != B_NO_ERROR) {
return SDL_SetError("URL open failed (err=%d)", (int)rc);

View File

@@ -1499,8 +1499,17 @@ static bool SDL_TARGETING("sse2") SDL_ConvertPixels_SwapNV_SSE2(int width, int h
dstUV += 8;
x -= 8;
}
if (x > 0) {
const Uint8 *srcUV8 = (const Uint8 *)srcUV;
Uint8 *dstUV8 = (Uint8 *)dstUV;
srcUV += x;
dstUV += x;
while (x--) {
*dstUV++ = SDL_Swap16(*srcUV++);
Uint8 u = *srcUV8++;
Uint8 v = *srcUV8++;
*dstUV8++ = v;
*dstUV8++ = u;
}
}
srcUV += srcUVPitchLeft;
dstUV += dstUVPitchLeft;

View File

@@ -316,7 +316,11 @@ void HAIKU_VideoQuit(SDL_VideoDevice *_this)
extern "C"
bool HAIKU_OpenURL(const char *url)
{
#if B_HAIKU_VERSION <= B_HAIKU_VERSION_1_BETA_5
BUrl burl(url);
#else
BUrl burl(url, true);
#endif
const status_t rc = burl.OpenWithPreferredApplication(false);
if (rc != B_NO_ERROR) {
return SDL_SetError("URL open failed (err=%d)", (int)rc);

View File

@@ -32,6 +32,9 @@
#include "../SDL_pixels_c.h"
// !!! FIXME: atomic cursors are broken right now.
#define USE_ATOMIC_CURSOR 0
static SDL_Cursor *KMSDRM_CreateDefaultCursor(void);
static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y);
static bool KMSDRM_ShowCursor(SDL_Cursor *cursor);
@@ -40,10 +43,10 @@ static void KMSDRM_FreeCursor(SDL_Cursor *cursor);
/**************************************************************************************/
// BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS.
// How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have
// How does SDL manage cursors internally? First, mouse != cursor. The mouse can have
// many cursors in mouse->cursors.
// -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many
// cursosr with this, not only one.
// cursors with this, not only one.
// -SDL stores those cursors in a cursors array, in mouse->cursors.
// -Whenever it wants (or the programmer wants) takes a cursor from that array
// and shows it on screen with KMSDRM_ShowCursor().
@@ -68,7 +71,7 @@ void KMSDRM_DestroyCursorBO(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
// Destroy the curso GBM BO.
if (dispdata->cursor_bo) {
SDL_VideoData *viddata = (SDL_VideoData *) _this->internal;
if (viddata->is_atomic) {
if (USE_ATOMIC_CURSOR && viddata->is_atomic) {
if (dispdata->cursor_plane) {
// Unset the the cursor BO from the cursor plane.
KMSDRM_PlaneInfo info;
@@ -99,7 +102,7 @@ bool KMSDRM_CreateCursorBO(SDL_VideoDisplay *display)
SDL_VideoData *viddata = dev->internal;
SDL_DisplayData *dispdata = display->internal;
if (viddata->is_atomic) {
if (USE_ATOMIC_CURSOR && viddata->is_atomic) {
setup_plane(dev, dispdata, &dispdata->cursor_plane, DRM_PLANE_TYPE_CURSOR);
}
@@ -141,7 +144,7 @@ static bool KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
SDL_VideoData *viddata = video_device->internal;
if (viddata->is_atomic) {
if (USE_ATOMIC_CURSOR && viddata->is_atomic) {
if (dispdata->cursor_plane) {
KMSDRM_PlaneInfo info;
SDL_zero(info);
@@ -207,11 +210,16 @@ static bool KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Mouse *mouse, S
goto cleanup;
}
if (viddata->is_atomic) {
if (USE_ATOMIC_CURSOR && viddata->is_atomic) {
// Get the fb_id for the GBM BO so we can show it on the cursor plane.
KMSDRM_FBInfo *fb = KMSDRM_FBFromBO(video_device, dispdata->cursor_bo);
KMSDRM_PlaneInfo info;
if (!fb) {
result = SDL_SetError("Failed to get cursor FB from BO");
goto cleanup;
}
// Show the GBM BO buffer on the cursor plane.
SDL_zero(info);
info.plane = dispdata->cursor_plane;
@@ -400,7 +408,7 @@ static bool KMSDRM_WarpMouseGlobal(float x, float y)
if (dispdata->cursor_bo) {
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_VideoData *viddata = dev->internal;
if (viddata->is_atomic) {
if (USE_ATOMIC_CURSOR && viddata->is_atomic) {
const SDL_CursorData *curdata = (const SDL_CursorData *) mouse->cur_cursor->internal;
drm_atomic_movecursor(dispdata, curdata, (uint16_t) (int) x, (uint16_t) (int) y);
} else {
@@ -467,7 +475,7 @@ static bool KMSDRM_MoveCursor(SDL_Cursor *cursor)
return SDL_SetError("Cursor not initialized properly.");
}
if (viddata->is_atomic) {
if (USE_ATOMIC_CURSOR && viddata->is_atomic) {
/* !!! FIXME: Some programs expect cursor movement even while they don't do SwapWindow() calls,
and since we ride on the atomic_commit() in SwapWindow() for cursor movement,
cursor won't move in these situations. We could do an atomic_commit() here

View File

@@ -1125,6 +1125,7 @@ static void KMSDRM_AddDisplay(SDL_VideoDevice *_this, drmModeConnector *conn, dr
to sane values. */
dispdata->cursor_bo = NULL;
dispdata->cursor_bo_drm_fd = -1;
dispdata->kms_in_fence_fd = -1;
dispdata->kms_out_fence_fd = -1;
/* Since we create and show the default cursor on KMSDRM_InitMouse(),

View File

@@ -208,6 +208,9 @@ static int TST_uallrem(void *a, void *b, int arg, void *result, void *expected)
return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
}
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__ICC)
static int TST_allshl(void *a, void *b, int arg, void *result, void *expected) __attribute__ ((no_sanitize("undefined")));
#endif
static int TST_allshl(void *a, void *b, int arg, void *result, void *expected)
{
(*(long long *)result) = (*(long long *)a) << arg;

View File

@@ -766,7 +766,7 @@ done:
int main(int argc, char **argv)
{
struct
static const struct
{
bool enable_intrinsics;
int pattern_size;