update SDL3 to 3.2.0

This commit is contained in:
Sasha Szpakowski
2025-01-24 21:20:11 -04:00
parent f27a1c24b3
commit 3582488fbc
1209 changed files with 26017 additions and 18421 deletions
+55 -47
View File
@@ -102,7 +102,7 @@ define_property(TARGET PROPERTY SDL_NONINTERACTIVE_ARGUMENTS BRIEF_DOCS "Argumen
define_property(TARGET PROPERTY SDL_NONINTERACTIVE_TIMEOUT BRIEF_DOCS "Timeout for noninteractive executable." FULL_DOCS "Timeout for noninteractive executable.")
macro(add_sdl_test_executable TARGET)
cmake_parse_arguments(AST "BUILD_DEPENDENT;NONINTERACTIVE;NEEDS_RESOURCES;TESTUTILS;THREADS;NO_C90;MAIN_CALLBACKS;NOTRACKMEM" "" "DISABLE_THREADS_ARGS;NONINTERACTIVE_TIMEOUT;NONINTERACTIVE_ARGS;INSTALLED_ARGS;SOURCES" ${ARGN})
cmake_parse_arguments(AST "BUILD_DEPENDENT;NONINTERACTIVE;NEEDS_RESOURCES;TESTUTILS;THREADS;NO_C90;MAIN_CALLBACKS;NOTRACKMEM" "" "DEPENDS;DISABLE_THREADS_ARGS;NONINTERACTIVE_TIMEOUT;NONINTERACTIVE_ARGS;INSTALLED_ARGS;SOURCES" ${ARGN})
if(AST_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}")
endif()
@@ -121,6 +121,7 @@ macro(add_sdl_test_executable TARGET)
else()
add_executable(${TARGET} ${AST_SOURCES} ${EXTRA_SOURCES})
endif()
target_compile_definitions(${TARGET} PRIVATE HAVE_BUILD_CONFIG)
SDL_AddCommonCompilerFlags(${TARGET})
target_include_directories(${TARGET} PRIVATE "${SDL3_SOURCE_DIR}/src/video/khronos")
target_link_libraries(${TARGET} PRIVATE SDL3::SDL3_test SDL3::${sdl_name_component})
@@ -128,6 +129,9 @@ macro(add_sdl_test_executable TARGET)
set_property(TARGET ${TARGET} PROPERTY C_STANDARD 90)
set_property(TARGET ${TARGET} PROPERTY C_EXTENSIONS FALSE)
endif()
if(AST_DEPENDS)
add_dependencies(${TARGET} ${AST_DEPENDS})
endif()
list(APPEND SDL_TEST_EXECUTABLES ${TARGET})
set_property(TARGET ${TARGET} PROPERTY SDL_NOTRACKMEM ${AST_NOTRACKMEM})
@@ -208,6 +212,50 @@ if(HAVE_LIBUDEV_H)
add_definitions(-DHAVE_LIBUDEV_H)
endif()
function(files2headers OUTPUT)
set(xxd "${SDL3_SOURCE_DIR}/cmake/xxd.py")
set(inputs ${ARGN})
set(outputs )
foreach(input IN LISTS inputs)
get_filename_component(file_we "${input}" NAME_WE)
set(intermediate "${CMAKE_CURRENT_BINARY_DIR}/${file_we}.h")
set(output "${CMAKE_CURRENT_SOURCE_DIR}/${file_we}.h")
list(APPEND outputs "${output}")
if(TARGET Python3::Interpreter AND NOT CMAKE_CROSSCOMPILING)
list(APPEND outputs "${intermediate}")
# Don't add the 'output' header to the output, to avoid marking them as GENERATED
# (generated files are removed when running the CLEAN target)
add_custom_command(OUTPUT "${intermediate}"
COMMAND Python3::Interpreter "${xxd}" -i "${CMAKE_CURRENT_SOURCE_DIR}/${input}" "-o" "${intermediate}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${intermediate}" "${output}"
DEPENDS "${xxd}" "${bmp}"
)
endif()
endforeach()
set(${OUTPUT} "${outputs}" PARENT_SCOPE)
add_custom_target(generate-${OUTPUT} DEPENDS ${outputs})
endfunction()
files2headers(gamepad_image_headers
gamepad_axis_arrow.bmp
gamepad_axis.bmp
gamepad_back.bmp
gamepad_battery.bmp
gamepad_battery_wired.bmp
gamepad_button_background.bmp
gamepad_button.bmp
gamepad_button_small.bmp
gamepad_face_abxy.bmp
gamepad_face_bayx.bmp
gamepad_face_sony.bmp
gamepad_front.bmp
gamepad_touchpad.bmp
gamepad_wired.bmp
gamepad_wireless.bmp
)
files2headers(icon_bmp_header icon.bmp)
files2headers(glass_bmp_header glass.bmp)
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
include("${CMAKE_CURRENT_LIST_DIR}/../cmake/FindFFmpeg.cmake")
if(FFmpeg_FOUND)
@@ -219,7 +267,7 @@ if(FFmpeg_FOUND)
cmake_pop_check_state()
endif()
if(FFmpeg_FOUND AND LIBAVUTIL_AVFRAME_HAS_CH_LAYOUT)
add_sdl_test_executable(testffmpeg NO_C90 SOURCES testffmpeg.c testffmpeg_vulkan.c ${icon_bmp_header})
add_sdl_test_executable(testffmpeg NO_C90 SOURCES testffmpeg.c testffmpeg_vulkan.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
if(LIBAVUTIL_AVFULKANFRAMESCONTEXT_HAS_FORMAT)
target_compile_definitions(testffmpeg PRIVATE FFMPEG_VULKAN_SUPPORT)
endif()
@@ -290,52 +338,11 @@ elseif(HAVE_X11 OR HAVE_WAYLAND)
endif ()
endif()
function(files2headers OUTPUT)
set(xxd "${SDL3_SOURCE_DIR}/cmake/xxd.py")
set(inputs ${ARGN})
set(outputs )
foreach(input IN LISTS inputs)
get_filename_component(file_we "${input}" NAME_WE)
set(intermediate "${CMAKE_CURRENT_BINARY_DIR}/${file_we}.h")
set(output "${CMAKE_CURRENT_SOURCE_DIR}/${file_we}.h")
list(APPEND outputs "${output}")
if(TARGET Python3::Interpreter AND NOT CMAKE_CROSSCOMPILING)
list(APPEND outputs "${intermediate}")
# Don't add the 'output' header to the output, to avoid marking them as GENERATED
# (generated files are removed when running the CLEAN target)
add_custom_command(OUTPUT "${intermediate}"
COMMAND Python3::Interpreter "${xxd}" -i "${CMAKE_CURRENT_SOURCE_DIR}/${input}" "-o" "${intermediate}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${intermediate}" "${output}"
DEPENDS "${xxd}" "${bmp}"
)
endif()
endforeach()
set(${OUTPUT} "${outputs}" PARENT_SCOPE)
endfunction()
files2headers(gamepad_image_headers
gamepad_axis_arrow.bmp
gamepad_axis.bmp
gamepad_back.bmp
gamepad_battery.bmp
gamepad_battery_wired.bmp
gamepad_button_background.bmp
gamepad_button.bmp
gamepad_button_small.bmp
gamepad_face_abxy.bmp
gamepad_face_bayx.bmp
gamepad_face_sony.bmp
gamepad_front.bmp
gamepad_touchpad.bmp
)
files2headers(icon_bmp_header icon.bmp)
files2headers(glass_bmp_header glass.bmp)
add_sdl_test_executable(testasyncio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testasyncio.c)
add_sdl_test_executable(testaudio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testaudio.c)
add_sdl_test_executable(testcolorspace SOURCES testcolorspace.c)
add_sdl_test_executable(testfile NONINTERACTIVE SOURCES testfile.c)
add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers})
add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers} DEPENDS generate-gamepad_image_headers)
add_sdl_test_executable(testgeometry TESTUTILS SOURCES testgeometry.c)
add_sdl_test_executable(testgl SOURCES testgl.c)
add_sdl_test_executable(testgles SOURCES testgles.c)
@@ -381,15 +388,16 @@ add_sdl_test_executable(testshader NEEDS_RESOURCES TESTUTILS SOURCES testshader.
if(EMSCRIPTEN)
target_link_options(testshader PRIVATE "-sLEGACY_GL_EMULATION")
endif()
add_sdl_test_executable(testshape NEEDS_RESOURCES SOURCES testshape.c ${glass_bmp_header})
add_sdl_test_executable(testshape NEEDS_RESOURCES SOURCES testshape.c ${glass_bmp_header} DEPENDS generate-glass_bmp_header)
add_sdl_test_executable(testsprite MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c)
add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_bmp_header})
add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_bmp_header})
add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
add_sdl_test_executable(testspritesurface SOURCES testspritesurface.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
add_sdl_test_executable(teststreaming NEEDS_RESOURCES TESTUTILS SOURCES teststreaming.c)
add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c)
add_sdl_test_executable(testurl SOURCES testurl.c)
add_sdl_test_executable(testver NONINTERACTIVE NOTRACKMEM SOURCES testver.c)
add_sdl_test_executable(testcamera MAIN_CALLBACKS SOURCES testcamera.c)
add_sdl_test_executable(testclipboard MAIN_CALLBACKS SOURCES testclipboard.c ${icon_bmp_header} DEPENDS generate-icon_bmp_header)
add_sdl_test_executable(testviewport NEEDS_RESOURCES TESTUTILS SOURCES testviewport.c)
add_sdl_test_executable(testwm SOURCES testwm.c)
add_sdl_test_executable(testyuv NONINTERACTIVE NONINTERACTIVE_ARGS "--automated" NEEDS_RESOURCES TESTUTILS SOURCES testyuv.c testyuv_cvt.c)
+1 -1
View File
@@ -3,7 +3,7 @@ following license, which is different (more permissive) than SDL's usual
license.
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+4 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -167,6 +167,9 @@ static void print_modifiers(char **text, size_t *maxlen, SDL_Keymod mod)
if (mod & SDL_KMOD_MODE) {
print_string(text, maxlen, " MODE");
}
if (mod & SDL_KMOD_LEVEL5) {
print_string(text, maxlen, " LEVEL5");
}
if (mod & SDL_KMOD_SCROLL) {
print_string(text, maxlen, " SCROLL");
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

+106
View File
@@ -0,0 +1,106 @@
unsigned char gamepad_wired_bmp[] = {
0x42, 0x4d, 0xca, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00,
0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x04,
0x00, 0x00, 0xd7, 0x0d, 0x00, 0x00, 0xd7, 0x0d, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x47,
0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00,
0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x5e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
0x00, 0xa9, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00,
0x00, 0xc5, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00,
0x00, 0xf3, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x71, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
0x00, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00,
0x00, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xe1, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1d, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x25, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00,
0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00,
0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x56, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00,
0x00, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00,
0x00, 0xed, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1a, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0x00, 0xed, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x8d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
0x00, 0xdf, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00,
0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00,
0x00, 0xf2, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00,
0x00, 0xed, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x5a, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x5b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00,
0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00,
0x00, 0x55, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
unsigned int gamepad_wired_bmp_len = 1226;
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+100
View File
@@ -0,0 +1,100 @@
unsigned char gamepad_wireless_bmp[] = {
0x42, 0x4d, 0x8a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00,
0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x23, 0x2e, 0x00, 0x00, 0x23, 0x2e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x47,
0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0a, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00,
0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
0x00, 0xea, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00,
0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xf5, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xf5, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00,
0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
0x00, 0x84, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00,
0x00, 0x9a, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x69, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7b, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00,
0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00,
0x00, 0xac, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00,
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00,
0x00, 0x99, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00,
0x00, 0x09, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00,
0x00, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00,
0x00, 0xe9, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xef, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
0x00, 0xf0, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00,
0x00, 0xf5, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00,
0x00, 0xf5, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x28, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xf3, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00,
0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00,
0x00, 0xac, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xcc, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x4a, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00,
0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
0x00, 0x34, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int gamepad_wireless_bmp_len = 1162;
+30 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -26,6 +26,8 @@
#include "gamepad_axis.h"
#include "gamepad_axis_arrow.h"
#include "gamepad_button_background.h"
#include "gamepad_wired.h"
#include "gamepad_wireless.h"
/* This is indexed by gamepad element */
@@ -95,6 +97,7 @@ struct GamepadImage
SDL_Texture *face_abxy_texture;
SDL_Texture *face_bayx_texture;
SDL_Texture *face_sony_texture;
SDL_Texture *connection_texture[2];
SDL_Texture *battery_texture[2];
SDL_Texture *touchpad_texture;
SDL_Texture *button_texture;
@@ -103,6 +106,8 @@ struct GamepadImage
float gamepad_height;
float face_width;
float face_height;
float connection_width;
float connection_height;
float battery_width;
float battery_height;
float touchpad_width;
@@ -121,6 +126,7 @@ struct GamepadImage
bool elements[SDL_GAMEPAD_ELEMENT_MAX];
SDL_JoystickConnectionState connection_state;
SDL_PowerState battery_state;
int battery_percent;
@@ -157,6 +163,10 @@ GamepadImage *CreateGamepadImage(SDL_Renderer *renderer)
ctx->face_sony_texture = CreateTexture(renderer, gamepad_face_sony_bmp, gamepad_face_sony_bmp_len);
SDL_GetTextureSize(ctx->face_abxy_texture, &ctx->face_width, &ctx->face_height);
ctx->connection_texture[0] = CreateTexture(renderer, gamepad_wired_bmp, gamepad_wired_bmp_len);
ctx->connection_texture[1] = CreateTexture(renderer, gamepad_wireless_bmp, gamepad_wireless_bmp_len);
SDL_GetTextureSize(ctx->connection_texture[0], &ctx->connection_width, &ctx->connection_height);
ctx->battery_texture[0] = CreateTexture(renderer, gamepad_battery_bmp, gamepad_battery_bmp_len);
ctx->battery_texture[1] = CreateTexture(renderer, gamepad_battery_wired_bmp, gamepad_battery_wired_bmp_len);
SDL_GetTextureSize(ctx->battery_texture[0], &ctx->battery_width, &ctx->battery_height);
@@ -463,6 +473,7 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad)
}
}
ctx->connection_state = SDL_GetGamepadConnectionState(gamepad);
ctx->battery_state = SDL_GetGamepadPowerInfo(gamepad, &ctx->battery_percent);
if (SDL_GetNumGamepadTouchpads(gamepad) > 0) {
@@ -565,6 +576,24 @@ void RenderGamepadImage(GamepadImage *ctx)
}
}
if (ctx->display_mode == CONTROLLER_MODE_TESTING) {
dst.x = ctx->x + ctx->gamepad_width - ctx->battery_width - 4 - ctx->connection_width;
dst.y = ctx->y;
dst.w = ctx->connection_width;
dst.h = ctx->connection_height;
switch (ctx->connection_state) {
case SDL_JOYSTICK_CONNECTION_WIRED:
SDL_RenderTexture(ctx->renderer, ctx->connection_texture[0], NULL, &dst);
break;
case SDL_JOYSTICK_CONNECTION_WIRELESS:
SDL_RenderTexture(ctx->renderer, ctx->connection_texture[1], NULL, &dst);
break;
default:
break;
}
}
if (ctx->display_mode == CONTROLLER_MODE_TESTING &&
ctx->battery_state != SDL_POWERSTATE_NO_BATTERY &&
ctx->battery_state != SDL_POWERSTATE_UNKNOWN) {
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+2 -2
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -139,7 +139,7 @@ static void async_io_task_complete(const SDL_AsyncIOOutcome *outcome)
#define RESCASE(x) case x: resultstr = #x; break
RESCASE(SDL_ASYNCIO_COMPLETE);
RESCASE(SDL_ASYNCIO_FAILURE);
RESCASE(SDL_ASYNCIO_CANCELLED);
RESCASE(SDL_ASYNCIO_CANCELED);
#undef RESCASE
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+2 -2
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -172,7 +172,7 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
SDL_AppResult SDL_AppIterate(void *appstate)
{
if (!SDL_AudioDevicePaused(SDL_GetAudioStreamDevice(stream_in))) {
if (!SDL_AudioStreamDevicePaused(stream_in)) {
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
} else {
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+11 -4
View File
@@ -108,6 +108,13 @@ static int SDLCALL clipboard_testClipboardDataFunctions(void *arg)
result == true,
"Validate SDL_ClearClipboardData result, expected true, got %i",
result);
expected_text = "";
text = SDL_GetClipboardText();
SDLTest_AssertCheck(
text && SDL_strcmp(text, expected_text) == 0,
"Verify clipboard text, expected \"%s\", got \"%s\"",
expected_text, text);
SDL_free(text);
/* Test clearing clipboard data when it's already clear */
last_clipboard_update_count = clipboard_update_count;
@@ -117,8 +124,8 @@ static int SDLCALL clipboard_testClipboardDataFunctions(void *arg)
"Validate SDL_ClearClipboardData result, expected true, got %i",
result);
SDLTest_AssertCheck(
clipboard_update_count == last_clipboard_update_count,
"Verify clipboard update unchanged, got %d",
clipboard_update_count != last_clipboard_update_count,
"Verify clipboard update count changed, got %d",
clipboard_update_count - last_clipboard_update_count);
/* Validate error handling */
@@ -430,8 +437,8 @@ static int SDLCALL clipboard_testClipboardTextFunctions(void *arg)
"Verify SDL_HasClipboardText returned false, got %s",
(boolResult) ? "true" : "false");
SDLTest_AssertCheck(
clipboard_update_count == last_clipboard_update_count,
"Verify clipboard update unchanged, got %d",
clipboard_update_count == last_clipboard_update_count + 1,
"Verify clipboard update count incremented by 1, got %d",
clipboard_update_count - last_clipboard_update_count);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+43 -43
View File
@@ -2,7 +2,7 @@
* Intrinsics test suite
*/
#ifndef NO_BUILD_CONFIG
#ifdef HAVE_BUILD_CONFIG
/* Disable intrinsics that are unsupported by the current compiler */
#include "SDL_build_config.h"
#endif
@@ -19,13 +19,13 @@
/* Helper functions */
static int allocate_random_int_arrays(Sint32 **dest, Sint32 **a, Sint32 **b, size_t *size) {
static int allocate_random_uint_arrays(Uint32 **dest, Uint32 **a, Uint32 **b, size_t *size) {
size_t i;
*size = (size_t)SDLTest_RandomIntegerInRange(127, 999);
*dest = SDL_malloc(sizeof(Sint32) * *size);
*a = SDL_malloc(sizeof(Sint32) * *size);
*b = SDL_malloc(sizeof(Sint32) * *size);
*dest = SDL_malloc(sizeof(Uint32) * *size);
*a = SDL_malloc(sizeof(Uint32) * *size);
*b = SDL_malloc(sizeof(Uint32) * *size);
if (!*dest || !*a || !*b) {
SDLTest_AssertCheck(false, "SDL_malloc failed");
@@ -33,8 +33,8 @@ static int allocate_random_int_arrays(Sint32 **dest, Sint32 **a, Sint32 **b, siz
}
for (i = 0; i < *size; ++i) {
(*a)[i] = SDLTest_RandomSint32();
(*b)[i] = SDLTest_RandomSint32();
(*a)[i] = SDLTest_RandomUint32();
(*b)[i] = SDLTest_RandomUint32();
}
return 0;
}
@@ -90,12 +90,12 @@ static void free_arrays(void *dest, void *a, void *b) {
/**
* Verify element-wise addition of 2 int arrays.
*/
static void verify_ints_addition(const Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size, const char *desc) {
static void verify_uints_addition(const Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size, const char *desc) {
size_t i;
int all_good = 1;
for (i = 0; i < size; ++i) {
Sint32 expected = a[i] + b[i];
Uint32 expected = a[i] + b[i];
if (dest[i] != expected) {
SDLTest_AssertCheck(false, "%" SDL_PRIs32 " + %" SDL_PRIs32 " = %" SDL_PRIs32 ", expected %" SDL_PRIs32 " ([%" SDL_PRIu32 "/%" SDL_PRIu32 "] %s)",
a[i], b[i], dest[i], expected, (Uint32)i, (Uint32)size, desc);
@@ -108,16 +108,16 @@ static void verify_ints_addition(const Sint32 *dest, const Sint32 *a, const Sint
}
/**
* Verify element-wise multiplication of 2 int arrays.
* Verify element-wise multiplication of 2 uint arrays.
*/
static void verify_ints_multiplication(const Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size, const char *desc) {
static void verify_uints_multiplication(const Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size, const char *desc) {
size_t i;
int all_good = 1;
for (i = 0; i < size; ++i) {
Sint32 expected = a[i] * b[i];
Uint32 expected = a[i] * b[i];
if (dest[i] != expected) {
SDLTest_AssertCheck(false, "%" SDL_PRIs32 " * %" SDL_PRIs32 " = %" SDL_PRIs32 ", expected %" SDL_PRIs32 " ([%" SDL_PRIu32 "/%" SDL_PRIu32 "] %s)",
SDLTest_AssertCheck(false, "%" SDL_PRIu32 " * %" SDL_PRIu32 " = %" SDL_PRIu32 ", expected %" SDL_PRIu32 " ([%" SDL_PRIu32 "/%" SDL_PRIu32 "] %s)",
a[i], b[i], dest[i], expected, (Uint32)i, (Uint32)size, desc);
all_good = 0;
}
@@ -171,13 +171,13 @@ static void verify_doubles_addition(const double *dest, const double *a, const d
/* Intrinsic kernels */
static void kernel_ints_add_cpu(Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size) {
static void kernel_uints_add_cpu(Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size) {
for (; size; --size, ++dest, ++a, ++b) {
*dest = *a + *b;
}
}
static void kernel_ints_mul_cpu(Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size) {
static void kernel_uints_mul_cpu(Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size) {
for (; size; --size, ++dest, ++a, ++b) {
*dest = *a * *b;
}
@@ -196,7 +196,7 @@ static void kernel_doubles_add_cpu(double *dest, const double *a, const double *
}
#ifdef SDL_MMX_INTRINSICS
SDL_TARGETING("mmx") static void kernel_ints_add_mmx(Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size) {
SDL_TARGETING("mmx") static void kernel_uints_add_mmx(Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size) {
for (; size >= 2; size -= 2, dest += 2, a += 2, b += 2) {
*(__m64*)dest = _mm_add_pi32(*(__m64*)a, *(__m64*)b);
}
@@ -230,7 +230,7 @@ SDL_TARGETING("sse2") static void kernel_doubles_add_sse2(double *dest, const do
#endif
#ifdef SDL_SSE3_INTRINSICS
SDL_TARGETING("sse3") static void kernel_ints_add_sse3(Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size) {
SDL_TARGETING("sse3") static void kernel_uints_add_sse3(Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
_mm_storeu_si128((__m128i*)dest, _mm_add_epi32(_mm_lddqu_si128((__m128i*)a), _mm_lddqu_si128((__m128i*)b)));
}
@@ -241,7 +241,7 @@ SDL_TARGETING("sse3") static void kernel_ints_add_sse3(Sint32 *dest, const Sint3
#endif
#ifdef SDL_SSE4_1_INTRINSICS
SDL_TARGETING("sse4.1") static void kernel_ints_mul_sse4_1(Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size) {
SDL_TARGETING("sse4.1") static void kernel_uints_mul_sse4_1(Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
_mm_storeu_si128((__m128i*)dest, _mm_mullo_epi32(_mm_lddqu_si128((__m128i*)a), _mm_lddqu_si128((__m128i*)b)));
}
@@ -294,7 +294,7 @@ SDL_TARGETING("avx") static void kernel_floats_add_avx(float *dest, const float
#endif
#ifdef SDL_AVX2_INTRINSICS
SDL_TARGETING("avx2") static void kernel_ints_add_avx2(Sint32 *dest, const Sint32 *a, const Sint32 *b, size_t size) {
SDL_TARGETING("avx2") static void kernel_uints_add_avx2(Uint32 *dest, const Uint32 *a, const Uint32 *b, size_t size) {
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
_mm256_storeu_si256((__m256i*)dest, _mm256_add_epi32(_mm256_loadu_si256((__m256i*)a), _mm256_loadu_si256((__m256i*)b)));
}
@@ -321,22 +321,22 @@ static int SDLCALL intrinsics_selftest(void *arg)
{
{
size_t size;
Sint32 *dest, *a, *b;
if (allocate_random_int_arrays(&dest, &a, &b, &size) < 0) {
Uint32 *dest, *a, *b;
if (allocate_random_uint_arrays(&dest, &a, &b, &size) < 0) {
return TEST_ABORTED;
}
kernel_ints_mul_cpu(dest, a, b, size);
verify_ints_multiplication(dest, a, b, size, "CPU");
kernel_uints_mul_cpu(dest, a, b, size);
verify_uints_multiplication(dest, a, b, size, "CPU");
free_arrays(dest, a, b);
}
{
size_t size;
Sint32 *dest, *a, *b;
if (allocate_random_int_arrays(&dest, &a, &b, &size) < 0) {
Uint32 *dest, *a, *b;
if (allocate_random_uint_arrays(&dest, &a, &b, &size) < 0) {
return TEST_ABORTED;
}
kernel_ints_add_cpu(dest, a, b, size);
verify_ints_addition(dest, a, b, size, "CPU");
kernel_uints_add_cpu(dest, a, b, size);
verify_uints_addition(dest, a, b, size, "CPU");
free_arrays(dest, a, b);
}
{
@@ -369,14 +369,14 @@ static int SDLCALL intrinsics_testMMX(void *arg)
#ifdef SDL_MMX_INTRINSICS
{
size_t size;
Sint32 *dest, *a, *b;
Uint32 *dest, *a, *b;
SDLTest_AssertCheck(true, "Test executable uses MMX intrinsics.");
if (allocate_random_int_arrays(&dest, &a, &b, &size) < 0) {
if (allocate_random_uint_arrays(&dest, &a, &b, &size) < 0) {
return TEST_ABORTED;
}
kernel_ints_add_mmx(dest, a, b, size);
verify_ints_addition(dest, a, b, size, "MMX");
kernel_uints_add_mmx(dest, a, b, size);
verify_uints_addition(dest, a, b, size, "MMX");
free_arrays(dest, a, b);
return TEST_COMPLETED;
@@ -453,14 +453,14 @@ static int SDLCALL intrinsics_testSSE3(void *arg)
#ifdef SDL_SSE3_INTRINSICS
{
size_t size;
Sint32 *dest, *a, *b;
Uint32 *dest, *a, *b;
SDLTest_AssertCheck(true, "Test executable uses SSE3 intrinsics.");
if (allocate_random_int_arrays(&dest, &a, &b, &size) < 0) {
if (allocate_random_uint_arrays(&dest, &a, &b, &size) < 0) {
return TEST_ABORTED;
}
kernel_ints_add_sse3(dest, a, b, size);
verify_ints_addition(dest, a, b, size, "SSE3");
kernel_uints_add_sse3(dest, a, b, size);
verify_uints_addition(dest, a, b, size, "SSE3");
free_arrays(dest, a, b);
return TEST_COMPLETED;
@@ -481,14 +481,14 @@ static int SDLCALL intrinsics_testSSE4_1(void *arg)
#ifdef SDL_SSE4_1_INTRINSICS
{
size_t size;
Sint32 *dest, *a, *b;
Uint32 *dest, *a, *b;
SDLTest_AssertCheck(true, "Test executable uses SSE4.1 intrinsics.");
if (allocate_random_int_arrays(&dest, &a, &b, &size) < 0) {
if (allocate_random_uint_arrays(&dest, &a, &b, &size) < 0) {
return TEST_ABORTED;
}
kernel_ints_mul_sse4_1(dest, a, b, size);
verify_ints_multiplication(dest, a, b, size, "SSE4.1");
kernel_uints_mul_sse4_1(dest, a, b, size);
verify_uints_multiplication(dest, a, b, size, "SSE4.1");
free_arrays(dest, a, b);
return TEST_COMPLETED;
@@ -572,14 +572,14 @@ static int SDLCALL intrinsics_testAVX2(void *arg)
#ifdef SDL_AVX2_INTRINSICS
{
size_t size;
Sint32 *dest, *a, *b;
Uint32 *dest, *a, *b;
SDLTest_AssertCheck(true, "Test executable uses AVX2 intrinsics.");
if (allocate_random_int_arrays(&dest, &a, &b, &size) < 0) {
if (allocate_random_uint_arrays(&dest, &a, &b, &size) < 0) {
return TEST_ABORTED;
}
kernel_ints_add_avx2(dest, a, b, size);
verify_ints_addition(dest, a, b, size, "AVX2");
kernel_uints_add_avx2(dest, a, b, size);
verify_uints_addition(dest, a, b, size, "AVX2");
free_arrays(dest, a, b);
return TEST_COMPLETED;
+2
View File
@@ -9,7 +9,9 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_test.h>
#include "testautomation_suites.h"
#ifdef HAVE_BUILD_CONFIG
#include "SDL_build_config.h"
#endif
/**
* Tests SDL_InitSubSystem() and SDL_QuitSubSystem()
+2 -2
View File
@@ -1149,8 +1149,8 @@ static int SDLCALL render_testLogicalSize(void *arg)
CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer, w / factor, h / factor, SDL_LOGICAL_PRESENTATION_LETTERBOX))
viewport.x = (TESTRENDER_SCREEN_W / 4) / factor;
viewport.y = (TESTRENDER_SCREEN_H / 4) / factor;
viewport.w = TESTRENDER_SCREEN_W / factor;
viewport.h = TESTRENDER_SCREEN_H / factor;
viewport.w = (TESTRENDER_SCREEN_W / 2) / factor;
viewport.h = (TESTRENDER_SCREEN_H / 2) / factor;
CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport))
CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
+2 -4
View File
@@ -1063,17 +1063,15 @@ static int SDLCALL sdltest_randomIntegerInRange(void *arg)
SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(max,min)");
SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%" SDL_PRIs32 ",%" SDL_PRIs32 "], got: %" SDL_PRIs32, min, max, result);
#if 0 /* This test correctly triggers an asan warning: runtime error: signed integer overflow: 2147483647 + 4239 cannot be represented in type 'int' */
/* Range with min at integer limit */
min = long_min;
max = long_max + (Sint32)SDLTest_RandomSint16();
max = long_min + (Sint32)SDLTest_RandomUint16();
result = SDLTest_RandomIntegerInRange(min, max);
SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(SINT32_MIN,...)");
SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%" SDL_PRIs32 ",%" SDL_PRIs32 "], got: %" SDL_PRIs32, min, max, result);
#endif
/* Range with max at integer limit */
min = long_min - (Sint32)SDLTest_RandomSint16();
min = long_max - (Sint32)SDLTest_RandomUint16();
max = long_max;
result = SDLTest_RandomIntegerInRange(min, max);
SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(...,SINT32_MAX)");
+27
View File
@@ -386,6 +386,22 @@ static int SDLCALL stdlib_swprintf(void *arg)
const wchar_t *expected;
size_t size;
result = SDL_swprintf(text, SDL_arraysize(text), L"%s", "hello, world");
expected = L"hello, world";
SDLTest_AssertPass("Call to SDL_swprintf(\"%%s\", \"hello, world\")");
SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %S, got: %S", expected, text);
SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
result = SDL_swprintf(text, 2, L"%s", "hello, world");
expected = L"h";
SDLTest_AssertPass("Call to SDL_swprintf(\"%%s\", \"hello, world\") with buffer size 2");
SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %S, got: %S", expected, text);
SDLTest_AssertCheck(result == 12, "Check result value, expected: 12, got: %d", result);
result = SDL_swprintf(NULL, 0, L"%s", "hello, world");
SDLTest_AssertPass("Call to SDL_swprintf(NULL, 0, \"%%s\", \"hello, world\")");
SDLTest_AssertCheck(result == 12, "Check result value, expected: 12, got: %d", result);
result = SDL_swprintf(text, SDL_arraysize(text), L"%s", "foo");
expected = L"foo";
SDLTest_AssertPass("Call to SDL_swprintf(\"%%s\", \"foo\")");
@@ -1324,6 +1340,9 @@ static int SDLCALL stdlib_strtox(void *arg)
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, "-uvwxyz", 32, -991, 3);
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, "ZzZzZzZzZzZzZzZzZzZzZzZzZ", 36, ullong_max, 25);
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, "0", 0, 0, 1);
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, "0", 10, 0, 1);
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, "-0", 0, 0, 2);
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, "-0", 10, 0, 2);
STRTOX_TEST_CASE(SDL_strtoull, unsigned long long, FMT_PRILLu, " - 1", 0, 0, 0); // invalid input
@@ -1335,6 +1354,10 @@ static int SDLCALL stdlib_strtox(void *arg)
// Since the CI runs the tests against a variety of targets, this should be fine in practice.
if (sizeof(long) == 4) {
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "0", 0, 0, 1);
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "0", 10, 0, 1);
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "-0", 0, 0, 2);
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "-0", 10, 0, 2);
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "2147483647", 10, 2147483647, 10);
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "2147483648", 10, 2147483647, 10);
STRTOX_TEST_CASE(SDL_strtol, long, "%ld", "-2147483648", 10, -2147483647L - 1, 11);
@@ -1347,6 +1370,10 @@ static int SDLCALL stdlib_strtox(void *arg)
}
if (sizeof(long long) == 8) {
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "0", 0, 0LL, 1);
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "0", 10, 0LL, 1);
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "-0", 0, 0LL, 2);
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "-0", 10, 0LL, 2);
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "9223372036854775807", 10, 9223372036854775807LL, 19);
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "9223372036854775808", 10, 9223372036854775807LL, 19);
STRTOX_TEST_CASE(SDL_strtoll, long long, FMT_PRILLd, "-9223372036854775808", 10, -9223372036854775807LL - 1, 20);
+1 -8
View File
@@ -1006,10 +1006,6 @@ static int SDLCALL video_getSetWindowSize(void *arg)
int referenceW, referenceH;
int currentW, currentH;
int desiredW, desiredH;
const bool restoreHint = SDL_GetHintBoolean("SDL_BORDERLESS_RESIZABLE_STYLE", true);
/* Win32 borderless windows are not resizable by default and need this undocumented hint */
SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1");
/* Get display bounds for size range */
result = SDL_GetDisplayUsableBounds(SDL_GetPrimaryDisplay(), &display);
@@ -1026,7 +1022,7 @@ static int SDLCALL video_getSetWindowSize(void *arg)
}
SDL_GetWindowSize(window, &currentW, &currentH);
if (SDL_SetWindowSize(window, currentW, currentH)) {
if (!SDL_SetWindowSize(window, currentW, currentH)) {
SDLTest_Log("Skipping window resize tests: %s reports window resizing as unsupported", SDL_GetCurrentVideoDriver());
goto null_tests;
}
@@ -1188,9 +1184,6 @@ null_tests:
SDLTest_AssertPass("Call to SDL_SetWindowSize(window=NULL)");
checkInvalidWindowError();
/* Restore the hint to the previous value */
SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", restoreHint ? "1" : "0");
return TEST_COMPLETED;
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+41 -14
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -19,7 +19,6 @@ static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDLTest_CommonState *state = NULL;
static SDL_Camera *camera = NULL;
static SDL_CameraSpec spec;
static SDL_Texture *texture = NULL;
static bool texture_updated = false;
static SDL_Surface *frame_current = NULL;
@@ -46,12 +45,34 @@ static void PrintCameraSpecs(SDL_CameraID camera_id)
}
}
static void PickCameraSpec(SDL_CameraID camera_id, SDL_CameraSpec *spec)
{
SDL_CameraSpec **specs = SDL_GetCameraSupportedFormats(camera_id, NULL);
SDL_zerop(spec);
if (specs) {
int i;
int max_size = (int)SDL_GetNumberProperty(SDL_GetRendererProperties(state->renderers[0]), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 0);
for (i = 0; specs[i]; ++i) {
const SDL_CameraSpec *s = specs[i];
if (s->width <= max_size && s->height <= max_size) {
SDL_copyp(spec, s);
break;
}
}
SDL_free(specs);
}
}
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
char window_title[128];
int devcount = 0;
int i;
const char *camera_name = NULL;
SDL_CameraSpec spec;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO | SDL_INIT_CAMERA);
@@ -78,7 +99,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
SDLTest_CommonLogUsage(state, argv[0], options);
SDL_Quit();
SDLTest_CommonDestroyState(state);
return 1;
return SDL_APP_FAILURE;
}
i += consumed;
}
@@ -103,6 +124,8 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
return SDL_APP_FAILURE;
}
SDL_Log("Using SDL camera driver: %s", SDL_GetCurrentCameraDriver());
SDL_CameraID *devices = SDL_GetCameras(&devcount);
if (!devices) {
SDL_Log("SDL_GetCameras failed: %s", SDL_GetError());
@@ -118,16 +141,22 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
const SDL_CameraPosition position = SDL_GetCameraPosition(device);
const char *posstr = "";
if (position == SDL_CAMERA_POSITION_FRONT_FACING) {
front_camera = device;
if (!front_camera) {
front_camera = device;
}
posstr = "[front-facing] ";
} else if (position == SDL_CAMERA_POSITION_BACK_FACING) {
back_camera = device;
if (!back_camera) {
back_camera = device;
}
posstr = "[back-facing] ";
}
if (camera_name && SDL_strcasecmp(name, camera_name) == 0) {
camera_id = device;
}
SDL_Log(" - Camera #%d: %s %s", i, posstr, name);
PrintCameraSpecs(device);
}
if (!camera_id) {
@@ -148,13 +177,8 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
return SDL_APP_FAILURE;
}
PrintCameraSpecs(camera_id);
SDL_CameraSpec *pspec = &spec;
spec.framerate_numerator = 30;
spec.framerate_denominator = 1;
camera = SDL_OpenCamera(camera_id, pspec);
PickCameraSpec(camera_id, &spec);
camera = SDL_OpenCamera(camera_id, &spec);
if (!camera) {
SDL_Log("Failed to open camera device: %s", SDL_GetError());
return SDL_APP_FAILURE;
@@ -184,6 +208,8 @@ static int FlipCamera(void)
}
if (nextcam) {
SDL_CameraSpec spec;
SDL_Log("Flip camera!");
if (frame_current) {
@@ -198,7 +224,8 @@ static int FlipCamera(void)
texture = NULL; /* will rebuild when new camera is approved. */
}
camera = SDL_OpenCamera(nextcam, NULL);
PickCameraSpec(nextcam, &spec);
camera = SDL_OpenCamera(nextcam, &spec);
if (!camera) {
SDL_Log("Failed to open camera device: %s", SDL_GetError());
return SDL_APP_FAILURE;
@@ -232,7 +259,7 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
case SDL_EVENT_QUIT:
SDL_Log("Quit!");
return 1;
return SDL_APP_SUCCESS;
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
SDL_Log("Camera approved!");
+180
View File
@@ -0,0 +1,180 @@
/*
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include "icon.h"
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static const char *mime_types[] = {
"text/plain",
"image/bmp",
};
static const void *ClipboardDataCallback(void *userdata, const char *mime_type, size_t *size)
{
if (SDL_strcmp(mime_type, "text/plain") == 0) {
const char *text = "Hello world!";
*size = SDL_strlen(text);
return text;
} else if (SDL_strcmp(mime_type, "image/bmp") == 0) {
*size = icon_bmp_len;
return icon_bmp;
} else {
return NULL;
}
}
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("testclipboard", 640, 480, 0, &window, &renderer)) {
SDL_Log("Couldn't create window and renderer: %s\n", SDL_GetError());
return SDL_APP_FAILURE;
}
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
switch (event->type) {
case SDL_EVENT_KEY_DOWN:
if (event->key.key == SDLK_ESCAPE) {
return SDL_APP_SUCCESS;
}
if (event->key.key == SDLK_C && event->key.mod & SDL_KMOD_CTRL) {
SDL_SetClipboardData(ClipboardDataCallback, NULL, NULL, mime_types, SDL_arraysize(mime_types));
break;
}
break;
case SDL_EVENT_CLIPBOARD_UPDATE:
if (event->clipboard.num_mime_types > 0) {
int i;
SDL_Log("Clipboard updated:\n");
for (i = 0; event->clipboard.mime_types[i]; ++i) {
SDL_Log(" %s\n", event->clipboard.mime_types[i]);
}
} else {
SDL_Log("Clipboard cleared\n");
}
break;
case SDL_EVENT_QUIT:
return SDL_APP_SUCCESS;
default:
break;
}
return SDL_APP_CONTINUE;
}
static float PrintClipboardText(float x, float y, const char *mime_type)
{
void *data = SDL_GetClipboardData(mime_type, NULL);
if (data) {
SDL_RenderDebugText(renderer, x, y, (const char *)data);
SDL_free(data);
return SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2.0f;
}
return 0.0f;
}
static float PrintClipboardImage(float x, float y, const char *mime_type)
{
/* We don't actually need to read this data each frame, but this is a simple example */
if (SDL_strcmp(mime_type, "image/bmp") == 0) {
size_t size;
void *data = SDL_GetClipboardData(mime_type, &size);
if (data) {
float w = 0.0f, h = 0.0f;
bool rendered = false;
SDL_IOStream *stream = SDL_IOFromConstMem(data, size);
if (stream) {
SDL_Surface *surface = SDL_LoadBMP_IO(stream, false);
if (surface) {
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
if (texture) {
SDL_GetTextureSize(texture, &w, &h);
SDL_FRect dst = { x, y, w, h };
rendered = SDL_RenderTexture(renderer, texture, NULL, &dst);
SDL_DestroyTexture(texture);
}
SDL_DestroySurface(surface);
}
SDL_CloseIO(stream);
}
if (!rendered) {
SDL_RenderDebugText(renderer, x, y, SDL_GetError());
}
SDL_free(data);
return h + 2.0f;
}
}
return 0.0f;
}
static void PrintClipboardContents(float x, float y)
{
char **clipboard_mime_types = SDL_GetClipboardMimeTypes(NULL);
if (clipboard_mime_types) {
int i;
for (i = 0; clipboard_mime_types[i]; ++i) {
const char *mime_type = clipboard_mime_types[i];
SDL_RenderDebugText(renderer, x, y, mime_type);
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
if (SDL_strncmp(mime_type, "text/", 5) == 0) {
y += PrintClipboardText(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y, mime_type);
} else if (SDL_strncmp(mime_type, "image/", 6) == 0) {
y += PrintClipboardImage(x + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2, y, mime_type);
}
}
SDL_free(clipboard_mime_types);
}
}
SDL_AppResult SDL_AppIterate(void *appstate)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
float x = 4.0f;
float y = 4.0f;
SDL_RenderDebugText(renderer, x, y, "Press Ctrl+C to copy content to the clipboard");
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2;
SDL_RenderDebugText(renderer, x, y, "Clipboard contents:");
x += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2;
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
PrintClipboardContents(x, y);
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE;
}
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+395 -399
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -12,6 +12,7 @@
/* Simple program to test the SDL controller routines */
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
@@ -64,6 +65,7 @@ typedef struct
int trigger_effect;
} Controller;
static SDLTest_CommonState *state;
static SDL_Window *window = NULL;
static SDL_Renderer *screen = NULL;
static ControllerDisplayMode display_mode = CONTROLLER_MODE_TESTING;
@@ -194,47 +196,47 @@ typedef struct
static void CyclePS5AudioRoute(Controller *device)
{
DS5EffectsState_t state;
DS5EffectsState_t effects;
device->audio_route = (device->audio_route + 1) % 4;
SDL_zero(state);
SDL_zero(effects);
switch (device->audio_route) {
case 0:
/* Audio disabled */
state.ucEnableBits1 |= (0x80 | 0x20 | 0x10); /* Modify audio route and speaker / headphone volume */
state.ucSpeakerVolume = 0; /* Minimum volume */
state.ucHeadphoneVolume = 0; /* Minimum volume */
state.ucAudioEnableBits = 0x00; /* Output to headphones */
effects.ucEnableBits1 |= (0x80 | 0x20 | 0x10); /* Modify audio route and speaker / headphone volume */
effects.ucSpeakerVolume = 0; /* Minimum volume */
effects.ucHeadphoneVolume = 0; /* Minimum volume */
effects.ucAudioEnableBits = 0x00; /* Output to headphones */
break;
case 1:
/* Headphones */
state.ucEnableBits1 |= (0x80 | 0x10); /* Modify audio route and headphone volume */
state.ucHeadphoneVolume = 50; /* 50% volume - don't blast into the ears */
state.ucAudioEnableBits = 0x00; /* Output to headphones */
effects.ucEnableBits1 |= (0x80 | 0x10); /* Modify audio route and headphone volume */
effects.ucHeadphoneVolume = 50; /* 50% volume - don't blast into the ears */
effects.ucAudioEnableBits = 0x00; /* Output to headphones */
break;
case 2:
/* Speaker */
state.ucEnableBits1 |= (0x80 | 0x20); /* Modify audio route and speaker volume */
state.ucSpeakerVolume = 100; /* Maximum volume */
state.ucAudioEnableBits = 0x30; /* Output to speaker */
effects.ucEnableBits1 |= (0x80 | 0x20); /* Modify audio route and speaker volume */
effects.ucSpeakerVolume = 100; /* Maximum volume */
effects.ucAudioEnableBits = 0x30; /* Output to speaker */
break;
case 3:
/* Both */
state.ucEnableBits1 |= (0x80 | 0x20 | 0x10); /* Modify audio route and speaker / headphone volume */
state.ucSpeakerVolume = 100; /* Maximum volume */
state.ucHeadphoneVolume = 50; /* 50% volume - don't blast into the ears */
state.ucAudioEnableBits = 0x20; /* Output to both speaker and headphones */
effects.ucEnableBits1 |= (0x80 | 0x20 | 0x10); /* Modify audio route and speaker / headphone volume */
effects.ucSpeakerVolume = 100; /* Maximum volume */
effects.ucHeadphoneVolume = 50; /* 50% volume - don't blast into the ears */
effects.ucAudioEnableBits = 0x20; /* Output to both speaker and headphones */
break;
}
SDL_SendGamepadEffect(device->gamepad, &state, sizeof(state));
SDL_SendGamepadEffect(device->gamepad, &effects, sizeof(effects));
}
static void CyclePS5TriggerEffect(Controller *device)
{
DS5EffectsState_t state;
DS5EffectsState_t effects;
Uint8 effects[3][11] = {
Uint8 trigger_effects[3][11] = {
/* Clear trigger effect */
{ 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* Constant resistance across entire trigger pull */
@@ -243,13 +245,13 @@ static void CyclePS5TriggerEffect(Controller *device)
{ 0x06, 15, 63, 128, 0, 0, 0, 0, 0, 0, 0 },
};
device->trigger_effect = (device->trigger_effect + 1) % SDL_arraysize(effects);
device->trigger_effect = (device->trigger_effect + 1) % SDL_arraysize(trigger_effects);
SDL_zero(state);
state.ucEnableBits1 |= (0x04 | 0x08); /* Modify right and left trigger effect respectively */
SDL_memcpy(state.rgucRightTriggerEffect, effects[device->trigger_effect], sizeof(effects[0]));
SDL_memcpy(state.rgucLeftTriggerEffect, effects[device->trigger_effect], sizeof(effects[0]));
SDL_SendGamepadEffect(device->gamepad, &state, sizeof(state));
SDL_zero(effects);
effects.ucEnableBits1 |= (0x04 | 0x08); /* Modify right and left trigger effect respectively */
SDL_memcpy(effects.rgucRightTriggerEffect, trigger_effects[device->trigger_effect], sizeof(trigger_effects[0]));
SDL_memcpy(effects.rgucLeftTriggerEffect, trigger_effects[device->trigger_effect], sizeof(trigger_effects[0]));
SDL_SendGamepadEffect(device->gamepad, &effects, sizeof(effects));
}
static void ClearButtonHighlights(void)
@@ -910,8 +912,10 @@ static void AddController(SDL_JoystickID id, bool verbose)
new_controller->id = id;
new_controller->joystick = SDL_OpenJoystick(id);
new_controller->num_axes = SDL_GetNumJoystickAxes(new_controller->joystick);
new_controller->axis_state = (AxisState *)SDL_calloc(new_controller->num_axes, sizeof(*new_controller->axis_state));
if (new_controller->joystick) {
new_controller->num_axes = SDL_GetNumJoystickAxes(new_controller->joystick);
new_controller->axis_state = (AxisState *)SDL_calloc(new_controller->num_axes, sizeof(*new_controller->axis_state));
}
joystick = new_controller->joystick;
if (joystick) {
@@ -1017,6 +1021,7 @@ static void HandleGamepadAdded(SDL_JoystickID id, bool verbose)
if (i < 0) {
return;
}
SDL_Log("Gamepad %" SDL_PRIu32 " added\n", id);
SDL_assert(!controllers[i].gamepad);
controllers[i].gamepad = SDL_OpenGamepad(id);
@@ -1088,6 +1093,7 @@ static void HandleGamepadRemoved(SDL_JoystickID id)
if (i < 0) {
return;
}
SDL_Log("Gamepad %" SDL_PRIu32 " removed\n", id);
if (controllers[i].mapping) {
SDL_free(controllers[i].mapping);
@@ -1569,360 +1575,361 @@ static void UpdateGamepadEffects(void)
}
}
static void loop(void *arg)
SDL_AppResult SDLCALL SDL_AppEvent(void *appstate, SDL_Event *event)
{
SDL_Event event;
SDL_ConvertEventToRenderCoordinates(screen, event);
switch (event->type) {
case SDL_EVENT_JOYSTICK_ADDED:
AddController(event->jdevice.which, true);
break;
case SDL_EVENT_JOYSTICK_REMOVED:
DelController(event->jdevice.which);
break;
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event->jaxis.value <= (-SDL_JOYSTICK_AXIS_MAX / 2) || event->jaxis.value >= (SDL_JOYSTICK_AXIS_MAX / 2)) {
SetController(event->jaxis.which);
}
} else if (display_mode == CONTROLLER_MODE_BINDING &&
event->jaxis.which == controller->id &&
event->jaxis.axis < controller->num_axes &&
binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 gamepad needed 96 */
AxisState *pAxisState = &controller->axis_state[event->jaxis.axis];
int nValue = event->jaxis.value;
int nCurrentDistance, nFarthestDistance;
if (!pAxisState->m_bMoving) {
Sint16 nInitialValue;
pAxisState->m_bMoving = SDL_GetJoystickAxisInitialState(controller->joystick, event->jaxis.axis, &nInitialValue);
pAxisState->m_nLastValue = nValue;
pAxisState->m_nStartingValue = nInitialValue;
pAxisState->m_nFarthestValue = nInitialValue;
} else if (SDL_abs(nValue - pAxisState->m_nLastValue) <= MAX_ALLOWED_JITTER) {
break;
} else {
pAxisState->m_nLastValue = nValue;
}
nCurrentDistance = SDL_abs(nValue - pAxisState->m_nStartingValue);
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
if (nCurrentDistance > nFarthestDistance) {
pAxisState->m_nFarthestValue = nValue;
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
}
#ifdef DEBUG_AXIS_MAPPING
SDL_Log("AXIS %d nValue %d nCurrentDistance %d nFarthestDistance %d\n", event->jaxis.axis, nValue, nCurrentDistance, nFarthestDistance);
#endif
/* If we've gone out far enough and started to come back, let's bind this axis */
if (nFarthestDistance >= 16000 && nCurrentDistance <= 10000) {
char binding[12];
int axis_min = StandardizeAxisValue(pAxisState->m_nStartingValue);
int axis_max = StandardizeAxisValue(pAxisState->m_nFarthestValue);
if (axis_min == 0 && axis_max == SDL_JOYSTICK_AXIS_MIN) {
/* The negative half axis */
(void)SDL_snprintf(binding, sizeof(binding), "-a%d", event->jaxis.axis);
} else if (axis_min == 0 && axis_max == SDL_JOYSTICK_AXIS_MAX) {
/* The positive half axis */
(void)SDL_snprintf(binding, sizeof(binding), "+a%d", event->jaxis.axis);
} else {
(void)SDL_snprintf(binding, sizeof(binding), "a%d", event->jaxis.axis);
if (axis_min > axis_max) {
/* Invert the axis */
SDL_strlcat(binding, "~", SDL_arraysize(binding));
}
}
#ifdef DEBUG_AXIS_MAPPING
SDL_Log("AXIS %d axis_min = %d, axis_max = %d, binding = %s\n", event->jaxis.axis, axis_min, axis_max, binding);
#endif
CommitBindingElement(binding, false);
}
}
break;
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
if (display_mode == CONTROLLER_MODE_TESTING) {
SetController(event->jbutton.which);
}
break;
case SDL_EVENT_JOYSTICK_BUTTON_UP:
if (display_mode == CONTROLLER_MODE_BINDING &&
event->jbutton.which == controller->id &&
binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
char binding[12];
SDL_snprintf(binding, sizeof(binding), "b%d", event->jbutton.button);
CommitBindingElement(binding, false);
}
break;
case SDL_EVENT_JOYSTICK_HAT_MOTION:
if (display_mode == CONTROLLER_MODE_BINDING &&
event->jhat.which == controller->id &&
event->jhat.value != SDL_HAT_CENTERED &&
binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
char binding[12];
SDL_snprintf(binding, sizeof(binding), "h%d.%d", event->jhat.hat, event->jhat.value);
CommitBindingElement(binding, false);
}
break;
case SDL_EVENT_GAMEPAD_ADDED:
HandleGamepadAdded(event->gdevice.which, true);
break;
case SDL_EVENT_GAMEPAD_REMOVED:
HandleGamepadRemoved(event->gdevice.which);
break;
case SDL_EVENT_GAMEPAD_REMAPPED:
HandleGamepadRemapped(event->gdevice.which);
break;
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
RefreshControllerName();
break;
#ifdef VERBOSE_TOUCHPAD
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
SDL_Log("Gamepad %" SDL_PRIu32 " touchpad %" SDL_PRIs32 " finger %" SDL_PRIs32 " %s %.2f, %.2f, %.2f\n",
event->gtouchpad.which,
event->gtouchpad.touchpad,
event->gtouchpad.finger,
(event->type == SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN ? "pressed at" : (event->type == SDL_EVENT_GAMEPAD_TOUCHPAD_UP ? "released at" : "moved to")),
event->gtouchpad.x,
event->gtouchpad.y,
event->gtouchpad.pressure);
break;
#endif /* VERBOSE_TOUCHPAD */
#ifdef VERBOSE_SENSORS
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
SDL_Log("Gamepad %" SDL_PRIu32 " sensor %s: %.2f, %.2f, %.2f (%" SDL_PRIu64 ")\n",
event->gsensor.which,
GetSensorName((SDL_SensorType) event->gsensor.sensor),
event->gsensor.data[0],
event->gsensor.data[1],
event->gsensor.data[2],
event->gsensor.sensor_timestamp);
break;
#endif /* VERBOSE_SENSORS */
#ifdef VERBOSE_AXES
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event->gaxis.value <= (-SDL_JOYSTICK_AXIS_MAX / 2) || event->gaxis.value >= (SDL_JOYSTICK_AXIS_MAX / 2)) {
SetController(event->gaxis.which);
}
}
SDL_Log("Gamepad %" SDL_PRIu32 " axis %s changed to %d\n",
event->gaxis.which,
SDL_GetGamepadStringForAxis((SDL_GamepadAxis) event->gaxis.axis),
event->gaxis.value);
break;
#endif /* VERBOSE_AXES */
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
case SDL_EVENT_GAMEPAD_BUTTON_UP:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
SetController(event->gbutton.which);
}
}
#ifdef VERBOSE_BUTTONS
SDL_Log("Gamepad %" SDL_PRIu32 " button %s %s\n",
event->gbutton.which,
SDL_GetGamepadStringForButton((SDL_GamepadButton) event->gbutton.button),
event->gbutton.state ? "pressed" : "released");
#endif /* VERBOSE_BUTTONS */
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN &&
controller && SDL_GetGamepadType(controller->gamepad) == SDL_GAMEPAD_TYPE_PS5) {
/* Cycle PS5 audio routing when the microphone button is pressed */
if (event->gbutton.button == SDL_GAMEPAD_BUTTON_MISC1) {
CyclePS5AudioRoute(controller);
}
/* Cycle PS5 trigger effects when the triangle button is pressed */
if (event->gbutton.button == SDL_GAMEPAD_BUTTON_NORTH) {
CyclePS5TriggerEffect(controller);
}
}
}
break;
case SDL_EVENT_MOUSE_BUTTON_DOWN:
if (virtual_joystick && controller && controller->joystick == virtual_joystick) {
VirtualGamepadMouseDown(event->button.x, event->button.y);
}
UpdateButtonHighlights(event->button.x, event->button.y, event->button.down);
break;
case SDL_EVENT_MOUSE_BUTTON_UP:
if (virtual_joystick && controller && controller->joystick == virtual_joystick) {
VirtualGamepadMouseUp(event->button.x, event->button.y);
}
if (display_mode == CONTROLLER_MODE_TESTING) {
if (GamepadButtonContains(setup_mapping_button, event->button.x, event->button.y)) {
SetDisplayMode(CONTROLLER_MODE_BINDING);
}
} else if (display_mode == CONTROLLER_MODE_BINDING) {
if (GamepadButtonContains(done_mapping_button, event->button.x, event->button.y)) {
if (controller->mapping) {
SDL_Log("Mapping complete:\n");
SDL_Log("%s\n", controller->mapping);
}
SetDisplayMode(CONTROLLER_MODE_TESTING);
} else if (GamepadButtonContains(cancel_button, event->button.x, event->button.y)) {
CancelMapping();
} else if (GamepadButtonContains(clear_button, event->button.x, event->button.y)) {
ClearMapping();
} else if (controller->has_bindings &&
GamepadButtonContains(copy_button, event->button.x, event->button.y)) {
CopyMapping();
} else if (GamepadButtonContains(paste_button, event->button.x, event->button.y)) {
PasteMapping();
} else if (title_pressed) {
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_NAME, false);
} else if (type_pressed) {
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_TYPE, false);
} else if (binding_element == SDL_GAMEPAD_ELEMENT_TYPE) {
int type = GetGamepadTypeDisplayAt(gamepad_type, event->button.x, event->button.y);
if (type != SDL_GAMEPAD_TYPE_UNSELECTED) {
CommitGamepadType((SDL_GamepadType)type);
StopBinding();
}
} else {
int gamepad_element = SDL_GAMEPAD_ELEMENT_INVALID;
char *joystick_element;
if (controller->joystick != virtual_joystick) {
gamepad_element = GetGamepadImageElementAt(image, event->button.x, event->button.y);
}
if (gamepad_element == SDL_GAMEPAD_ELEMENT_INVALID) {
gamepad_element = GetGamepadDisplayElementAt(gamepad_elements, controller->gamepad, event->button.x, event->button.y);
}
if (gamepad_element != SDL_GAMEPAD_ELEMENT_INVALID) {
/* Set this to false if you don't want to start the binding flow at this point */
const bool should_start_flow = true;
SetCurrentBindingElement(gamepad_element, should_start_flow);
}
joystick_element = GetJoystickDisplayElementAt(joystick_elements, controller->joystick, event->button.x, event->button.y);
if (joystick_element) {
CommitBindingElement(joystick_element, true);
SDL_free(joystick_element);
}
}
}
UpdateButtonHighlights(event->button.x, event->button.y, event->button.down);
break;
case SDL_EVENT_MOUSE_MOTION:
if (virtual_joystick && controller && controller->joystick == virtual_joystick) {
VirtualGamepadMouseMotion(event->motion.x, event->motion.y);
}
UpdateButtonHighlights(event->motion.x, event->motion.y, event->motion.state ? true : false);
break;
case SDL_EVENT_KEY_DOWN:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event->key.key >= SDLK_0 && event->key.key <= SDLK_9) {
if (controller && controller->gamepad) {
int player_index = (event->key.key - SDLK_0);
SDL_SetGamepadPlayerIndex(controller->gamepad, player_index);
}
break;
} else if (event->key.key == SDLK_A) {
OpenVirtualGamepad();
} else if (event->key.key == SDLK_D) {
CloseVirtualGamepad();
} else if (event->key.key == SDLK_R && (event->key.mod & SDL_KMOD_CTRL)) {
SDL_ReloadGamepadMappings();
} else if (event->key.key == SDLK_ESCAPE) {
done = true;
}
} else if (display_mode == CONTROLLER_MODE_BINDING) {
if (event->key.key == SDLK_C && (event->key.mod & SDL_KMOD_CTRL)) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
CopyControllerName();
} else {
CopyMapping();
}
} else if (event->key.key == SDLK_V && (event->key.mod & SDL_KMOD_CTRL)) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
ClearControllerName();
PasteControllerName();
} else {
PasteMapping();
}
} else if (event->key.key == SDLK_X && (event->key.mod & SDL_KMOD_CTRL)) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
CopyControllerName();
ClearControllerName();
} else {
CopyMapping();
ClearMapping();
}
} else if (event->key.key == SDLK_SPACE) {
if (binding_element != SDL_GAMEPAD_ELEMENT_NAME) {
ClearBinding();
}
} else if (event->key.key == SDLK_BACKSPACE) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
BackspaceControllerName();
}
} else if (event->key.key == SDLK_RETURN) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
StopBinding();
}
} else if (event->key.key == SDLK_ESCAPE) {
if (binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
StopBinding();
} else {
CancelMapping();
}
}
}
break;
case SDL_EVENT_TEXT_INPUT:
if (display_mode == CONTROLLER_MODE_BINDING) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
AddControllerNameText(event->text.text);
}
}
break;
case SDL_EVENT_QUIT:
done = true;
break;
default:
break;
}
if (done) {
return SDL_APP_SUCCESS;
} else {
return SDL_APP_CONTINUE;
}
}
SDL_AppResult SDLCALL SDL_AppIterate(void *appstate)
{
/* If we have a virtual controller, send a virtual accelerometer sensor reading */
if (virtual_joystick) {
float data[3] = { 0.0f, SDL_STANDARD_GRAVITY, 0.0f };
SDL_SendJoystickVirtualSensorData(virtual_joystick, SDL_SENSOR_ACCEL, SDL_GetTicksNS(), data, SDL_arraysize(data));
}
/* Update to get the current event state */
SDL_PumpEvents();
/* Process all currently pending events */
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) == 1) {
SDL_ConvertEventToRenderCoordinates(screen, &event);
switch (event.type) {
case SDL_EVENT_JOYSTICK_ADDED:
AddController(event.jdevice.which, true);
break;
case SDL_EVENT_JOYSTICK_REMOVED:
DelController(event.jdevice.which);
break;
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event.jaxis.value <= (-SDL_JOYSTICK_AXIS_MAX / 2) || event.jaxis.value >= (SDL_JOYSTICK_AXIS_MAX / 2)) {
SetController(event.jaxis.which);
}
} else if (display_mode == CONTROLLER_MODE_BINDING &&
event.jaxis.which == controller->id &&
event.jaxis.axis < controller->num_axes &&
binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 gamepad needed 96 */
AxisState *pAxisState = &controller->axis_state[event.jaxis.axis];
int nValue = event.jaxis.value;
int nCurrentDistance, nFarthestDistance;
if (!pAxisState->m_bMoving) {
Sint16 nInitialValue;
pAxisState->m_bMoving = SDL_GetJoystickAxisInitialState(controller->joystick, event.jaxis.axis, &nInitialValue);
pAxisState->m_nLastValue = nValue;
pAxisState->m_nStartingValue = nInitialValue;
pAxisState->m_nFarthestValue = nInitialValue;
} else if (SDL_abs(nValue - pAxisState->m_nLastValue) <= MAX_ALLOWED_JITTER) {
break;
} else {
pAxisState->m_nLastValue = nValue;
}
nCurrentDistance = SDL_abs(nValue - pAxisState->m_nStartingValue);
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
if (nCurrentDistance > nFarthestDistance) {
pAxisState->m_nFarthestValue = nValue;
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
}
#ifdef DEBUG_AXIS_MAPPING
SDL_Log("AXIS %d nValue %d nCurrentDistance %d nFarthestDistance %d\n", event.jaxis.axis, nValue, nCurrentDistance, nFarthestDistance);
#endif
/* If we've gone out far enough and started to come back, let's bind this axis */
if (nFarthestDistance >= 16000 && nCurrentDistance <= 10000) {
char binding[12];
int axis_min = StandardizeAxisValue(pAxisState->m_nStartingValue);
int axis_max = StandardizeAxisValue(pAxisState->m_nFarthestValue);
if (axis_min == 0 && axis_max == SDL_JOYSTICK_AXIS_MIN) {
/* The negative half axis */
(void)SDL_snprintf(binding, sizeof(binding), "-a%d", event.jaxis.axis);
} else if (axis_min == 0 && axis_max == SDL_JOYSTICK_AXIS_MAX) {
/* The positive half axis */
(void)SDL_snprintf(binding, sizeof(binding), "+a%d", event.jaxis.axis);
} else {
(void)SDL_snprintf(binding, sizeof(binding), "a%d", event.jaxis.axis);
if (axis_min > axis_max) {
/* Invert the axis */
SDL_strlcat(binding, "~", SDL_arraysize(binding));
}
}
#ifdef DEBUG_AXIS_MAPPING
SDL_Log("AXIS %d axis_min = %d, axis_max = %d, binding = %s\n", event.jaxis.axis, axis_min, axis_max, binding);
#endif
CommitBindingElement(binding, false);
}
}
break;
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
if (display_mode == CONTROLLER_MODE_TESTING) {
SetController(event.jbutton.which);
}
break;
case SDL_EVENT_JOYSTICK_BUTTON_UP:
if (display_mode == CONTROLLER_MODE_BINDING &&
event.jbutton.which == controller->id &&
binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
char binding[12];
SDL_snprintf(binding, sizeof(binding), "b%d", event.jbutton.button);
CommitBindingElement(binding, false);
}
break;
case SDL_EVENT_JOYSTICK_HAT_MOTION:
if (display_mode == CONTROLLER_MODE_BINDING &&
event.jhat.which == controller->id &&
event.jhat.value != SDL_HAT_CENTERED &&
binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
char binding[12];
SDL_snprintf(binding, sizeof(binding), "h%d.%d", event.jhat.hat, event.jhat.value);
CommitBindingElement(binding, false);
}
break;
case SDL_EVENT_GAMEPAD_ADDED:
HandleGamepadAdded(event.gdevice.which, true);
break;
case SDL_EVENT_GAMEPAD_REMOVED:
HandleGamepadRemoved(event.gdevice.which);
break;
case SDL_EVENT_GAMEPAD_REMAPPED:
HandleGamepadRemapped(event.gdevice.which);
break;
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
RefreshControllerName();
break;
#ifdef VERBOSE_TOUCHPAD
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
SDL_Log("Gamepad %" SDL_PRIu32 " touchpad %" SDL_PRIs32 " finger %" SDL_PRIs32 " %s %.2f, %.2f, %.2f\n",
event.gtouchpad.which,
event.gtouchpad.touchpad,
event.gtouchpad.finger,
(event.type == SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN ? "pressed at" : (event.type == SDL_EVENT_GAMEPAD_TOUCHPAD_UP ? "released at" : "moved to")),
event.gtouchpad.x,
event.gtouchpad.y,
event.gtouchpad.pressure);
break;
#endif /* VERBOSE_TOUCHPAD */
#ifdef VERBOSE_SENSORS
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
SDL_Log("Gamepad %" SDL_PRIu32 " sensor %s: %.2f, %.2f, %.2f (%" SDL_PRIu64 ")\n",
event.gsensor.which,
GetSensorName((SDL_SensorType) event.gsensor.sensor),
event.gsensor.data[0],
event.gsensor.data[1],
event.gsensor.data[2],
event.gsensor.sensor_timestamp);
break;
#endif /* VERBOSE_SENSORS */
#ifdef VERBOSE_AXES
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event.gaxis.value <= (-SDL_JOYSTICK_AXIS_MAX / 2) || event.gaxis.value >= (SDL_JOYSTICK_AXIS_MAX / 2)) {
SetController(event.gaxis.which);
}
}
SDL_Log("Gamepad %" SDL_PRIu32 " axis %s changed to %d\n",
event.gaxis.which,
SDL_GetGamepadStringForAxis((SDL_GamepadAxis) event.gaxis.axis),
event.gaxis.value);
break;
#endif /* VERBOSE_AXES */
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
case SDL_EVENT_GAMEPAD_BUTTON_UP:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
SetController(event.gbutton.which);
}
}
#ifdef VERBOSE_BUTTONS
SDL_Log("Gamepad %" SDL_PRIu32 " button %s %s\n",
event.gbutton.which,
SDL_GetGamepadStringForButton((SDL_GamepadButton) event.gbutton.button),
event.gbutton.state ? "pressed" : "released");
#endif /* VERBOSE_BUTTONS */
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN &&
controller && SDL_GetGamepadType(controller->gamepad) == SDL_GAMEPAD_TYPE_PS5) {
/* Cycle PS5 audio routing when the microphone button is pressed */
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_MISC1) {
CyclePS5AudioRoute(controller);
}
/* Cycle PS5 trigger effects when the triangle button is pressed */
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_NORTH) {
CyclePS5TriggerEffect(controller);
}
}
}
break;
case SDL_EVENT_MOUSE_BUTTON_DOWN:
if (virtual_joystick && controller && controller->joystick == virtual_joystick) {
VirtualGamepadMouseDown(event.button.x, event.button.y);
}
UpdateButtonHighlights(event.button.x, event.button.y, event.button.down);
break;
case SDL_EVENT_MOUSE_BUTTON_UP:
if (virtual_joystick && controller && controller->joystick == virtual_joystick) {
VirtualGamepadMouseUp(event.button.x, event.button.y);
}
if (display_mode == CONTROLLER_MODE_TESTING) {
if (GamepadButtonContains(setup_mapping_button, event.button.x, event.button.y)) {
SetDisplayMode(CONTROLLER_MODE_BINDING);
}
} else if (display_mode == CONTROLLER_MODE_BINDING) {
if (GamepadButtonContains(done_mapping_button, event.button.x, event.button.y)) {
if (controller->mapping) {
SDL_Log("Mapping complete:\n");
SDL_Log("%s\n", controller->mapping);
}
SetDisplayMode(CONTROLLER_MODE_TESTING);
} else if (GamepadButtonContains(cancel_button, event.button.x, event.button.y)) {
CancelMapping();
} else if (GamepadButtonContains(clear_button, event.button.x, event.button.y)) {
ClearMapping();
} else if (controller->has_bindings &&
GamepadButtonContains(copy_button, event.button.x, event.button.y)) {
CopyMapping();
} else if (GamepadButtonContains(paste_button, event.button.x, event.button.y)) {
PasteMapping();
} else if (title_pressed) {
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_NAME, false);
} else if (type_pressed) {
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_TYPE, false);
} else if (binding_element == SDL_GAMEPAD_ELEMENT_TYPE) {
int type = GetGamepadTypeDisplayAt(gamepad_type, event.button.x, event.button.y);
if (type != SDL_GAMEPAD_TYPE_UNSELECTED) {
CommitGamepadType((SDL_GamepadType)type);
StopBinding();
}
} else {
int gamepad_element = SDL_GAMEPAD_ELEMENT_INVALID;
char *joystick_element;
if (controller->joystick != virtual_joystick) {
gamepad_element = GetGamepadImageElementAt(image, event.button.x, event.button.y);
}
if (gamepad_element == SDL_GAMEPAD_ELEMENT_INVALID) {
gamepad_element = GetGamepadDisplayElementAt(gamepad_elements, controller->gamepad, event.button.x, event.button.y);
}
if (gamepad_element != SDL_GAMEPAD_ELEMENT_INVALID) {
/* Set this to false if you don't want to start the binding flow at this point */
const bool should_start_flow = true;
SetCurrentBindingElement(gamepad_element, should_start_flow);
}
joystick_element = GetJoystickDisplayElementAt(joystick_elements, controller->joystick, event.button.x, event.button.y);
if (joystick_element) {
CommitBindingElement(joystick_element, true);
SDL_free(joystick_element);
}
}
}
UpdateButtonHighlights(event.button.x, event.button.y, event.button.down);
break;
case SDL_EVENT_MOUSE_MOTION:
if (virtual_joystick && controller && controller->joystick == virtual_joystick) {
VirtualGamepadMouseMotion(event.motion.x, event.motion.y);
}
UpdateButtonHighlights(event.motion.x, event.motion.y, event.motion.state ? true : false);
break;
case SDL_EVENT_KEY_DOWN:
if (display_mode == CONTROLLER_MODE_TESTING) {
if (event.key.key >= SDLK_0 && event.key.key <= SDLK_9) {
if (controller && controller->gamepad) {
int player_index = (event.key.key - SDLK_0);
SDL_SetGamepadPlayerIndex(controller->gamepad, player_index);
}
break;
} else if (event.key.key == SDLK_A) {
OpenVirtualGamepad();
} else if (event.key.key == SDLK_D) {
CloseVirtualGamepad();
} else if (event.key.key == SDLK_R && (event.key.mod & SDL_KMOD_CTRL)) {
SDL_ReloadGamepadMappings();
} else if (event.key.key == SDLK_ESCAPE) {
done = true;
}
} else if (display_mode == CONTROLLER_MODE_BINDING) {
if (event.key.key == SDLK_C && (event.key.mod & SDL_KMOD_CTRL)) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
CopyControllerName();
} else {
CopyMapping();
}
} else if (event.key.key == SDLK_V && (event.key.mod & SDL_KMOD_CTRL)) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
ClearControllerName();
PasteControllerName();
} else {
PasteMapping();
}
} else if (event.key.key == SDLK_X && (event.key.mod & SDL_KMOD_CTRL)) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
CopyControllerName();
ClearControllerName();
} else {
CopyMapping();
ClearMapping();
}
} else if (event.key.key == SDLK_SPACE) {
if (binding_element != SDL_GAMEPAD_ELEMENT_NAME) {
ClearBinding();
}
} else if (event.key.key == SDLK_BACKSPACE) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
BackspaceControllerName();
}
} else if (event.key.key == SDLK_RETURN) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
StopBinding();
}
} else if (event.key.key == SDLK_ESCAPE) {
if (binding_element != SDL_GAMEPAD_ELEMENT_INVALID) {
StopBinding();
} else {
CancelMapping();
}
}
}
break;
case SDL_EVENT_TEXT_INPUT:
if (display_mode == CONTROLLER_MODE_BINDING) {
if (binding_element == SDL_GAMEPAD_ELEMENT_NAME) {
AddControllerNameText(event.text.text);
}
}
break;
case SDL_EVENT_QUIT:
done = true;
break;
default:
break;
}
}
/* Wait 30 ms for joystick events to stop coming in,
in case a gamepad sends multiple events for a single control (e.g. axis and button for trigger)
*/
@@ -1978,14 +1985,10 @@ static void loop(void *arg)
SDL_Delay(16);
SDL_RenderPresent(screen);
#ifdef SDL_PLATFORM_EMSCRIPTEN
if (done) {
emscripten_cancel_main_loop();
}
#endif
return SDL_APP_CONTINUE;
}
int main(int argc, char *argv[])
SDL_AppResult SDLCALL SDL_AppInit(void **appstate, int argc, char *argv[])
{
bool show_mappings = false;
int i;
@@ -1993,17 +1996,15 @@ int main(int argc, char *argv[])
int screen_width, screen_height;
SDL_FRect area;
int gamepad_index = -1;
SDLTest_CommonState *state;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0);
if (!state) {
return 1;
return SDL_APP_FAILURE;
}
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "auto");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ROG_CHAKRAM, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
@@ -2035,7 +2036,7 @@ int main(int argc, char *argv[])
if (consumed <= 0) {
static const char *options[] = { "[--mappings]", "[--virtual]", "[index]", NULL };
SDLTest_CommonLogUsage(state, argv[0], options);
return 1;
return SDL_APP_FAILURE;
}
i += consumed;
@@ -2047,7 +2048,7 @@ int main(int argc, char *argv[])
/* Initialize SDL (Note: video is required to start event loop) */
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
return 1;
return SDL_APP_FAILURE;
}
SDL_AddGamepadMappingsFromFile("gamecontrollerdb.txt");
@@ -2074,14 +2075,14 @@ int main(int argc, char *argv[])
window = SDL_CreateWindow("SDL Controller Test", screen_width, screen_height, 0);
if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
return 2;
return SDL_APP_FAILURE;
}
screen = SDL_CreateRenderer(window, NULL);
if (!screen) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
return 2;
return SDL_APP_FAILURE;
}
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
@@ -2107,7 +2108,7 @@ int main(int argc, char *argv[])
if (!image) {
SDL_DestroyRenderer(screen);
SDL_DestroyWindow(window);
return 2;
return SDL_APP_FAILURE;
}
SetGamepadImagePosition(image, PANEL_WIDTH + PANEL_SPACING, TITLE_HEIGHT);
@@ -2175,7 +2176,7 @@ int main(int argc, char *argv[])
SetGamepadButtonArea(done_mapping_button, &area);
/* Process the initial gamepad list */
loop(NULL);
SDL_AppIterate(NULL);
if (gamepad_index < num_controllers) {
SetController(controllers[gamepad_index].id);
@@ -2183,15 +2184,11 @@ int main(int argc, char *argv[])
SetController(controllers[0].id);
}
/* Loop, getting gamepad events! */
#ifdef SDL_PLATFORM_EMSCRIPTEN
emscripten_set_main_loop_arg(loop, NULL, 0, 1);
#else
while (!done) {
loop(NULL);
}
#endif
return SDL_APP_CONTINUE;
}
void SDLCALL SDL_AppQuit(void *appstate, SDL_AppResult result)
{
CloseVirtualGamepad();
while (num_controllers > 0) {
HandleGamepadRemoved(controllers[0].id);
@@ -2214,5 +2211,4 @@ int main(int argc, char *argv[])
SDL_DestroyWindow(window);
SDL_Quit();
SDLTest_CommonDestroyState(state);
return 0;
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+2 -2
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2020-2022 Collabora Ltd.
This software is provided 'as-is', without any express or implied
@@ -21,7 +21,7 @@
#endif
#define SDL_DYNAMIC_API 0
#ifndef NO_BUILD_CONFIG
#ifdef HAVE_BUILD_CONFIG
#include "../src/SDL_internal.h"
#endif
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+120 -11
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -20,14 +20,7 @@ static SDL_EnumerationResult SDLCALL enum_callback(void *userdata, const char *o
SDL_PathInfo info;
char *fullpath = NULL;
/* you can use '/' for a path separator on Windows, but to make the log output look correct, we'll #ifdef this... */
#ifdef SDL_PLATFORM_WINDOWS
const char *pathsep = "\\";
#else
const char *pathsep = "/";
#endif
if (SDL_asprintf(&fullpath, "%s%s%s", origdir, *origdir ? pathsep : "", fname) < 0) {
if (SDL_asprintf(&fullpath, "%s%s", origdir, fname) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!");
return SDL_ENUM_FAILURE;
}
@@ -43,7 +36,7 @@ static SDL_EnumerationResult SDLCALL enum_callback(void *userdata, const char *o
} else {
type = "OTHER";
}
SDL_Log("%s (type=%s, size=%" SDL_PRIu64 ", create=%" SDL_PRIu64 ", mod=%" SDL_PRIu64 ", access=%" SDL_PRIu64 ")",
SDL_Log("DIRECTORY %s (type=%s, size=%" SDL_PRIu64 ", create=%" SDL_PRIu64 ", mod=%" SDL_PRIu64 ", access=%" SDL_PRIu64 ")",
fullpath, type, info.size, info.modify_time, info.create_time, info.access_time);
if (info.type == SDL_PATHTYPE_DIRECTORY) {
@@ -58,6 +51,42 @@ static SDL_EnumerationResult SDLCALL enum_callback(void *userdata, const char *o
}
static SDL_EnumerationResult SDLCALL enum_storage_callback(void *userdata, const char *origdir, const char *fname)
{
SDL_Storage *storage = (SDL_Storage *) userdata;
SDL_PathInfo info;
char *fullpath = NULL;
if (SDL_asprintf(&fullpath, "%s%s", origdir, fname) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!");
return SDL_ENUM_FAILURE;
}
if (!SDL_GetStoragePathInfo(storage, fullpath, &info)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't stat '%s': %s", fullpath, SDL_GetError());
} else {
const char *type;
if (info.type == SDL_PATHTYPE_FILE) {
type = "FILE";
} else if (info.type == SDL_PATHTYPE_DIRECTORY) {
type = "DIRECTORY";
} else {
type = "OTHER";
}
SDL_Log("STORAGE %s (type=%s, size=%" SDL_PRIu64 ", create=%" SDL_PRIu64 ", mod=%" SDL_PRIu64 ", access=%" SDL_PRIu64 ")",
fullpath, type, info.size, info.modify_time, info.create_time, info.access_time);
if (info.type == SDL_PATHTYPE_DIRECTORY) {
if (!SDL_EnumerateStorageDirectory(storage, fullpath, enum_storage_callback, userdata)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Enumeration failed!");
}
}
}
SDL_free(fullpath);
return SDL_ENUM_CONTINUE; /* keep going */
}
int main(int argc, char *argv[])
{
SDLTest_CommonState *state;
@@ -118,8 +147,10 @@ int main(int argc, char *argv[])
if (base_path) {
char **globlist;
SDL_Storage *storage = NULL;
SDL_IOStream *stream;
const char *text = "foo\n";
SDL_PathInfo pathinfo;
if (!SDL_EnumerateDirectory(base_path, enum_callback, NULL)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path enumeration failed!");
@@ -131,7 +162,7 @@ int main(int argc, char *argv[])
} else {
int i;
for (i = 0; globlist[i]; i++) {
SDL_Log("GLOB[%d]: '%s'", i, globlist[i]);
SDL_Log("DIRECTORY GLOB[%d]: '%s'", i, globlist[i]);
}
SDL_free(globlist);
}
@@ -198,6 +229,84 @@ int main(int argc, char *argv[])
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_IOFromFile('testfilesystem-A', 'w') failed: %s", SDL_GetError());
}
storage = SDL_OpenFileStorage(base_path);
if (!storage) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open base path storage object: %s", SDL_GetError());
} else {
if (!SDL_EnumerateStorageDirectory(storage, "CMakeFiles", enum_storage_callback, storage)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Storage Base path enumeration failed!");
}
globlist = SDL_GlobStorageDirectory(storage, "", "C*/test*/T?st*", SDL_GLOB_CASEINSENSITIVE, NULL);
if (!globlist) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path globbing failed!");
} else {
int i;
for (i = 0; globlist[i]; i++) {
SDL_Log("STORAGE GLOB[%d]: '%s'", i, globlist[i]);
}
SDL_free(globlist);
}
/* these should fail: */
if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/../testsprite.c", &pathinfo)) {
SDL_Log("Storage access on path with internal '..' refused correctly.");
} else {
SDL_Log("Storage access on path with internal '..' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/./TargetDirectories.txt", &pathinfo)) {
SDL_Log("Storage access on path with internal '.' refused correctly.");
} else {
SDL_Log("Storage access on path with internal '.' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "../test", &pathinfo)) {
SDL_Log("Storage access on path with leading '..' refused correctly.");
} else {
SDL_Log("Storage access on path with leading '..' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "./CMakeFiles", &pathinfo)) {
SDL_Log("Storage access on path with leading '.' refused correctly.");
} else {
SDL_Log("Storage access on path with leading '.' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/..", &pathinfo)) {
SDL_Log("Storage access on path with trailing '..' refused correctly.");
} else {
SDL_Log("Storage access on path with trailing '..' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/.", &pathinfo)) {
SDL_Log("Storage access on path with trailing '.' refused correctly.");
} else {
SDL_Log("Storage access on path with trailing '.' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "..", &pathinfo)) {
SDL_Log("Storage access on path '..' refused correctly.");
} else {
SDL_Log("Storage access on path '..' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, ".", &pathinfo)) {
SDL_Log("Storage access on path '.' refused correctly.");
} else {
SDL_Log("Storage access on path '.' accepted INCORRECTLY.");
}
if (!SDL_GetStoragePathInfo(storage, "CMakeFiles\\TargetDirectories.txt", &pathinfo)) {
SDL_Log("Storage access on path with Windows separator refused correctly.");
} else {
SDL_Log("Storage access on path with Windows separator accepted INCORRECTLY.");
}
SDL_CloseStorage(storage);
}
}
SDL_Quit();
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+9 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -263,6 +263,9 @@ int main(int argc, char *argv[])
state->gl_green_size = 5;
state->gl_blue_size = 5;
state->gl_depth_size = 16;
/* For release_behavior to work, at least on Windows, you'll most likely need to set state->gl_major_version = 3 */
/* state->gl_major_version = 3; */
state->gl_release_behavior = 0;
state->gl_double_buffer = 1;
if (fsaa) {
state->gl_multisamplebuffers = 1;
@@ -331,6 +334,11 @@ int main(int argc, char *argv[])
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError());
}
if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_RELEASE_BEHAVIOR, &value)) {
SDL_Log("SDL_GL_CONTEXT_RELEASE_BEHAVIOR: requested %d, got %d\n", 0, value);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_CONTEXT_RELEASE_BEHAVIOR: %s\n", SDL_GetError());
}
if (fsaa) {
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value)) {
SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+7 -5
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -538,23 +538,25 @@ init_render_state(int msaa)
buffer_desc.usage = SDL_GPU_BUFFERUSAGE_VERTEX;
buffer_desc.size = sizeof(vertex_data);
buffer_desc.props = 0;
buffer_desc.props = SDL_CreateProperties();
SDL_SetStringProperty(buffer_desc.props, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "космонавт");
render_state.buf_vertex = SDL_CreateGPUBuffer(
gpu_device,
&buffer_desc
);
CHECK_CREATE(render_state.buf_vertex, "Static vertex buffer")
SDL_SetGPUBufferName(gpu_device, render_state.buf_vertex, "космонавт");
SDL_DestroyProperties(buffer_desc.props);
transfer_buffer_desc.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
transfer_buffer_desc.size = sizeof(vertex_data);
transfer_buffer_desc.props = 0;
transfer_buffer_desc.props = SDL_CreateProperties();
SDL_SetStringProperty(transfer_buffer_desc.props, SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING, "Transfer Buffer");
buf_transfer = SDL_CreateGPUTransferBuffer(
gpu_device,
&transfer_buffer_desc
);
CHECK_CREATE(buf_transfer, "Vertex transfer buffer")
SDL_DestroyProperties(transfer_buffer_desc.props);
/* We just need to upload the static data once. */
map = SDL_MapGPUTransferBuffer(gpu_device, buf_transfer, false);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+6 -2
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -11,13 +11,17 @@
*/
/* Simple test of the SDL MessageBox API */
#include <stdlib.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
/* This enables themed Windows dialogs when building with Visual Studio */
#if defined(SDL_PLATFORM_WINDOWS) && defined(_MSC_VER)
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+3 -3
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -180,8 +180,8 @@ static int TestEndian(bool verbose)
static int TST_allmul(void *a, void *b, int arg, void *result, void *expected)
{
(*(long long *)result) = ((*(long long *)a) * (*(long long *)b));
return (*(long long *)result) == (*(long long *)expected);
(*(unsigned long long *)result) = ((*(unsigned long long *)a) * (*(unsigned long long *)b));
return (*(unsigned long long *)result) == (*(unsigned long long *)expected);
}
static int TST_alldiv(void *a, void *b, int arg, void *result, void *expected)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+49 -3
View File
@@ -9,6 +9,18 @@ static void SDLCALL tray_quit(void *ptr, SDL_TrayEntry *entry)
SDL_PushEvent(&e);
}
static bool trays_destroyed = false;
static void SDLCALL tray_close(void *ptr, SDL_TrayEntry *entry)
{
SDL_Tray **trays = (SDL_Tray **) ptr;
trays_destroyed = true;
SDL_DestroyTray(trays[0]);
SDL_DestroyTray(trays[1]);
}
static void SDLCALL apply_icon(void *ptr, const char * const *filelist, int filter)
{
if (!*filelist) {
@@ -471,6 +483,7 @@ static void SDLCALL append_submenu_to(void *ptr, SDL_TrayEntry *entry)
int main(int argc, char **argv)
{
SDL_Tray **trays = NULL;
SDLTest_CommonState *state;
int i;
@@ -500,6 +513,13 @@ int main(int argc, char **argv)
return 1;
}
SDL_Window *w = SDL_CreateWindow("testtray", 640, 480, 0);
if (!w) {
SDL_Log("Couldn't create window: %s", SDL_GetError());
goto quit;
}
/* TODO: Resource paths? */
SDL_Surface *icon = SDL_LoadBMP("../test/sdl-test_round.bmp");
@@ -517,7 +537,7 @@ int main(int argc, char **argv)
if (!tray) {
SDL_Log("Couldn't create control tray: %s", SDL_GetError());
goto quit;
goto clean_window;
}
SDL_Tray *tray2 = SDL_CreateTray(icon2, "SDL Tray example");
@@ -545,7 +565,20 @@ int main(int argc, char **argv)
SDL_TrayEntry *entry_quit = SDL_InsertTrayEntryAt(menu, -1, "Quit", SDL_TRAYENTRY_BUTTON);
CHECK(entry_quit);
SDL_TrayEntry *entry_close = SDL_InsertTrayEntryAt(menu, -1, "Close", SDL_TRAYENTRY_BUTTON);
CHECK(entry_close);
/* TODO: Track memory! */
trays = SDL_malloc(sizeof(SDL_Tray *) * 2);
if (!trays) {
goto clean_all;
}
trays[0] = tray;
trays[1] = tray2;
SDL_SetTrayEntryCallback(entry_quit, tray_quit, NULL);
SDL_SetTrayEntryCallback(entry_close, tray_close, trays);
SDL_InsertTrayEntryAt(menu, -1, NULL, 0);
@@ -582,14 +615,27 @@ int main(int argc, char **argv)
while (SDL_WaitEvent(&e)) {
if (e.type == SDL_EVENT_QUIT) {
break;
} else if (e.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED) {
SDL_DestroyWindow(w);
w = NULL;
}
}
clean_all:
SDL_DestroyTray(tray2);
if (!trays_destroyed) {
SDL_DestroyTray(tray2);
}
clean_tray1:
SDL_DestroyTray(tray);
if (!trays_destroyed) {
SDL_DestroyTray(tray);
}
SDL_free(trays);
clean_window:
if (w) {
SDL_DestroyWindow(w);
}
quit:
SDL_Quit();
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

Some files were not shown because too many files have changed in this diff Show More