From 6aaedb813fa11ba0679c3051bc2eb28646b9506c Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 30 Aug 2025 16:53:58 -0700 Subject: Update to SDL3 --- src/contrib/SDL-3.2.20/examples/CMakeLists.txt | 382 ++++++++++++++++ src/contrib/SDL-3.2.20/examples/README.md | 67 +++ .../examples/asyncio/01-load-bitmaps/README.txt | 6 + .../asyncio/01-load-bitmaps/load-bitmaps.c | 125 ++++++ .../examples/asyncio/01-load-bitmaps/thumbnail.png | Bin 0 -> 76234 bytes .../SDL-3.2.20/examples/asyncio/description.txt | 1 + .../examples/audio/01-simple-playback/README.txt | 5 + .../audio/01-simple-playback/simple-playback.c | 103 +++++ .../audio/02-simple-playback-callback/README.txt | 5 + .../simple-playback-callback.c | 115 +++++ .../examples/audio/03-load-wav/README.txt | 5 + .../examples/audio/03-load-wav/load-wav.c | 103 +++++ .../examples/audio/04-multiple-streams/README.txt | 5 + .../audio/04-multiple-streams/multiple-streams.c | 135 ++++++ .../SDL-3.2.20/examples/audio/onmouseover.webp | Bin 0 -> 176470 bytes .../SDL-3.2.20/examples/audio/thumbnail.png | Bin 0 -> 14221 bytes .../examples/camera/01-read-and-draw/README.txt | 1 + .../camera/01-read-and-draw/onmouseover.webp | Bin 0 -> 346856 bytes .../camera/01-read-and-draw/read-and-draw.c | 113 +++++ .../examples/camera/01-read-and-draw/thumbnail.png | Bin 0 -> 239597 bytes src/contrib/SDL-3.2.20/examples/categories.txt | 13 + .../SDL-3.2.20/examples/demo/01-snake/README.txt | 1 + .../examples/demo/01-snake/onmouseover.webp | Bin 0 -> 30996 bytes .../SDL-3.2.20/examples/demo/01-snake/snake.c | 350 +++++++++++++++ .../examples/demo/01-snake/thumbnail.png | Bin 0 -> 2958 bytes .../examples/demo/02-woodeneye-008/README.txt | 1 + .../demo/02-woodeneye-008/onmouseover.webp | Bin 0 -> 468022 bytes .../examples/demo/02-woodeneye-008/thumbnail.png | Bin 0 -> 25191 bytes .../examples/demo/02-woodeneye-008/woodeneye-008.c | 480 +++++++++++++++++++++ .../examples/demo/03-infinite-monkeys/README.txt | 7 + .../demo/03-infinite-monkeys/infinite-monkeys.c | 377 ++++++++++++++++ .../demo/03-infinite-monkeys/onmouseover.webp | Bin 0 -> 95578 bytes .../demo/03-infinite-monkeys/thumbnail.png | Bin 0 -> 7740 bytes .../examples/demo/04-bytepusher/README.txt | 4 + .../examples/demo/04-bytepusher/bytepusher.c | 416 ++++++++++++++++++ .../examples/demo/04-bytepusher/onmouseover.webp | Bin 0 -> 430096 bytes .../examples/demo/04-bytepusher/thumbnail.png | Bin 0 -> 23851 bytes .../SDL-3.2.20/examples/demo/description.txt | 1 + .../SDL-3.2.20/examples/highlight-plugin.lua | 79 ++++ .../examples/input/01-joystick-polling/README.txt | 2 + .../input/01-joystick-polling/joystick-polling.c | 193 +++++++++ .../input/01-joystick-polling/onmouseover.webp | Bin 0 -> 47840 bytes .../input/01-joystick-polling/thumbnail.png | Bin 0 -> 5940 bytes .../examples/input/02-joystick-events/README.txt | 2 + .../input/02-joystick-events/joystick-events.c | 232 ++++++++++ .../input/02-joystick-events/onmouseover.webp | Bin 0 -> 2302260 bytes .../input/02-joystick-events/thumbnail.png | Bin 0 -> 30785 bytes .../examples/pen/01-drawing-lines/README.txt | 3 + .../examples/pen/01-drawing-lines/drawing-lines.c | 121 ++++++ .../examples/pen/01-drawing-lines/onmouseover.webp | Bin 0 -> 28346 bytes .../examples/pen/01-drawing-lines/thumbnail.png | Bin 0 -> 2042 bytes .../examples/renderer/01-clear/README.txt | 3 + .../SDL-3.2.20/examples/renderer/01-clear/clear.c | 68 +++ .../examples/renderer/01-clear/onmouseover.webp | Bin 0 -> 69392 bytes .../examples/renderer/01-clear/thumbnail.png | Bin 0 -> 2070 bytes .../examples/renderer/02-primitives/README.txt | 7 + .../examples/renderer/02-primitives/primitives.c | 95 ++++ .../examples/renderer/02-primitives/thumbnail.png | Bin 0 -> 8761 bytes .../examples/renderer/03-lines/README.txt | 3 + .../SDL-3.2.20/examples/renderer/03-lines/lines.c | 93 ++++ .../examples/renderer/03-lines/onmouseover.webp | Bin 0 -> 66034 bytes .../examples/renderer/03-lines/thumbnail.png | Bin 0 -> 28130 bytes .../examples/renderer/04-points/README.txt | 3 + .../examples/renderer/04-points/onmouseover.webp | Bin 0 -> 155796 bytes .../examples/renderer/04-points/points.c | 118 +++++ .../examples/renderer/04-points/thumbnail.png | Bin 0 -> 8114 bytes .../examples/renderer/05-rectangles/README.txt | 3 + .../renderer/05-rectangles/onmouseover.webp | Bin 0 -> 75754 bytes .../examples/renderer/05-rectangles/rectangles.c | 112 +++++ .../examples/renderer/05-rectangles/thumbnail.png | Bin 0 -> 3634 bytes .../examples/renderer/06-textures/README.txt | 3 + .../examples/renderer/06-textures/onmouseover.webp | Bin 0 -> 605954 bytes .../examples/renderer/06-textures/textures.c | 127 ++++++ .../examples/renderer/06-textures/thumbnail.png | Bin 0 -> 238654 bytes .../renderer/07-streaming-textures/README.txt | 3 + .../07-streaming-textures/onmouseover.webp | Bin 0 -> 17160 bytes .../07-streaming-textures/streaming-textures.c | 109 +++++ .../renderer/07-streaming-textures/thumbnail.png | Bin 0 -> 3552 bytes .../renderer/08-rotating-textures/README.txt | 3 + .../renderer/08-rotating-textures/onmouseover.webp | Bin 0 -> 312998 bytes .../08-rotating-textures/rotating-textures.c | 113 +++++ .../renderer/08-rotating-textures/thumbnail.png | Bin 0 -> 91098 bytes .../renderer/09-scaling-textures/README.txt | 3 + .../renderer/09-scaling-textures/onmouseover.webp | Bin 0 -> 318914 bytes .../09-scaling-textures/scaling-textures.c | 110 +++++ .../renderer/09-scaling-textures/thumbnail.png | Bin 0 -> 83431 bytes .../examples/renderer/10-geometry/README.txt | 3 + .../examples/renderer/10-geometry/geometry.c | 166 +++++++ .../examples/renderer/10-geometry/onmouseover.webp | Bin 0 -> 119254 bytes .../examples/renderer/10-geometry/thumbnail.png | Bin 0 -> 57164 bytes .../examples/renderer/11-color-mods/README.txt | 3 + .../examples/renderer/11-color-mods/color-mods.c | 134 ++++++ .../renderer/11-color-mods/onmouseover.webp | Bin 0 -> 278286 bytes .../examples/renderer/11-color-mods/thumbnail.png | Bin 0 -> 122439 bytes .../examples/renderer/14-viewport/README.txt | 4 + .../examples/renderer/14-viewport/thumbnail.png | Bin 0 -> 146306 bytes .../examples/renderer/14-viewport/viewport.c | 136 ++++++ .../examples/renderer/15-cliprect/README.txt | 5 + .../examples/renderer/15-cliprect/cliprect.c | 137 ++++++ .../examples/renderer/15-cliprect/onmouseover.webp | Bin 0 -> 260400 bytes .../examples/renderer/15-cliprect/thumbnail.png | Bin 0 -> 87025 bytes .../examples/renderer/17-read-pixels/README.txt | 12 + .../renderer/17-read-pixels/onmouseover.webp | Bin 0 -> 482380 bytes .../examples/renderer/17-read-pixels/read-pixels.c | 178 ++++++++ .../examples/renderer/17-read-pixels/thumbnail.png | Bin 0 -> 102838 bytes .../examples/renderer/18-debug-text/README.txt | 4 + .../examples/renderer/18-debug-text/debug-text.c | 80 ++++ .../examples/renderer/18-debug-text/thumbnail.png | Bin 0 -> 4344 bytes .../SDL-3.2.20/examples/template-category.html | 41 ++ .../SDL-3.2.20/examples/template-homepage.html | 41 ++ .../SDL-3.2.20/examples/template-placeholder.png | Bin 0 -> 34957 bytes src/contrib/SDL-3.2.20/examples/template.c | 53 +++ src/contrib/SDL-3.2.20/examples/template.css | 284 ++++++++++++ src/contrib/SDL-3.2.20/examples/template.html | 292 +++++++++++++ 114 files changed, 6002 insertions(+) create mode 100644 src/contrib/SDL-3.2.20/examples/CMakeLists.txt create mode 100644 src/contrib/SDL-3.2.20/examples/README.md create mode 100644 src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/load-bitmaps.c create mode 100644 src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/asyncio/description.txt create mode 100644 src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/simple-playback.c create mode 100644 src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/simple-playback-callback.c create mode 100644 src/contrib/SDL-3.2.20/examples/audio/03-load-wav/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/audio/03-load-wav/load-wav.c create mode 100644 src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/multiple-streams.c create mode 100644 src/contrib/SDL-3.2.20/examples/audio/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/audio/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/read-and-draw.c create mode 100644 src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/categories.txt create mode 100644 src/contrib/SDL-3.2.20/examples/demo/01-snake/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/demo/01-snake/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/demo/01-snake/snake.c create mode 100644 src/contrib/SDL-3.2.20/examples/demo/01-snake/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c create mode 100644 src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/infinite-monkeys.c create mode 100644 src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/bytepusher.c create mode 100644 src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/demo/description.txt create mode 100644 src/contrib/SDL-3.2.20/examples/highlight-plugin.lua create mode 100644 src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/joystick-polling.c create mode 100644 src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/input/02-joystick-events/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/input/02-joystick-events/joystick-events.c create mode 100644 src/contrib/SDL-3.2.20/examples/input/02-joystick-events/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/input/02-joystick-events/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/drawing-lines.c create mode 100644 src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/01-clear/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/01-clear/clear.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/01-clear/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/01-clear/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/02-primitives/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/02-primitives/primitives.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/02-primitives/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/03-lines/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/03-lines/lines.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/03-lines/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/03-lines/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/04-points/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/04-points/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/04-points/points.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/04-points/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/rectangles.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/06-textures/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/06-textures/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/06-textures/textures.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/06-textures/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/streaming-textures.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/rotating-textures.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/scaling-textures.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/10-geometry/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/10-geometry/geometry.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/10-geometry/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/10-geometry/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/color-mods.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/14-viewport/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/14-viewport/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/14-viewport/viewport.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/cliprect.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/onmouseover.webp create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/read-pixels.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/README.txt create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/debug-text.c create mode 100644 src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/thumbnail.png create mode 100644 src/contrib/SDL-3.2.20/examples/template-category.html create mode 100644 src/contrib/SDL-3.2.20/examples/template-homepage.html create mode 100644 src/contrib/SDL-3.2.20/examples/template-placeholder.png create mode 100644 src/contrib/SDL-3.2.20/examples/template.c create mode 100644 src/contrib/SDL-3.2.20/examples/template.css create mode 100644 src/contrib/SDL-3.2.20/examples/template.html (limited to 'src/contrib/SDL-3.2.20/examples') diff --git a/src/contrib/SDL-3.2.20/examples/CMakeLists.txt b/src/contrib/SDL-3.2.20/examples/CMakeLists.txt new file mode 100644 index 0000000..2a13a03 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/CMakeLists.txt @@ -0,0 +1,382 @@ +# +# CMake script for building the SDL examples +# + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake") + +include(CheckIncludeFile) +include(CheckStructHasMember) +include(CMakePushCheckState) +include(sdlcompilers) + +if(SDL_EXAMPLES_LINK_SHARED) + set(sdl_name_component SDL3-shared) +else() + set(sdl_name_component SDL3-static) +endif() +set(HAVE_EXAMPLES_LINK_SHARED "${SDL_EXAMPLES_LINK_SHARED}" PARENT_SCOPE) + +# CMake incorrectly detects opengl32.lib being present on MSVC ARM64 +if(NOT (MSVC AND SDL_CPU_ARM64)) + # Prefer GLVND, if present + set(OpenGL_GL_PREFERENCE GLVND) + find_package(OpenGL) +endif() + +set(SDL_EXAMPLE_EXECUTABLES) + +if(CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(example_bin_dir "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + if(NOT IS_ABSOLUTE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + set(example_bin_dir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + endif() +else() + set(example_bin_dir "${CMAKE_CURRENT_BINARY_DIR}") +endif() +if(NOT CMAKE_VERSION VERSION_LESS 3.20) + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + set(example_bin_dir "${example_bin_dir}$<$:/$>") +endif() + +file(GLOB RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/*.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/*.wav ${CMAKE_CURRENT_SOURCE_DIR}/../test/*.hex) + +set(RESOURCE_FILE_NAMES) +set(RESOURCE_FILES_BINDIR) +foreach(resource_file IN LISTS RESOURCE_FILES) + get_filename_component(res_file_name ${resource_file} NAME) + list(APPEND RESOURCE_FILE_NAMES "${res_file_name}") + set(resource_file_bindir "${example_bin_dir}/${res_file_name}") + add_custom_command(OUTPUT "${resource_file_bindir}" + COMMAND "${CMAKE_COMMAND}" -E copy "${resource_file}" "${resource_file_bindir}" + DEPENDS "${resource_file}" + ) + list(APPEND RESOURCE_FILES_BINDIR "${resource_file_bindir}") +endforeach() +add_custom_target(copy-sdl-example-resources + DEPENDS "${RESOURCE_FILES_BINDIR}" +) + +macro(add_sdl_example_executable TARGET) + cmake_parse_arguments(AST "BUILD_DEPENDENT" "" "SOURCES;DATAFILES" ${ARGN}) + if(AST_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}") + endif() + if(NOT AST_SOURCES) + message(FATAL_ERROR "add_sdl_example_executable needs at least one source") + endif() + set(EXTRA_SOURCES "") + if(AST_DATAFILES) + list(APPEND EXTRA_SOURCES ${DATAFILES}) + endif() + if(ANDROID) + add_library(${TARGET} SHARED ${AST_SOURCES} ${EXTRA_SOURCES}) + else() + add_executable(${TARGET} ${AST_SOURCES} ${EXTRA_SOURCES}) + endif() + SDL_AddCommonCompilerFlags(${TARGET}) + target_include_directories(${TARGET} PRIVATE "${SDL3_SOURCE_DIR}/src/video/khronos") + target_link_libraries(${TARGET} PRIVATE SDL3::${sdl_name_component}) + + list(APPEND SDL_EXAMPLE_EXECUTABLES ${TARGET}) + if(AST_DATAFILES) + if(PSP OR PS2) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E make_directory $/sdl-${TARGET} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${AST_DATAFILES} $/sdl-${TARGET} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + else() + add_dependencies(${TARGET} copy-sdl-example-resources) + endif() + if(APPLE) + # Make sure resource files get installed into macOS/iOS .app bundles. + set_target_properties(${TARGET} PROPERTIES RESOURCE "${AST_DATAFILES}") + endif() + if(EMSCRIPTEN) + foreach(res IN LISTS AST_DATAFILES) + get_filename_component(res_name "${res}" NAME) + target_link_options(${TARGET} PRIVATE "SHELL:--embed-file ${res}@${res_name}") + endforeach() + endif() + set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$/$$/>") + endif() + + if(WINDOWS) + # CET support was added in VS 16.7 + if(MSVC_VERSION GREATER 1926 AND CMAKE_GENERATOR_PLATFORM MATCHES "Win32|x64") + set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -CETCOMPAT") + endif() + elseif(PSP) + target_link_libraries(${TARGET} PRIVATE GL) + elseif(EMSCRIPTEN) + set_property(TARGET ${TARGET} PROPERTY SUFFIX ".html") + target_link_options(${TARGET} PRIVATE -sALLOW_MEMORY_GROWTH=1) + endif() + + if(OPENGL_FOUND) + target_compile_definitions(${TARGET} PRIVATE HAVE_OPENGL) + endif() + + # FIXME: only add "${SDL3_BINARY_DIR}/include-config-$>" + include paths of external dependencies + target_include_directories(${TARGET} PRIVATE "$") +endmacro() + +add_sdl_example_executable(renderer-clear SOURCES renderer/01-clear/clear.c) +add_sdl_example_executable(renderer-primitives SOURCES renderer/02-primitives/primitives.c) +add_sdl_example_executable(renderer-lines SOURCES renderer/03-lines/lines.c) +add_sdl_example_executable(renderer-points SOURCES renderer/04-points/points.c) +add_sdl_example_executable(renderer-rectangles SOURCES renderer/05-rectangles/rectangles.c) +add_sdl_example_executable(renderer-textures SOURCES renderer/06-textures/textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-streaming-textures SOURCES renderer/07-streaming-textures/streaming-textures.c) +add_sdl_example_executable(renderer-rotating-textures SOURCES renderer/08-rotating-textures/rotating-textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-scaling-textures SOURCES renderer/09-scaling-textures/scaling-textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-geometry SOURCES renderer/10-geometry/geometry.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-color-mods SOURCES renderer/11-color-mods/color-mods.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-viewport SOURCES renderer/14-viewport/viewport.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-cliprect SOURCES renderer/15-cliprect/cliprect.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-read-pixels SOURCES renderer/17-read-pixels/read-pixels.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp) +add_sdl_example_executable(renderer-debug-text SOURCES renderer/18-debug-text/debug-text.c) +add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c) +add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c) +add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav) +add_sdl_example_executable(audio-multiple-streams SOURCES audio/04-multiple-streams/multiple-streams.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav ${CMAKE_CURRENT_SOURCE_DIR}/../test/sword.wav) +add_sdl_example_executable(input-joystick-polling SOURCES input/01-joystick-polling/joystick-polling.c) +add_sdl_example_executable(input-joystick-events SOURCES input/02-joystick-events/joystick-events.c) +add_sdl_example_executable(camera-read-and-draw SOURCES camera/01-read-and-draw/read-and-draw.c) +add_sdl_example_executable(pen-drawing-lines SOURCES pen/01-drawing-lines/drawing-lines.c) +add_sdl_example_executable(asyncio-load-bitmaps SOURCES asyncio/01-load-bitmaps/load-bitmaps.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/gamepad_front.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/speaker.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/icon2x.bmp) +add_sdl_example_executable(demo-snake SOURCES demo/01-snake/snake.c) +add_sdl_example_executable(demo-woodeneye-008 SOURCES demo/02-woodeneye-008/woodeneye-008.c) +add_sdl_example_executable(demo-infinite-monkeys SOURCES demo/03-infinite-monkeys/infinite-monkeys.c) +add_sdl_example_executable(demo-bytepusher SOURCES demo/04-bytepusher/bytepusher.c) + +# When you add an example, remember to add the Visual Studio project as well: +# - Add a new example in examples/ +# - Run python VisualC/examples/generate.py +# - Take note of the newly generated .vcxproj files +# - Modify the .vcxproj files if necessary (adding content such as BMP or WAV files) +# - Open VisualC/SDL.sln in Visual Studio or JetBrains Rider +# - Locate the appropriate folder in the Solution Explorer +# - Add the newly generated projects: Right click -> Add -> Existing project... +# - Test if they work +# - Save the SDL.sln solution + +if(PSP) + # Build EBOOT files if building for PSP + foreach(APP ${SDL_EXAMPLE_EXECUTABLES}) + create_pbp_file( + TARGET ${APP} + TITLE SDL-${APP} + ICON_PATH NULL + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + OUTPUT_DIR $/sdl-${APP} + ) + endforeach() +endif() + +if(N3DS) + set(ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/romfs") + file(MAKE_DIRECTORY "${ROMFS_DIR}") + file(COPY ${RESOURCE_FILES} DESTINATION "${ROMFS_DIR}") + + foreach(APP ${SDL_EXAMPLE_EXECUTABLES}) + get_target_property(TARGET_BINARY_DIR ${APP} BINARY_DIR) + set(SMDH_FILE "${TARGET_BINARY_DIR}/${APP}.smdh") + ctr_generate_smdh("${SMDH_FILE}" + NAME "SDL-${APP}" + DESCRIPTION "SDL3 Test suite" + AUTHOR "SDL3 Contributors" + ICON "${CMAKE_CURRENT_SOURCE_DIR}/../test/n3ds/logo48x48.png" + ) + ctr_create_3dsx( + ${APP} + ROMFS "${ROMFS_DIR}" + SMDH "${SMDH_FILE}" + ) + endforeach() +endif() + +if(RISCOS) + set(SDL_EXAMPLE_EXECUTABLES_AIF) + foreach(APP ${SDL_EXAMPLE_EXECUTABLES}) + set_property(TARGET ${APP} APPEND_STRING PROPERTY LINK_FLAGS " -static") + add_custom_command( + OUTPUT ${APP},ff8 + COMMAND elf2aif ${APP} ${APP},ff8 + DEPENDS ${APP} + ) + add_custom_target(${APP}-aif ALL DEPENDS ${APP},ff8) + list(APPEND SDL_EXAMPLE_EXECUTABLES_AIF ${CMAKE_CURRENT_BINARY_DIR}/${APP},ff8) + endforeach() +endif() + +# Set Apple App ID / Bundle ID. This is needed to launch apps on some Apple +# platforms (iOS, for example). +if(APPLE) + foreach(CURRENT_TARGET ${SDL_EXAMPLE_EXECUTABLES}) + set_target_properties("${CURRENT_TARGET}" PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER "org.libsdl.${CURRENT_TARGET}" + MACOSX_BUNDLE_BUNDLE_VERSION "${SDL3_VERSION}" + MACOSX_BUNDLE_SHORT_VERSION_STRING "${SDL3_VERSION}" + ) + endforeach() +endif() + +if(SDL_INSTALL_EXAMPLES) + if(RISCOS) + install( + FILES ${SDL_EXAMPLE_EXECUTABLES_AIF} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3 + ) + else() + install( + TARGETS ${SDL_EXAMPLE_EXECUTABLES} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3 + ) + endif() + if(MSVC) + foreach(example IN LISTS SDL_EXAMPLE_EXECUTABLES) + SDL_install_pdb(${example} "${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3") + endforeach() + endif() + install( + FILES ${RESOURCE_FILES} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3 + ) +endif() + +if(ANDROID AND TARGET SDL3::Jar) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake/android") + find_package(SdlAndroid MODULE) + if(SdlAndroid_FOUND) + set(apks "") + set(packages "") + + include(SdlAndroidFunctions) + sdl_create_android_debug_keystore(SDL_example-debug-keystore) + sdl_android_compile_resources(SDL_example-resources RESFOLDER ${CMAKE_CURRENT_SOURCE_DIR}/../test/android/res) + add_custom_target(sdl-example-apks) + foreach(EXAMPLE ${SDL_EXAMPLE_EXECUTABLES}) + set(ANDROID_MANIFEST_APP_NAME "${EXAMPLE}") + set(ANDROID_MANIFEST_LABEL "${EXAMPLE}") + set(ANDROID_MANIFEST_LIB_NAME "$") + set(ANDROID_MANIFEST_PACKAGE "org.libsdl.sdl.example.${EXAMPLE}") + set(generated_manifest_path "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-src/AndroidManifest.xml") + string(REPLACE "." "/" JAVA_PACKAGE_DIR "${ANDROID_MANIFEST_PACKAGE}") + set(GENERATED_SRC_FOLDER "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-src") + set(GENERATED_RES_FOLDER "${GENERATED_SRC_FOLDER}/res") + set(JAVA_PACKAGE_DIR "${GENERATED_SRC_FOLDER}/${JAVA_PACKAGE_DIR}") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/SDLEntryTestActivity.java.cmake "${JAVA_PACKAGE_DIR}/SDLEntryTestActivity.java" @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/SDLTestActivity.java.cmake "${JAVA_PACKAGE_DIR}/SDLTestActivity.java" @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/res/values/strings.xml.cmake android/res/values/strings-${EXAMPLE}.xml @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/res/xml/shortcuts.xml.cmake "${GENERATED_RES_FOLDER}/xml/shortcuts.xml" @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/AndroidManifest.xml.cmake "${generated_manifest_path}" @ONLY) + file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-$/res/values/strings.xml" + INPUT "${CMAKE_CURRENT_BINARY_DIR}/android/res/values/strings-${EXAMPLE}.xml" + ) + + sdl_android_compile_resources(${EXAMPLE}-resources + RESOURCES + "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-$/res/values/strings.xml" + "${GENERATED_RES_FOLDER}/xml/shortcuts.xml" + ) + + sdl_android_link_resources(${EXAMPLE}-apk-linked + MANIFEST "${generated_manifest_path}" + PACKAGE ${ANDROID_MANIFEST_PACKAGE} + RES_TARGETS SDL_example-resources ${EXAMPLE}-resources + TARGET_SDK_VERSION 31 + ) + + set(CMAKE_JAVA_COMPILE_FLAGS "-encoding;utf-8") + set(classes_path "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${EXAMPLE}-java.dir/classes") + # Some CMake versions have a slow `cmake -E make_directory` implementation + if(NOT IS_DIRECTORY "${classes_path}") + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${classes_path}") + endif() + set(OUT_JAR "${CMAKE_CURRENT_BINARY_DIR}/${EXAMPLE}.jar") + add_custom_command( + OUTPUT "${OUT_JAR}" + COMMAND ${CMAKE_COMMAND} -E rm -rf "${classes_path}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${classes_path}" + COMMAND ${Java_JAVAC_EXECUTABLE} + -source 1.8 -target 1.8 + -bootclasspath "$" + "${JAVA_PACKAGE_DIR}/SDLEntryTestActivity.java" + "${JAVA_PACKAGE_DIR}/SDLTestActivity.java" + $ + -cp "$:${SDL_ANDROID_PLATFORM_ANDROID_JAR}" + -d "${classes_path}" + COMMAND ${Java_JAR_EXECUTABLE} cf "${OUT_JAR}" -C "${classes_path}" . + DEPENDS $ "$" "${JAVA_PACKAGE_DIR}/SDLTestActivity.java" "${JAVA_PACKAGE_DIR}/SDLEntryTestActivity.java" + ) + add_custom_target(${EXAMPLE}-jar DEPENDS "${OUT_JAR}") + set_property(TARGET ${EXAMPLE}-jar PROPERTY OUTPUT "${OUT_JAR}") + + set(dexworkdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${EXAMPLE}-dex.dir") + # Some CMake versions have a slow `cmake -E make_directory` implementation + if(NOT IS_DIRECTORY "${dexworkdir}") + execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${dexworkdir}") + endif() + set(classes_dex_base_name "classes.dex") + set(classes_dex "${dexworkdir}/${classes_dex_base_name}") + add_custom_command( + OUTPUT "${classes_dex}" + COMMAND SdlAndroid::d8 + $ + $ + --lib "${SDL_ANDROID_PLATFORM_ANDROID_JAR}" + --output "${dexworkdir}" + DEPENDS $ $ + ) + add_custom_target(${EXAMPLE}-dex DEPENDS "${classes_dex}") + set_property(TARGET ${EXAMPLE}-dex PROPERTY OUTPUT "${classes_dex}") + set_property(TARGET ${EXAMPLE}-dex PROPERTY OUTPUT_BASE_NAME "${classes_dex_base_name}") + + sdl_add_to_apk_unaligned(${EXAMPLE}-unaligned-apk + APK_IN ${EXAMPLE}-apk-linked + OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/intermediates" + ASSETS ${RESOURCE_FILES} + NATIVE_LIBS SDL3::SDL3-shared ${EXAMPLE} + DEX ${EXAMPLE}-dex + ) + + sdl_apk_align(${EXAMPLE}-aligned-apk ${EXAMPLE}-unaligned-apk + OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/intermediates" + ) + sdl_apk_sign(${EXAMPLE}-apk ${EXAMPLE}-aligned-apk + KEYSTORE SDL_example-debug-keystore + ) + add_dependencies(sdl-example-apks ${EXAMPLE}-apk) + + if(TARGET SdlAndroid::adb) + add_custom_target(install-${EXAMPLE} + COMMAND "${CMAKE_COMMAND}" -DACTION=install "-DAPKS=$" -P "${SDL3_SOURCE_DIR}/cmake/android/SdlAndroidScript.cmake" + DEPENDS "${EXAMPLE}-apk" + ) + add_custom_target(start-${EXAMPLE} + COMMAND "${ADB_BIN}" shell am start-activity -S "${ANDROID_MANIFEST_PACKAGE}/.SDLTestActivity" + ) + add_custom_target(build-install-start-${EXAMPLE} + COMMAND "${CMAKE_COMMAND}" -DACTION=build-install-run "-DEXECUTABLES=${EXAMPLE}" "-DBUILD_FOLDER=${CMAKE_BINARY_DIR}" -P "${SDL3_SOURCE_DIR}/cmake/android/SdlAndroidScript.cmake" + ) + endif() + + list(APPEND packages "${ANDROID_MANIFEST_PACKAGE}") + list(APPEND install_targets install-${EXAMPLE}) + endforeach() + + if(TARGET SdlAndroid::adb) + add_custom_target(install-sdl-example-apks + DEPENDS ${install_targets} + VERBATIM + ) + add_custom_target(uninstall-sdl-example-apks + COMMAND "${CMAKE_COMMAND}" "-DADB=$" -DACTION=uninstall "-DPACKAGES=${packages}" -P "${SDL3_SOURCE_DIR}/cmake/android/SdlAndroidScript.cmake" + VERBATIM + ) + endif() + endif() +endif() diff --git a/src/contrib/SDL-3.2.20/examples/README.md b/src/contrib/SDL-3.2.20/examples/README.md new file mode 100644 index 0000000..872e087 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/README.md @@ -0,0 +1,67 @@ +# Examples + +## What is this? + +In here are a collection of standalone SDL application examples. Unless +otherwise stated, they should work on all supported platforms out of the box. +If they don't [please file a bug to let us know](https://github.com/libsdl-org/SDL/issues/new). + + +## What is this SDL_AppIterate thing? + +SDL can optionally build apps as a collection of callbacks instead of the +usual program structure that starts and ends in a function called `main`. +The examples use this format for two reasons. + +First, it allows the examples to work when built as web applications without +a pile of ugly `#ifdef`s, and all of these examples are published on the web +at [examples.libsdl.org](https://examples.libsdl.org/), so you can easily see +them in action. + +Second, it's example code! The callbacks let us cleanly break the program up +into the four logical pieces most apps care about: + +- Program startup +- Event handling +- What the program actually does in a single frame +- Program shutdown + +A detailed technical explanation of these callbacks is in +docs/README-main-functions.md (or view that page on the web on +[the wiki](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3)). + + +## I would like to build and run these examples myself. + +When you build SDL with CMake, you can add `-DSDL_EXAMPLES=On` to the +CMake command line. When you build SDL, these examples will be built with it. + +But most of these can just be built as a single .c file, as long as you point +your compiler at SDL3's headers and link against SDL. + + +## What is the license on the example code? Can I paste this into my project? + +All code in the examples directory is considered public domain! You can do +anything you like with it, including copy/paste it into your closed-source +project, sell it, and pretend you wrote it yourself. We do not require you to +give us credit for this code (but we always appreciate if you do!). + +This is only true for the examples directory. The rest of SDL falls under the +[zlib license](https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt). + + +## What is template.html and highlight-plugin.lua in this directory? + +This is what [examples.libsdl.org](https://examples.libsdl.org/) uses when +generating the web versions of these example programs. You can ignore this, +unless you are improving it, in which case we definitely would love to hear +from you! + + +## What is template.c in this directory? + +If writing new examples, this is the skeleton code we start from, to keep +everything consistent. You can ignore it. + + diff --git a/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/README.txt b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/README.txt new file mode 100644 index 0000000..e4283d4 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/README.txt @@ -0,0 +1,6 @@ +This example code loads a few bitmap files from disk using the asynchronous +i/o, and then draws it to the window. It uses a task group to watch multiple +reads and deal with them in whatever order they finish. + +Note that for a single tiny file like this, you'd probably not want to bother +with async i/o in real life, but this is just an example of how to do it. diff --git a/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/load-bitmaps.c b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/load-bitmaps.c new file mode 100644 index 0000000..44c2abf --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/load-bitmaps.c @@ -0,0 +1,125 @@ +/* + * This example code loads a bitmap with asynchronous i/o and renders it. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_AsyncIOQueue *queue = NULL; + +#define TOTAL_TEXTURES 4 +static const char * const bmps[TOTAL_TEXTURES] = { "sample.bmp", "gamepad_front.bmp", "speaker.bmp", "icon2x.bmp" }; +static SDL_Texture *textures[TOTAL_TEXTURES]; +static const SDL_FRect texture_rects[TOTAL_TEXTURES] = { + { 116, 156, 408, 167 }, + { 20, 200, 96, 60 }, + { 525, 180, 96, 96 }, + { 288, 375, 64, 64 } +}; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int i; + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/asyncio/load-bitmaps", 640, 480, 0, &window, &renderer)) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL); + return SDL_APP_FAILURE; + } + + queue = SDL_CreateAsyncIOQueue(); + if (!queue) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create async i/o queue!", SDL_GetError(), NULL); + return SDL_APP_FAILURE; + } + + /* Load some .bmp files asynchronously from wherever the app is being run from, put them in the same queue. */ + for (i = 0; i < SDL_arraysize(bmps); i++) { + char *path = NULL; + SDL_asprintf(&path, "%s%s", SDL_GetBasePath(), bmps[i]); /* allocate a string of the full file path */ + /* you _should) check for failure, but we'll just go on without files here. */ + SDL_LoadFileAsync(path, queue, (void *) bmps[i]); /* attach the filename as app-specific data, so we can see it later. */ + SDL_free(path); + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_AsyncIOOutcome outcome; + int i; + + if (SDL_GetAsyncIOResult(queue, &outcome)) { /* a .bmp file load has finished? */ + if (outcome.result == SDL_ASYNCIO_COMPLETE) { + /* this might be _any_ of the bmps; they might finish loading in any order. */ + for (i = 0; i < SDL_arraysize(bmps); i++) { + /* this doesn't need a strcmp because we gave the pointer from this array to SDL_LoadFileAsync */ + if (outcome.userdata == bmps[i]) { + break; + } + } + + if (i < SDL_arraysize(bmps)) { /* (just in case.) */ + SDL_Surface *surface = SDL_LoadBMP_IO(SDL_IOFromConstMem(outcome.buffer, (size_t) outcome.bytes_transferred), true); + if (surface) { /* the renderer is not multithreaded, so create the texture here once the data loads. */ + textures[i] = SDL_CreateTextureFromSurface(renderer, surface); + if (!textures[i]) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create texture!", SDL_GetError(), NULL); + return SDL_APP_FAILURE; + } + SDL_DestroySurface(surface); + } + } + } + SDL_free(outcome.buffer); + } + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + for (i = 0; i < SDL_arraysize(textures); i++) { + SDL_RenderTexture(renderer, textures[i], NULL, &texture_rects[i]); + } + + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + int i; + + SDL_DestroyAsyncIOQueue(queue); + + for (i = 0; i < SDL_arraysize(textures); i++) { + SDL_DestroyTexture(textures[i]); + } + + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/thumbnail.png b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/thumbnail.png new file mode 100644 index 0000000..4f8be2a Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/asyncio/description.txt b/src/contrib/SDL-3.2.20/examples/asyncio/description.txt new file mode 100644 index 0000000..c3aafe1 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/asyncio/description.txt @@ -0,0 +1 @@ +Asynchronous I/O \ No newline at end of file diff --git a/src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/README.txt b/src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/README.txt new file mode 100644 index 0000000..20ad059 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/README.txt @@ -0,0 +1,5 @@ +If you're running this in a web browser, you need to click the window before you'll hear anything! + +This example code creates a simple audio stream for playing sound, and +generates a sine wave sound effect for it to play as time goes on. This is the +simplest way to get up and running with procedural sound. diff --git a/src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/simple-playback.c b/src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/simple-playback.c new file mode 100644 index 0000000..15126e5 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/simple-playback.c @@ -0,0 +1,103 @@ +/* + * This example code creates a simple audio stream for playing sound, and + * generates a sine wave sound effect for it to play as time goes on. This + * is the simplest way to get up and running with procedural sound. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_AudioStream *stream = NULL; +static int current_sine_sample = 0; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_AudioSpec spec; + + SDL_SetAppMetadata("Example Audio Simple Playback", "1.0", "com.example.audio-simple-playback"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* we don't _need_ a window for audio-only things but it's good policy to have one. */ + if (!SDL_CreateWindowAndRenderer("examples/audio/simple-playback", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* We're just playing a single thing here, so we'll use the simplified option. + We are always going to feed audio in as mono, float32 data at 8000Hz. + The stream will convert it to whatever the hardware wants on the other side. */ + spec.channels = 1; + spec.format = SDL_AUDIO_F32; + spec.freq = 8000; + stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL); + if (!stream) { + SDL_Log("Couldn't create audio stream: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */ + SDL_ResumeAudioStreamDevice(stream); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + /* see if we need to feed the audio stream more data yet. + We're being lazy here, but if there's less than half a second queued, generate more. + A sine wave is unchanging audio--easy to stream--but for video games, you'll want + to generate significantly _less_ audio ahead of time! */ + const int minimum_audio = (8000 * sizeof (float)) / 2; /* 8000 float samples per second. Half of that. */ + if (SDL_GetAudioStreamQueued(stream) < minimum_audio) { + static float samples[512]; /* this will feed 512 samples each frame until we get to our maximum. */ + int i; + + /* generate a 440Hz pure tone */ + for (i = 0; i < SDL_arraysize(samples); i++) { + const int freq = 440; + const float phase = current_sine_sample * freq / 8000.0f; + samples[i] = SDL_sinf(phase * 2 * SDL_PI_F); + current_sine_sample++; + } + + /* wrapping around to avoid floating-point errors */ + current_sine_sample %= 8000; + + /* feed the new data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */ + SDL_PutAudioStreamData(stream, samples, sizeof (samples)); + } + + /* we're not doing anything with the renderer, so just blank it out. */ + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/README.txt b/src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/README.txt new file mode 100644 index 0000000..888ae34 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/README.txt @@ -0,0 +1,5 @@ +If you're running this in a web browser, you need to click the window before you'll hear anything! + +This example code creates a simple audio stream for playing sound, and +generates a sine wave sound effect for it to play as time goes on. Unlike +the previous example, this uses a callback to generate sound. diff --git a/src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/simple-playback-callback.c b/src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/simple-playback-callback.c new file mode 100644 index 0000000..c011c72 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/simple-playback-callback.c @@ -0,0 +1,115 @@ +/* + * This example code creates a simple audio stream for playing sound, and + * generates a sine wave sound effect for it to play as time goes on. Unlike + * the previous example, this uses a callback to generate sound. + * + * This might be the path of least resistance if you're moving an SDL2 + * program's audio code to SDL3. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_AudioStream *stream = NULL; +static int current_sine_sample = 0; + +/* this function will be called (usually in a background thread) when the audio stream is consuming data. */ +static void SDLCALL FeedTheAudioStreamMore(void *userdata, SDL_AudioStream *astream, int additional_amount, int total_amount) +{ + /* total_amount is how much data the audio stream is eating right now, additional_amount is how much more it needs + than what it currently has queued (which might be zero!). You can supply any amount of data here; it will take what + it needs and use the extra later. If you don't give it enough, it will take everything and then feed silence to the + hardware for the rest. Ideally, though, we always give it what it needs and no extra, so we aren't buffering more + than necessary. */ + additional_amount /= sizeof (float); /* convert from bytes to samples */ + while (additional_amount > 0) { + float samples[128]; /* this will feed 128 samples each iteration until we have enough. */ + const int total = SDL_min(additional_amount, SDL_arraysize(samples)); + int i; + + /* generate a 440Hz pure tone */ + for (i = 0; i < total; i++) { + const int freq = 440; + const float phase = current_sine_sample * freq / 8000.0f; + samples[i] = SDL_sinf(phase * 2 * SDL_PI_F); + current_sine_sample++; + } + + /* wrapping around to avoid floating-point errors */ + current_sine_sample %= 8000; + + /* feed the new data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */ + SDL_PutAudioStreamData(astream, samples, total * sizeof (float)); + additional_amount -= total; /* subtract what we've just fed the stream. */ + } +} + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_AudioSpec spec; + + SDL_SetAppMetadata("Example Simple Audio Playback Callback", "1.0", "com.example.audio-simple-playback-callback"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* we don't _need_ a window for audio-only things but it's good policy to have one. */ + if (!SDL_CreateWindowAndRenderer("examples/audio/simple-playback-callback", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* We're just playing a single thing here, so we'll use the simplified option. + We are always going to feed audio in as mono, float32 data at 8000Hz. + The stream will convert it to whatever the hardware wants on the other side. */ + spec.channels = 1; + spec.format = SDL_AUDIO_F32; + spec.freq = 8000; + stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, FeedTheAudioStreamMore, NULL); + if (!stream) { + SDL_Log("Couldn't create audio stream: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */ + SDL_ResumeAudioStreamDevice(stream); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + /* we're not doing anything with the renderer, so just blank it out. */ + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + /* all the work of feeding the audio stream is happening in a callback in a background thread. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/audio/03-load-wav/README.txt b/src/contrib/SDL-3.2.20/examples/audio/03-load-wav/README.txt new file mode 100644 index 0000000..57eb90c --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/03-load-wav/README.txt @@ -0,0 +1,5 @@ +If you're running this in a web browser, you need to click the window before you'll hear anything! + +This example code creates a simple audio stream for playing sound, and +loads a .wav file that is pushed through the stream in a loop. + diff --git a/src/contrib/SDL-3.2.20/examples/audio/03-load-wav/load-wav.c b/src/contrib/SDL-3.2.20/examples/audio/03-load-wav/load-wav.c new file mode 100644 index 0000000..c517e5d --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/03-load-wav/load-wav.c @@ -0,0 +1,103 @@ +/* + * This example code creates a simple audio stream for playing sound, and + * loads a .wav file that is pushed through the stream in a loop. + * + * This code is public domain. Feel free to use it for any purpose! + * + * The .wav file is a sample from Will Provost's song, The Living Proof, + * used with permission. + * + * From the album The Living Proof + * Publisher: 5 Guys Named Will + * Copyright 1996 Will Provost + * https://itunes.apple.com/us/album/the-living-proof/id4153978 + * http://www.amazon.com/The-Living-Proof-Will-Provost/dp/B00004R8RH + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_AudioStream *stream = NULL; +static Uint8 *wav_data = NULL; +static Uint32 wav_data_len = 0; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_AudioSpec spec; + char *wav_path = NULL; + + SDL_SetAppMetadata("Example Audio Load Wave", "1.0", "com.example.audio-load-wav"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* we don't _need_ a window for audio-only things but it's good policy to have one. */ + if (!SDL_CreateWindowAndRenderer("examples/audio/load-wav", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Load the .wav file from wherever the app is being run from. */ + SDL_asprintf(&wav_path, "%ssample.wav", SDL_GetBasePath()); /* allocate a string of the full file path */ + if (!SDL_LoadWAV(wav_path, &spec, &wav_data, &wav_data_len)) { + SDL_Log("Couldn't load .wav file: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(wav_path); /* done with this string. */ + + /* Create our audio stream in the same format as the .wav file. It'll convert to what the audio hardware wants. */ + stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL); + if (!stream) { + SDL_Log("Couldn't create audio stream: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */ + SDL_ResumeAudioStreamDevice(stream); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + /* see if we need to feed the audio stream more data yet. + We're being lazy here, but if there's less than the entire wav file left to play, + just shove a whole copy of it into the queue, so we always have _tons_ of + data queued for playback. */ + if (SDL_GetAudioStreamQueued(stream) < (int)wav_data_len) { + /* feed more data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */ + SDL_PutAudioStreamData(stream, wav_data, wav_data_len); + } + + /* we're not doing anything with the renderer, so just blank it out. */ + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_free(wav_data); /* strictly speaking, this isn't necessary because the process is ending, but it's good policy. */ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/README.txt b/src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/README.txt new file mode 100644 index 0000000..9ef2275 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/README.txt @@ -0,0 +1,5 @@ +If you're running this in a web browser, you need to click the window before you'll hear anything! + +This example code loads two .wav files, puts them an audio streams and binds +them for playback, repeating both sounds on loop. This shows several streams +mixing into a single playback device. diff --git a/src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/multiple-streams.c b/src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/multiple-streams.c new file mode 100644 index 0000000..8d3bfaa --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/multiple-streams.c @@ -0,0 +1,135 @@ +/* + * This example code loads two .wav files, puts them an audio streams and + * binds them for playback, repeating both sounds on loop. This shows several + * streams mixing into a single playback device. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_AudioDeviceID audio_device = 0; + +/* things that are playing sound (the audiostream itself, plus the original data, so we can refill to loop. */ +typedef struct Sound { + Uint8 *wav_data; + Uint32 wav_data_len; + SDL_AudioStream *stream; +} Sound; + +static Sound sounds[2]; + +static bool init_sound(const char *fname, Sound *sound) +{ + bool retval = false; + SDL_AudioSpec spec; + char *wav_path = NULL; + + /* Load the .wav files from wherever the app is being run from. */ + SDL_asprintf(&wav_path, "%s%s", SDL_GetBasePath(), fname); /* allocate a string of the full file path */ + if (!SDL_LoadWAV(wav_path, &spec, &sound->wav_data, &sound->wav_data_len)) { + SDL_Log("Couldn't load .wav file: %s", SDL_GetError()); + return false; + } + + /* Create an audio stream. Set the source format to the wav's format (what + we'll input), leave the dest format NULL here (it'll change to what the + device wants once we bind it). */ + sound->stream = SDL_CreateAudioStream(&spec, NULL); + if (!sound->stream) { + SDL_Log("Couldn't create audio stream: %s", SDL_GetError()); + } else if (!SDL_BindAudioStream(audio_device, sound->stream)) { /* once bound, it'll start playing when there is data available! */ + SDL_Log("Failed to bind '%s' stream to device: %s", fname, SDL_GetError()); + } else { + retval = true; /* success! */ + } + + SDL_free(wav_path); /* done with this string. */ + return retval; +} + + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + + SDL_SetAppMetadata("Example Audio Multiple Streams", "1.0", "com.example.audio-multiple-streams"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/audio/multiple-streams", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* open the default audio device in whatever format it prefers; our audio streams will adjust to it. */ + audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL); + if (audio_device == 0) { + SDL_Log("Couldn't open audio device: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!init_sound("sample.wav", &sounds[0])) { + return SDL_APP_FAILURE; + } else if (!init_sound("sword.wav", &sounds[1])) { + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + int i; + + for (i = 0; i < SDL_arraysize(sounds); i++) { + /* If less than a full copy of the audio is queued for playback, put another copy in there. + This is overkill, but easy when lots of RAM is cheap. One could be more careful and + queue less at a time, as long as the stream doesn't run dry. */ + if (SDL_GetAudioStreamQueued(sounds[i].stream) < ((int) sounds[i].wav_data_len)) { + SDL_PutAudioStreamData(sounds[i].stream, sounds[i].wav_data, (int) sounds[i].wav_data_len); + } + } + + /* just blank the screen. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + int i; + + SDL_CloseAudioDevice(audio_device); + + for (i = 0; i < SDL_arraysize(sounds); i++) { + if (sounds[i].stream) { + SDL_DestroyAudioStream(sounds[i].stream); + } + SDL_free(sounds[i].wav_data); + } + + /* SDL will clean up the window/renderer for us. */ +} diff --git a/src/contrib/SDL-3.2.20/examples/audio/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/audio/onmouseover.webp new file mode 100644 index 0000000..1f3ba4b Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/audio/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/audio/thumbnail.png b/src/contrib/SDL-3.2.20/examples/audio/thumbnail.png new file mode 100644 index 0000000..10bc6c8 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/audio/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/README.txt b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/README.txt new file mode 100644 index 0000000..f7ac1f5 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/README.txt @@ -0,0 +1 @@ +This reads from a webcam and draws frames of video to the screen. diff --git a/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/onmouseover.webp new file mode 100644 index 0000000..1d414e6 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/read-and-draw.c b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/read-and-draw.c new file mode 100644 index 0000000..989fd54 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/read-and-draw.c @@ -0,0 +1,113 @@ +/* + * This example code reads frames from a camera and draws it to the screen. + * + * This is a very simple approach that is often Good Enough. You can get + * fancier with this: multiple cameras, front/back facing cameras on phones, + * color spaces, choosing formats and framerates...this just requests + * _anything_ and goes with what it is handed. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Camera *camera = NULL; +static SDL_Texture *texture = NULL; + + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_CameraID *devices = NULL; + int devcount = 0; + + SDL_SetAppMetadata("Example Camera Read and Draw", "1.0", "com.example.camera-read-and-draw"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/camera/read-and-draw", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + devices = SDL_GetCameras(&devcount); + if (devices == NULL) { + SDL_Log("Couldn't enumerate camera devices: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } else if (devcount == 0) { + SDL_Log("Couldn't find any camera devices! Please connect a camera and try again."); + return SDL_APP_FAILURE; + } + + camera = SDL_OpenCamera(devices[0], NULL); // just take the first thing we see in any format it wants. + SDL_free(devices); + if (camera == NULL) { + SDL_Log("Couldn't open camera: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } else if (event->type == SDL_EVENT_CAMERA_DEVICE_APPROVED) { + SDL_Log("Camera use approved by user!"); + } else if (event->type == SDL_EVENT_CAMERA_DEVICE_DENIED) { + SDL_Log("Camera use denied by user!"); + return SDL_APP_FAILURE; + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + Uint64 timestampNS = 0; + SDL_Surface *frame = SDL_AcquireCameraFrame(camera, ×tampNS); + + if (frame != NULL) { + /* Some platforms (like Emscripten) don't know _what_ the camera offers + until the user gives permission, so we build the texture and resize + the window when we get a first frame from the camera. */ + if (!texture) { + SDL_SetWindowSize(window, frame->w, frame->h); /* Resize the window to match */ + texture = SDL_CreateTexture(renderer, frame->format, SDL_TEXTUREACCESS_STREAMING, frame->w, frame->h); + } + + if (texture) { + SDL_UpdateTexture(texture, NULL, frame->pixels, frame->pitch); + } + + SDL_ReleaseCameraFrame(camera, frame); + } + + SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + if (texture) { /* draw the latest camera frame, if available. */ + SDL_RenderTexture(renderer, texture, NULL, NULL); + } + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_CloseCamera(camera); + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/thumbnail.png b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/thumbnail.png new file mode 100644 index 0000000..98fe4e0 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/categories.txt b/src/contrib/SDL-3.2.20/examples/categories.txt new file mode 100644 index 0000000..8a9b5ec --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/categories.txt @@ -0,0 +1,13 @@ +# Blank lines and lines that start with '#' in this file are ignored. + +# Categories, by directory name, go in here, in the order they should be +# listed on the main page. If this file is missing, it'll assume any +# subdirectory is a category and sort them alphabetically. + +renderer +input +audio +camera +asyncio +pen +demo diff --git a/src/contrib/SDL-3.2.20/examples/demo/01-snake/README.txt b/src/contrib/SDL-3.2.20/examples/demo/01-snake/README.txt new file mode 100644 index 0000000..1cf9784 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/01-snake/README.txt @@ -0,0 +1 @@ +A complete game of Snake, written in SDL. diff --git a/src/contrib/SDL-3.2.20/examples/demo/01-snake/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/demo/01-snake/onmouseover.webp new file mode 100644 index 0000000..1757202 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/01-snake/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/01-snake/snake.c b/src/contrib/SDL-3.2.20/examples/demo/01-snake/snake.c new file mode 100644 index 0000000..0aca862 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/01-snake/snake.c @@ -0,0 +1,350 @@ +/* + * Logic implementation of the Snake game. It is designed to efficiently + * represent the state of the game in memory. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +#define STEP_RATE_IN_MILLISECONDS 125 +#define SNAKE_BLOCK_SIZE_IN_PIXELS 24 +#define SDL_WINDOW_WIDTH (SNAKE_BLOCK_SIZE_IN_PIXELS * SNAKE_GAME_WIDTH) +#define SDL_WINDOW_HEIGHT (SNAKE_BLOCK_SIZE_IN_PIXELS * SNAKE_GAME_HEIGHT) + +#define SNAKE_GAME_WIDTH 24U +#define SNAKE_GAME_HEIGHT 18U +#define SNAKE_MATRIX_SIZE (SNAKE_GAME_WIDTH * SNAKE_GAME_HEIGHT) + +#define THREE_BITS 0x7U /* ~CHAR_MAX >> (CHAR_BIT - SNAKE_CELL_MAX_BITS) */ +#define SHIFT(x, y) (((x) + ((y) * SNAKE_GAME_WIDTH)) * SNAKE_CELL_MAX_BITS) + +typedef enum +{ + SNAKE_CELL_NOTHING = 0U, + SNAKE_CELL_SRIGHT = 1U, + SNAKE_CELL_SUP = 2U, + SNAKE_CELL_SLEFT = 3U, + SNAKE_CELL_SDOWN = 4U, + SNAKE_CELL_FOOD = 5U +} SnakeCell; + +#define SNAKE_CELL_MAX_BITS 3U /* floor(log2(SNAKE_CELL_FOOD)) + 1 */ + +typedef enum +{ + SNAKE_DIR_RIGHT, + SNAKE_DIR_UP, + SNAKE_DIR_LEFT, + SNAKE_DIR_DOWN +} SnakeDirection; + +typedef struct +{ + unsigned char cells[(SNAKE_MATRIX_SIZE * SNAKE_CELL_MAX_BITS) / 8U]; + char head_xpos; + char head_ypos; + char tail_xpos; + char tail_ypos; + char next_dir; + char inhibit_tail_step; + unsigned occupied_cells; +} SnakeContext; + +typedef struct +{ + SDL_Window *window; + SDL_Renderer *renderer; + SnakeContext snake_ctx; + Uint64 last_step; +} AppState; + +SnakeCell snake_cell_at(const SnakeContext *ctx, char x, char y) +{ + const int shift = SHIFT(x, y); + unsigned short range; + SDL_memcpy(&range, ctx->cells + (shift / 8), sizeof(range)); + return (SnakeCell)((range >> (shift % 8)) & THREE_BITS); +} + +static void set_rect_xy_(SDL_FRect *r, short x, short y) +{ + r->x = (float)(x * SNAKE_BLOCK_SIZE_IN_PIXELS); + r->y = (float)(y * SNAKE_BLOCK_SIZE_IN_PIXELS); +} + +static void put_cell_at_(SnakeContext *ctx, char x, char y, SnakeCell ct) +{ + const int shift = SHIFT(x, y); + const int adjust = shift % 8; + unsigned char *const pos = ctx->cells + (shift / 8); + unsigned short range; + SDL_memcpy(&range, pos, sizeof(range)); + range &= ~(THREE_BITS << adjust); /* clear bits */ + range |= (ct & THREE_BITS) << adjust; + SDL_memcpy(pos, &range, sizeof(range)); +} + +static int are_cells_full_(SnakeContext *ctx) +{ + return ctx->occupied_cells == SNAKE_GAME_WIDTH * SNAKE_GAME_HEIGHT; +} + +static void new_food_pos_(SnakeContext *ctx) +{ + while (true) { + const char x = (char) SDL_rand(SNAKE_GAME_WIDTH); + const char y = (char) SDL_rand(SNAKE_GAME_HEIGHT); + if (snake_cell_at(ctx, x, y) == SNAKE_CELL_NOTHING) { + put_cell_at_(ctx, x, y, SNAKE_CELL_FOOD); + break; + } + } +} + +void snake_initialize(SnakeContext *ctx) +{ + int i; + SDL_zeroa(ctx->cells); + ctx->head_xpos = ctx->tail_xpos = SNAKE_GAME_WIDTH / 2; + ctx->head_ypos = ctx->tail_ypos = SNAKE_GAME_HEIGHT / 2; + ctx->next_dir = SNAKE_DIR_RIGHT; + ctx->inhibit_tail_step = ctx->occupied_cells = 4; + --ctx->occupied_cells; + put_cell_at_(ctx, ctx->tail_xpos, ctx->tail_ypos, SNAKE_CELL_SRIGHT); + for (i = 0; i < 4; i++) { + new_food_pos_(ctx); + ++ctx->occupied_cells; + } +} + +void snake_redir(SnakeContext *ctx, SnakeDirection dir) +{ + SnakeCell ct = snake_cell_at(ctx, ctx->head_xpos, ctx->head_ypos); + if ((dir == SNAKE_DIR_RIGHT && ct != SNAKE_CELL_SLEFT) || + (dir == SNAKE_DIR_UP && ct != SNAKE_CELL_SDOWN) || + (dir == SNAKE_DIR_LEFT && ct != SNAKE_CELL_SRIGHT) || + (dir == SNAKE_DIR_DOWN && ct != SNAKE_CELL_SUP)) { + ctx->next_dir = dir; + } +} + +static void wrap_around_(char *val, char max) +{ + if (*val < 0) { + *val = max - 1; + } else if (*val > max - 1) { + *val = 0; + } +} + +void snake_step(SnakeContext *ctx) +{ + const SnakeCell dir_as_cell = (SnakeCell)(ctx->next_dir + 1); + SnakeCell ct; + char prev_xpos; + char prev_ypos; + /* Move tail forward */ + if (--ctx->inhibit_tail_step == 0) { + ++ctx->inhibit_tail_step; + ct = snake_cell_at(ctx, ctx->tail_xpos, ctx->tail_ypos); + put_cell_at_(ctx, ctx->tail_xpos, ctx->tail_ypos, SNAKE_CELL_NOTHING); + switch (ct) { + case SNAKE_CELL_SRIGHT: + ctx->tail_xpos++; + break; + case SNAKE_CELL_SUP: + ctx->tail_ypos--; + break; + case SNAKE_CELL_SLEFT: + ctx->tail_xpos--; + break; + case SNAKE_CELL_SDOWN: + ctx->tail_ypos++; + break; + default: + break; + } + wrap_around_(&ctx->tail_xpos, SNAKE_GAME_WIDTH); + wrap_around_(&ctx->tail_ypos, SNAKE_GAME_HEIGHT); + } + /* Move head forward */ + prev_xpos = ctx->head_xpos; + prev_ypos = ctx->head_ypos; + switch (ctx->next_dir) { + case SNAKE_DIR_RIGHT: + ++ctx->head_xpos; + break; + case SNAKE_DIR_UP: + --ctx->head_ypos; + break; + case SNAKE_DIR_LEFT: + --ctx->head_xpos; + break; + case SNAKE_DIR_DOWN: + ++ctx->head_ypos; + break; + } + wrap_around_(&ctx->head_xpos, SNAKE_GAME_WIDTH); + wrap_around_(&ctx->head_ypos, SNAKE_GAME_HEIGHT); + /* Collisions */ + ct = snake_cell_at(ctx, ctx->head_xpos, ctx->head_ypos); + if (ct != SNAKE_CELL_NOTHING && ct != SNAKE_CELL_FOOD) { + snake_initialize(ctx); + return; + } + put_cell_at_(ctx, prev_xpos, prev_ypos, dir_as_cell); + put_cell_at_(ctx, ctx->head_xpos, ctx->head_ypos, dir_as_cell); + if (ct == SNAKE_CELL_FOOD) { + if (are_cells_full_(ctx)) { + snake_initialize(ctx); + return; + } + new_food_pos_(ctx); + ++ctx->inhibit_tail_step; + ++ctx->occupied_cells; + } +} + +static SDL_AppResult handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code) +{ + switch (key_code) { + /* Quit. */ + case SDL_SCANCODE_ESCAPE: + case SDL_SCANCODE_Q: + return SDL_APP_SUCCESS; + /* Restart the game as if the program was launched. */ + case SDL_SCANCODE_R: + snake_initialize(ctx); + break; + /* Decide new direction of the snake. */ + case SDL_SCANCODE_RIGHT: + snake_redir(ctx, SNAKE_DIR_RIGHT); + break; + case SDL_SCANCODE_UP: + snake_redir(ctx, SNAKE_DIR_UP); + break; + case SDL_SCANCODE_LEFT: + snake_redir(ctx, SNAKE_DIR_LEFT); + break; + case SDL_SCANCODE_DOWN: + snake_redir(ctx, SNAKE_DIR_DOWN); + break; + default: + break; + } + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) +{ + AppState *as = (AppState *)appstate; + SnakeContext *ctx = &as->snake_ctx; + const Uint64 now = SDL_GetTicks(); + SDL_FRect r; + unsigned i; + unsigned j; + int ct; + + // run game logic if we're at or past the time to run it. + // if we're _really_ behind the time to run it, run it + // several times. + while ((now - as->last_step) >= STEP_RATE_IN_MILLISECONDS) { + snake_step(ctx); + as->last_step += STEP_RATE_IN_MILLISECONDS; + } + + r.w = r.h = SNAKE_BLOCK_SIZE_IN_PIXELS; + SDL_SetRenderDrawColor(as->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(as->renderer); + for (i = 0; i < SNAKE_GAME_WIDTH; i++) { + for (j = 0; j < SNAKE_GAME_HEIGHT; j++) { + ct = snake_cell_at(ctx, i, j); + if (ct == SNAKE_CELL_NOTHING) + continue; + set_rect_xy_(&r, i, j); + if (ct == SNAKE_CELL_FOOD) + SDL_SetRenderDrawColor(as->renderer, 80, 80, 255, SDL_ALPHA_OPAQUE); + else /* body */ + SDL_SetRenderDrawColor(as->renderer, 0, 128, 0, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(as->renderer, &r); + } + } + SDL_SetRenderDrawColor(as->renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /*head*/ + set_rect_xy_(&r, ctx->head_xpos, ctx->head_ypos); + SDL_RenderFillRect(as->renderer, &r); + SDL_RenderPresent(as->renderer); + return SDL_APP_CONTINUE; +} + +static const struct +{ + const char *key; + const char *value; +} extended_metadata[] = +{ + { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/01-snake/" }, + { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" }, + { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" }, + { SDL_PROP_APP_METADATA_TYPE_STRING, "game" } +}; + +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + size_t i; + + if (!SDL_SetAppMetadata("Example Snake game", "1.0", "com.example.Snake")) { + return SDL_APP_FAILURE; + } + + for (i = 0; i < SDL_arraysize(extended_metadata); i++) { + if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) { + return SDL_APP_FAILURE; + } + } + + if (!SDL_Init(SDL_INIT_VIDEO)) { + return SDL_APP_FAILURE; + } + + AppState *as = (AppState *)SDL_calloc(1, sizeof(AppState)); + if (!as) { + return SDL_APP_FAILURE; + } + + *appstate = as; + + if (!SDL_CreateWindowAndRenderer("examples/demo/snake", SDL_WINDOW_WIDTH, SDL_WINDOW_HEIGHT, 0, &as->window, &as->renderer)) { + return SDL_APP_FAILURE; + } + + snake_initialize(&as->snake_ctx); + + as->last_step = SDL_GetTicks(); + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + SnakeContext *ctx = &((AppState *)appstate)->snake_ctx; + switch (event->type) { + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + case SDL_EVENT_KEY_DOWN: + return handle_key_event_(ctx, event->key.scancode); + } + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + if (appstate != NULL) { + AppState *as = (AppState *)appstate; + SDL_DestroyRenderer(as->renderer); + SDL_DestroyWindow(as->window); + SDL_free(as); + } +} diff --git a/src/contrib/SDL-3.2.20/examples/demo/01-snake/thumbnail.png b/src/contrib/SDL-3.2.20/examples/demo/01-snake/thumbnail.png new file mode 100644 index 0000000..f0e27c5 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/01-snake/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/README.txt b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/README.txt new file mode 100644 index 0000000..83de3e3 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/README.txt @@ -0,0 +1 @@ +Minimal splitscreen FPS with multiple mouse and keyboards, drawn with the 2D Render API. \ No newline at end of file diff --git a/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/onmouseover.webp new file mode 100644 index 0000000..2e7f44f Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/thumbnail.png b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/thumbnail.png new file mode 100644 index 0000000..c8d1efa Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c new file mode 100644 index 0000000..b97b06a --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c @@ -0,0 +1,480 @@ +/* + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +#define MAP_BOX_SCALE 16 +#define MAP_BOX_EDGES_LEN (12 + MAP_BOX_SCALE * 2) +#define MAX_PLAYER_COUNT 4 +#define CIRCLE_DRAW_SIDES 32 +#define CIRCLE_DRAW_SIDES_LEN (CIRCLE_DRAW_SIDES + 1) + +typedef struct { + SDL_MouseID mouse; + SDL_KeyboardID keyboard; + double pos[3]; + double vel[3]; + unsigned int yaw; + int pitch; + float radius, height; + unsigned char color[3]; + unsigned char wasd; +} Player; + +typedef struct { + SDL_Window *window; + SDL_Renderer *renderer; + int player_count; + Player players[MAX_PLAYER_COUNT]; + float edges[MAP_BOX_EDGES_LEN][6]; +} AppState; + +static const struct { + const char *key; + const char *value; +} extended_metadata[] = { + { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/02-woodeneye-008/" }, + { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" }, + { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" }, + { SDL_PROP_APP_METADATA_TYPE_STRING, "game" } +}; + +static int whoseMouse(SDL_MouseID mouse, const Player players[], int players_len) +{ + int i; + for (i = 0; i < players_len; i++) { + if (players[i].mouse == mouse) return i; + } + return -1; +} + +static int whoseKeyboard(SDL_KeyboardID keyboard, const Player players[], int players_len) +{ + int i; + for (i = 0; i < players_len; i++) { + if (players[i].keyboard == keyboard) return i; + } + return -1; +} + +static void shoot(int shooter, Player players[], int players_len) +{ + int i, j; + double x0 = players[shooter].pos[0]; + double y0 = players[shooter].pos[1]; + double z0 = players[shooter].pos[2]; + double bin_rad = SDL_PI_D / 2147483648.0; + double yaw_rad = bin_rad * players[shooter].yaw; + double pitch_rad = bin_rad * players[shooter].pitch; + double cos_yaw = SDL_cos( yaw_rad); + double sin_yaw = SDL_sin( yaw_rad); + double cos_pitch = SDL_cos(pitch_rad); + double sin_pitch = SDL_sin(pitch_rad); + double vx = -sin_yaw*cos_pitch; + double vy = sin_pitch; + double vz = -cos_yaw*cos_pitch; + for (i = 0; i < players_len; i++) { + if (i == shooter) continue; + Player *target = &(players[i]); + int hit = 0; + for (j = 0; j < 2; j++) { + double r = target->radius; + double h = target->height; + double dx = target->pos[0] - x0; + double dy = target->pos[1] - y0 + (j == 0 ? 0 : r - h); + double dz = target->pos[2] - z0; + double vd = vx*dx + vy*dy + vz*dz; + double dd = dx*dx + dy*dy + dz*dz; + double vv = vx*vx + vy*vy + vz*vz; + double rr = r * r; + if (vd < 0) continue; + if (vd * vd >= vv * (dd - rr)) hit += 1; + } + if (hit) { + target->pos[0] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256; + target->pos[1] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256; + target->pos[2] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256; + } + } +} + +static void update(Player *players, int players_len, Uint64 dt_ns) +{ + int i; + for (i = 0; i < players_len; i++) { + Player *player = &players[i]; + double rate = 6.0; + double time = (double)dt_ns * 1e-9; + double drag = SDL_exp(-time * rate); + double diff = 1.0 - drag; + double mult = 60.0; + double grav = 25.0; + double yaw = (double)player->yaw; + double rad = yaw * SDL_PI_D / 2147483648.0; + double cos = SDL_cos(rad); + double sin = SDL_sin(rad); + unsigned char wasd = player->wasd; + double dirX = (wasd & 8 ? 1.0 : 0.0) - (wasd & 2 ? 1.0 : 0.0); + double dirZ = (wasd & 4 ? 1.0 : 0.0) - (wasd & 1 ? 1.0 : 0.0); + double norm = dirX * dirX + dirZ * dirZ; + double accX = mult * (norm == 0 ? 0 : ( cos*dirX + sin*dirZ) / SDL_sqrt(norm)); + double accZ = mult * (norm == 0 ? 0 : (-sin*dirX + cos*dirZ) / SDL_sqrt(norm)); + double velX = player->vel[0]; + double velY = player->vel[1]; + double velZ = player->vel[2]; + player->vel[0] -= velX * diff; + player->vel[1] -= grav * time; + player->vel[2] -= velZ * diff; + player->vel[0] += diff * accX / rate; + player->vel[2] += diff * accZ / rate; + player->pos[0] += (time - diff/rate) * accX / rate + diff * velX / rate; + player->pos[1] += -0.5 * grav * time * time + velY * time; + player->pos[2] += (time - diff/rate) * accZ / rate + diff * velZ / rate; + double scale = (double)MAP_BOX_SCALE; + double bound = scale - player->radius; + double posX = SDL_max(SDL_min(bound, player->pos[0]), -bound); + double posY = SDL_max(SDL_min(bound, player->pos[1]), player->height - scale); + double posZ = SDL_max(SDL_min(bound, player->pos[2]), -bound); + if (player->pos[0] != posX) player->vel[0] = 0; + if (player->pos[1] != posY) player->vel[1] = (wasd & 16) ? 8.4375 : 0; + if (player->pos[2] != posZ) player->vel[2] = 0; + player->pos[0] = posX; + player->pos[1] = posY; + player->pos[2] = posZ; + } +} + +static void drawCircle(SDL_Renderer *renderer, float r, float x, float y) +{ + float ang; + SDL_FPoint points[CIRCLE_DRAW_SIDES_LEN]; + int i; + for (i = 0; i < CIRCLE_DRAW_SIDES_LEN; i++) { + ang = 2.0f * SDL_PI_F * (float)i / (float)CIRCLE_DRAW_SIDES; + points[i].x = x + r * SDL_cosf(ang); + points[i].y = y + r * SDL_sinf(ang); + } + SDL_RenderLines(renderer, (const SDL_FPoint*)&points, CIRCLE_DRAW_SIDES_LEN); +} + +static void drawClippedSegment( + SDL_Renderer *renderer, + float ax, float ay, float az, + float bx, float by, float bz, + float x, float y, float z, float w) +{ + if (az >= -w && bz >= -w) return; + float dx = ax - bx; + float dy = ay - by; + if (az > -w) { + float t = (-w - bz) / (az - bz); + ax = bx + dx * t; + ay = by + dy * t; + az = -w; + } else if (bz > -w) { + float t = (-w - az) / (bz - az); + bx = ax - dx * t; + by = ay - dy * t; + bz = -w; + } + ax = -z * ax / az; + ay = -z * ay / az; + bx = -z * bx / bz; + by = -z * by / bz; + SDL_RenderLine(renderer, x + ax, y - ay, x + bx, y - by); +} + +static char debug_string[32]; +static void draw(SDL_Renderer *renderer, const float (*edges)[6], const Player players[], int players_len) +{ + int w, h, i, j, k; + if (!SDL_GetRenderOutputSize(renderer, &w, &h)) { + return; + } + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + if (players_len > 0) { + float wf = (float)w; + float hf = (float)h; + int part_hor = players_len > 2 ? 2 : 1; + int part_ver = players_len > 1 ? 2 : 1; + float size_hor = wf / ((float)part_hor); + float size_ver = hf / ((float)part_ver); + for (i = 0; i < players_len; i++) { + const Player *player = &players[i]; + float mod_x = (float)(i % part_hor); + float mod_y = (float)(i / part_hor); + float hor_origin = (mod_x + 0.5f) * size_hor; + float ver_origin = (mod_y + 0.5f) * size_ver; + float cam_origin = (float)(0.5 * SDL_sqrt(size_hor * size_hor + size_ver * size_ver)); + float hor_offset = mod_x * size_hor; + float ver_offset = mod_y * size_ver; + SDL_Rect rect; + rect.x = (int)hor_offset; + rect.y = (int)ver_offset; + rect.w = (int)size_hor; + rect.h = (int)size_ver; + SDL_SetRenderClipRect(renderer, &rect); + double x0 = player->pos[0]; + double y0 = player->pos[1]; + double z0 = player->pos[2]; + double bin_rad = SDL_PI_D / 2147483648.0; + double yaw_rad = bin_rad * player->yaw; + double pitch_rad = bin_rad * player->pitch; + double cos_yaw = SDL_cos( yaw_rad); + double sin_yaw = SDL_sin( yaw_rad); + double cos_pitch = SDL_cos(pitch_rad); + double sin_pitch = SDL_sin(pitch_rad); + double mat[9] = { + cos_yaw , 0, -sin_yaw , + sin_yaw*sin_pitch, cos_pitch, cos_yaw*sin_pitch, + sin_yaw*cos_pitch, -sin_pitch, cos_yaw*cos_pitch + }; + SDL_SetRenderDrawColor(renderer, 64, 64, 64, 255); + for (k = 0; k < MAP_BOX_EDGES_LEN; k++) { + const float *line = edges[k]; + float ax = (float)(mat[0] * (line[0] - x0) + mat[1] * (line[1] - y0) + mat[2] * (line[2] - z0)); + float ay = (float)(mat[3] * (line[0] - x0) + mat[4] * (line[1] - y0) + mat[5] * (line[2] - z0)); + float az = (float)(mat[6] * (line[0] - x0) + mat[7] * (line[1] - y0) + mat[8] * (line[2] - z0)); + float bx = (float)(mat[0] * (line[3] - x0) + mat[1] * (line[4] - y0) + mat[2] * (line[5] - z0)); + float by = (float)(mat[3] * (line[3] - x0) + mat[4] * (line[4] - y0) + mat[5] * (line[5] - z0)); + float bz = (float)(mat[6] * (line[3] - x0) + mat[7] * (line[4] - y0) + mat[8] * (line[5] - z0)); + drawClippedSegment(renderer, ax, ay, az, bx, by, bz, hor_origin, ver_origin, cam_origin, 1); + } + for (j = 0; j < players_len; j++) { + if (i == j) continue; + const Player *target = &players[j]; + SDL_SetRenderDrawColor(renderer, target->color[0], target->color[1], target->color[2], 255); + for (k = 0; k < 2; k++) { + double rx = target->pos[0] - player->pos[0]; + double ry = target->pos[1] - player->pos[1] + (target->radius - target->height) * (float)k; + double rz = target->pos[2] - player->pos[2]; + double dx = mat[0] * rx + mat[1] * ry + mat[2] * rz; + double dy = mat[3] * rx + mat[4] * ry + mat[5] * rz; + double dz = mat[6] * rx + mat[7] * ry + mat[8] * rz; + double r_eff = target->radius * cam_origin / dz; + if (!(dz < 0)) continue; + drawCircle(renderer, (float)(r_eff), (float)(hor_origin - cam_origin*dx/dz), (float)(ver_origin + cam_origin*dy/dz)); + } + } + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderLine(renderer, hor_origin, ver_origin-10, hor_origin, ver_origin+10); + SDL_RenderLine(renderer, hor_origin-10, ver_origin, hor_origin+10, ver_origin); + } + } + SDL_SetRenderClipRect(renderer, 0); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderDebugText(renderer, 0, 0, debug_string); + SDL_RenderPresent(renderer); +} + +static void initPlayers(Player *players, int len) +{ + int i; + for (i = 0; i < len; i++) { + players[i].pos[0] = 8.0 * (i & 1 ? -1.0 : 1.0); + players[i].pos[1] = 0; + players[i].pos[2] = 8.0 * (i & 1 ? -1.0 : 1.0) * (i & 2 ? -1.0 : 1.0); + players[i].vel[0] = 0; + players[i].vel[1] = 0; + players[i].vel[2] = 0; + players[i].yaw = 0x20000000 + (i & 1 ? 0x80000000 : 0) + (i & 2 ? 0x40000000 : 0); + players[i].pitch = -0x08000000; + players[i].radius = 0.5f; + players[i].height = 1.5f; + players[i].wasd = 0; + players[i].mouse = 0; + players[i].keyboard = 0; + players[i].color[0] = (1 << (i / 2)) & 2 ? 0 : 0xff; + players[i].color[1] = (1 << (i / 2)) & 1 ? 0 : 0xff; + players[i].color[2] = (1 << (i / 2)) & 4 ? 0 : 0xff; + players[i].color[0] = (i & 1) ? players[i].color[0] : ~players[i].color[0]; + players[i].color[1] = (i & 1) ? players[i].color[1] : ~players[i].color[1]; + players[i].color[2] = (i & 1) ? players[i].color[2] : ~players[i].color[2]; + } +} + +static void initEdges(int scale, float (*edges)[6], int edges_len) +{ + int i, j; + const float r = (float)scale; + const int map[24] = { + 0,1 , 1,3 , 3,2 , 2,0 , + 7,6 , 6,4 , 4,5 , 5,7 , + 6,2 , 3,7 , 0,4 , 5,1 + }; + for(i = 0; i < 12; i++) { + for (j = 0; j < 3; j++) { + edges[i][j+0] = (map[i*2+0] & (1 << j) ? r : -r); + edges[i][j+3] = (map[i*2+1] & (1 << j) ? r : -r); + } + } + for(i = 0; i < scale; i++) { + float d = (float)(i * 2); + for (j = 0; j < 2; j++) { + edges[i+12][3*j+0] = j ? r : -r; + edges[i+12][3*j+1] = -r; + edges[i+12][3*j+2] = d-r; + edges[i+12+scale][3*j+0] = d-r; + edges[i+12+scale][3*j+1] = -r; + edges[i+12+scale][3*j+2] = j ? r : -r; + } + } +} + +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + if (!SDL_SetAppMetadata("Example splitscreen shooter game", "1.0", "com.example.woodeneye-008")) { + return SDL_APP_FAILURE; + } + int i; + for (i = 0; i < SDL_arraysize(extended_metadata); i++) { + if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) { + return SDL_APP_FAILURE; + } + } + + AppState *as = SDL_calloc(1, sizeof(AppState)); + if (!as) { + return SDL_APP_FAILURE; + } else { + *appstate = as; + } + + if (!SDL_Init(SDL_INIT_VIDEO)) { + return SDL_APP_FAILURE; + } + if (!SDL_CreateWindowAndRenderer("examples/demo/woodeneye-008", 640, 480, 0, &as->window, &as->renderer)) { + return SDL_APP_FAILURE; + } + + as->player_count = 1; + initPlayers(as->players, MAX_PLAYER_COUNT); + initEdges(MAP_BOX_SCALE, as->edges, MAP_BOX_EDGES_LEN); + debug_string[0] = 0; + + SDL_SetRenderVSync(as->renderer, false); + SDL_SetWindowRelativeMouseMode(as->window, true); + SDL_SetHintWithPriority(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1", SDL_HINT_OVERRIDE); + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + AppState *as = appstate; + Player *players = as->players; + int player_count = as->player_count; + int i; + switch (event->type) { + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + break; + case SDL_EVENT_MOUSE_REMOVED: + for (i = 0; i < player_count; i++) { + if (players[i].mouse == event->mdevice.which) { + players[i].mouse = 0; + } + } + break; + case SDL_EVENT_KEYBOARD_REMOVED: + for (i = 0; i < player_count; i++) { + if (players[i].keyboard == event->kdevice.which) { + players[i].keyboard = 0; + } + } + break; + case SDL_EVENT_MOUSE_MOTION: { + SDL_MouseID id = event->motion.which; + int index = whoseMouse(id, players, player_count); + if (index >= 0) { + players[index].yaw -= ((int)event->motion.xrel) * 0x00080000; + players[index].pitch = SDL_max(-0x40000000, SDL_min(0x40000000, players[index].pitch - ((int)event->motion.yrel) * 0x00080000)); + } else if (id) { + for (i = 0; i < MAX_PLAYER_COUNT; i++) { + if (players[i].mouse == 0) { + players[i].mouse = id; + as->player_count = SDL_max(as->player_count, i + 1); + break; + } + } + } + break; + } + case SDL_EVENT_MOUSE_BUTTON_DOWN: { + SDL_MouseID id = event->button.which; + int index = whoseMouse(id, players, player_count); + if (index >= 0) { + shoot(index, players, player_count); + } + break; + } + case SDL_EVENT_KEY_DOWN: { + SDL_Keycode sym = event->key.key; + SDL_KeyboardID id = event->key.which; + int index = whoseKeyboard(id, players, player_count); + if (index >= 0) { + if (sym == SDLK_W) players[index].wasd |= 1; + if (sym == SDLK_A) players[index].wasd |= 2; + if (sym == SDLK_S) players[index].wasd |= 4; + if (sym == SDLK_D) players[index].wasd |= 8; + if (sym == SDLK_SPACE) players[index].wasd |= 16; + } else if (id) { + for (i = 0; i < MAX_PLAYER_COUNT; i++) { + if (players[i].keyboard == 0) { + players[i].keyboard = id; + as->player_count = SDL_max(as->player_count, i + 1); + break; + } + } + } + break; + } + case SDL_EVENT_KEY_UP: { + SDL_Keycode sym = event->key.key; + SDL_KeyboardID id = event->key.which; + if (sym == SDLK_ESCAPE) return SDL_APP_SUCCESS; + int index = whoseKeyboard(id, players, player_count); + if (index >= 0) { + if (sym == SDLK_W) players[index].wasd &= 30; + if (sym == SDLK_A) players[index].wasd &= 29; + if (sym == SDLK_S) players[index].wasd &= 27; + if (sym == SDLK_D) players[index].wasd &= 23; + if (sym == SDLK_SPACE) players[index].wasd &= 15; + } + break; + } + } + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) +{ + AppState *as = appstate; + static Uint64 accu = 0; + static Uint64 last = 0; + static Uint64 past = 0; + Uint64 now = SDL_GetTicksNS(); + Uint64 dt_ns = now - past; + update(as->players, as->player_count, dt_ns); + draw(as->renderer, (const float (*)[6])as->edges, as->players, as->player_count); + if (now - last > 999999999) { + last = now; + SDL_snprintf(debug_string, sizeof(debug_string), "%" SDL_PRIu64 " fps", accu); + accu = 0; + } + past = now; + accu += 1; + Uint64 elapsed = SDL_GetTicksNS() - now; + if (elapsed < 999999) { + SDL_DelayNS(999999 - elapsed); + } + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_free(appstate); // just free the memory, SDL will clean up the window/renderer for us. +} \ No newline at end of file diff --git a/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/README.txt b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/README.txt new file mode 100644 index 0000000..3a80b69 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/README.txt @@ -0,0 +1,7 @@ + +How many monkeys does it take to write the complete works of Shakespeare? + + Now you can find out! + +Cheer on your favorite monkey as they bash keyboards on their way through classic literature. + diff --git a/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/infinite-monkeys.c b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/infinite-monkeys.c new file mode 100644 index 0000000..a8bfad1 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/infinite-monkeys.c @@ -0,0 +1,377 @@ +/* + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static char *text; +static const char *end; +static const char *progress; +static SDL_Time start_time; +static SDL_Time end_time; +typedef struct { + Uint32 *text; + int length; +} Line; +int row = 0; +int rows = 0; +int cols = 0; +static Line **lines; +static Line monkey_chars; +static int monkeys = 100; + +/* The highest and lowest scancodes a monkey can hit */ +#define MIN_MONKEY_SCANCODE SDL_SCANCODE_A +#define MAX_MONKEY_SCANCODE SDL_SCANCODE_SLASH + +static const char *default_text = +"Jabberwocky, by Lewis Carroll\n" +"\n" +"'Twas brillig, and the slithy toves\n" +" Did gyre and gimble in the wabe:\n" +"All mimsy were the borogoves,\n" +" And the mome raths outgrabe.\n" +"\n" +"\"Beware the Jabberwock, my son!\n" +" The jaws that bite, the claws that catch!\n" +"Beware the Jubjub bird, and shun\n" +" The frumious Bandersnatch!\"\n" +"\n" +"He took his vorpal sword in hand;\n" +" Long time the manxome foe he sought-\n" +"So rested he by the Tumtum tree\n" +" And stood awhile in thought.\n" +"\n" +"And, as in uffish thought he stood,\n" +" The Jabberwock, with eyes of flame,\n" +"Came whiffling through the tulgey wood,\n" +" And burbled as it came!\n" +"\n" +"One, two! One, two! And through and through\n" +" The vorpal blade went snicker-snack!\n" +"He left it dead, and with its head\n" +" He went galumphing back.\n" +"\n" +"\"And hast thou slain the Jabberwock?\n" +" Come to my arms, my beamish boy!\n" +"O frabjous day! Callooh! Callay!\"\n" +" He chortled in his joy.\n" +"\n" +"'Twas brillig, and the slithy toves\n" +" Did gyre and gimble in the wabe:\n" +"All mimsy were the borogoves,\n" +" And the mome raths outgrabe.\n"; + + +static void FreeLines(void) +{ + int i; + + if (rows > 0 && cols > 0) { + for (i = 0; i < rows; ++i) { + SDL_free(lines[i]->text); + SDL_free(lines[i]); + } + SDL_free(lines); + lines = NULL; + } + SDL_free(monkey_chars.text); + monkey_chars.text = NULL; +} + +static void OnWindowSizeChanged(void) +{ + int w, h; + + if (!SDL_GetCurrentRenderOutputSize(renderer, &w, &h)) { + return; + } + + FreeLines(); + + row = 0; + rows = (h / SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) - 4; + cols = (w / SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE); + if (rows > 0 && cols > 0) { + int i; + + lines = (Line **)SDL_malloc(rows * sizeof(Line *)); + if (lines) { + for (i = 0; i < rows; ++i) { + lines[i] = (Line *)SDL_malloc(sizeof(Line)); + if (!lines[i]) { + FreeLines(); + break; + } + lines[i]->text = (Uint32 *)SDL_malloc(cols * sizeof(Uint32)); + if (!lines[i]->text) { + FreeLines(); + break; + } + lines[i]->length = 0; + } + } + + monkey_chars.text = (Uint32 *)SDL_malloc(cols * sizeof(Uint32)); + if (monkey_chars.text) { + for (i = 0; i < cols; ++i) { + monkey_chars.text[i] = ' '; + } + monkey_chars.length = cols; + } + } +} + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int arg = 1; + + SDL_SetAppMetadata("Infinite Monkeys", "1.0", "com.example.infinite-monkeys"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/demo/infinite-monkeys", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + SDL_SetRenderVSync(renderer, 1); + + if (argv[arg] && SDL_strcmp(argv[arg], "--monkeys") == 0) { + ++arg; + if (argv[arg]) { + monkeys = SDL_atoi(argv[arg]); + ++arg; + } else { + SDL_Log("Usage: %s [--monkeys N] [file.txt]", argv[0]); + return SDL_APP_FAILURE; + } + } + + if (argv[arg]) { + const char *file = argv[arg]; + size_t size; + text = (char *)SDL_LoadFile(file, &size); + if (!text) { + SDL_Log("Couldn't open %s: %s", file, SDL_GetError()); + return SDL_APP_FAILURE; + } + end = text + size; + } else { + text = SDL_strdup(default_text); + end = text + SDL_strlen(text); + } + progress = text; + + SDL_GetCurrentTime(&start_time); + + OnWindowSizeChanged(); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + switch (event->type) { + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + OnWindowSizeChanged(); + break; + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +static void DisplayLine(float x, float y, Line *line) +{ + /* Allocate maximum space potentially needed for this line */ + char *utf8 = (char *)SDL_malloc(line->length * 4 + 1); + if (utf8) { + char *spot = utf8; + int i; + + for (i = 0; i < line->length; ++i) { + spot = SDL_UCS4ToUTF8(line->text[i], spot); + } + *spot = '\0'; + + SDL_RenderDebugText(renderer, x, y, utf8); + SDL_free(utf8); + } +} + +static bool CanMonkeyType(Uint32 ch) +{ + SDL_Keymod modstate; + SDL_Scancode scancode = SDL_GetScancodeFromKey(ch, &modstate); + if (scancode < MIN_MONKEY_SCANCODE || scancode > MAX_MONKEY_SCANCODE) { + return false; + } + /* Monkeys can hit the shift key, but nothing else */ + if ((modstate & ~SDL_KMOD_SHIFT) != 0) { + return false; + } + return true; +} + +static void AdvanceRow(void) +{ + Line *line; + + ++row; + line = lines[row % rows]; + line->length = 0; +} + +static void AddMonkeyChar(int monkey, Uint32 ch) +{ + if (monkey >= 0 && monkey_chars.text) { + monkey_chars.text[(monkey % cols)] = ch; + } + + if (lines) { + if (ch == '\n') { + AdvanceRow(); + } else { + Line *line = lines[row % rows]; + line->text[line->length++] = ch; + if (line->length == cols) { + AdvanceRow(); + } + } + } + + SDL_StepUTF8(&progress, NULL); +} + +static Uint32 GetNextChar(void) +{ + Uint32 ch = 0; + while (progress < end) { + const char *spot = progress; + ch = SDL_StepUTF8(&spot, NULL); + if (CanMonkeyType(ch)) { + break; + } else { + /* This is a freebie, monkeys can't type this */ + AddMonkeyChar(-1, ch); + } + } + return ch; +} + +static Uint32 MonkeyPlay(void) +{ + int count = (MAX_MONKEY_SCANCODE - MIN_MONKEY_SCANCODE + 1); + SDL_Scancode scancode = (SDL_Scancode)(MIN_MONKEY_SCANCODE + SDL_rand(count)); + SDL_Keymod modstate = (SDL_rand(2) ? SDL_KMOD_SHIFT : 0); + + return SDL_GetKeyFromScancode(scancode, modstate, false); +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + int i, monkey; + Uint32 next_char = 0, ch; + float x, y; + char *caption = NULL; + SDL_Time now, elapsed; + int hours, minutes, seconds; + SDL_FRect rect; + + for (monkey = 0; monkey < monkeys; ++monkey) { + if (next_char == 0) { + next_char = GetNextChar(); + if (!next_char) { + /* All done! */ + break; + } + } + + ch = MonkeyPlay(); + if (ch == next_char) { + AddMonkeyChar(monkey, ch); + next_char = 0; + } + } + + /* Clear the screen */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + + /* Show the text already decoded */ + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); + x = 0.0f; + y = 0.0f; + if (lines) { + int row_offset = row - rows + 1; + if (row_offset < 0) { + row_offset = 0; + } + for (i = 0; i < rows; ++i) { + Line *line = lines[(row_offset + i) % rows]; + DisplayLine(x, y, line); + y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE; + } + + /* Show the caption */ + y = (float)((rows + 1) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE); + if (progress == end) { + if (!end_time) { + SDL_GetCurrentTime(&end_time); + } + now = end_time; + } else { + SDL_GetCurrentTime(&now); + } + elapsed = (now - start_time); + elapsed /= SDL_NS_PER_SECOND; + seconds = (int)(elapsed % 60); + elapsed /= 60; + minutes = (int)(elapsed % 60); + elapsed /= 60; + hours = (int)elapsed; + SDL_asprintf(&caption, "Monkeys: %d - %dH:%dM:%dS", monkeys, hours, minutes, seconds); + if (caption) { + SDL_RenderDebugText(renderer, x, y, caption); + SDL_free(caption); + } + y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE; + + /* Show the characters currently typed */ + DisplayLine(x, y, &monkey_chars); + y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE; + } + + /* Show the current progress */ + SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); + rect.x = x; + rect.y = y; + rect.w = ((float)(progress - text) / (end - text)) * (cols * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE); + rect.h = (float)SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE; + SDL_RenderFillRect(renderer, &rect); + + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ + + FreeLines(); + SDL_free(text); +} + diff --git a/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/onmouseover.webp new file mode 100644 index 0000000..f522974 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/thumbnail.png b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/thumbnail.png new file mode 100644 index 0000000..418390b Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/README.txt b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/README.txt new file mode 100644 index 0000000..dbee4ce --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/README.txt @@ -0,0 +1,4 @@ +An implementation of the BytePusher VM + +For example programs and more information about BytePusher, see +https://esolangs.org/wiki/BytePusher diff --git a/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/bytepusher.c b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/bytepusher.c new file mode 100644 index 0000000..acb2ea4 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/bytepusher.c @@ -0,0 +1,416 @@ +/* + * An implementation of the BytePusher VM. + * + * For example programs and more information about BytePusher, see + * https://esolangs.org/wiki/BytePusher + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS +#include +#include +#include + +#define SCREEN_W 256 +#define SCREEN_H 256 +#define RAM_SIZE 0x1000000 +#define FRAMES_PER_SECOND 60 +#define SAMPLES_PER_FRAME 256 +#define NS_PER_SECOND (Uint64)SDL_NS_PER_SECOND +#define MAX_AUDIO_LATENCY_FRAMES 5 + +#define IO_KEYBOARD 0 +#define IO_PC 2 +#define IO_SCREEN_PAGE 5 +#define IO_AUDIO_BANK 6 + +typedef struct { + Uint8 ram[RAM_SIZE + 8]; + Uint8 screenbuf[SCREEN_W * SCREEN_H]; + Uint64 last_tick; + Uint64 tick_acc; + SDL_Window* window; + SDL_Renderer* renderer; + SDL_Surface* screen; + SDL_Texture* screentex; + SDL_Texture* rendertarget; /* we need this render target for text to look good */ + SDL_AudioStream* audiostream; + char status[SCREEN_W / 8]; + int status_ticks; + Uint16 keystate; + bool display_help; + bool positional_input; +} BytePusher; + +static const struct { + const char *key; + const char *value; +} extended_metadata[] = { + { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/04-bytepusher/" }, + { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" }, + { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" }, + { SDL_PROP_APP_METADATA_TYPE_STRING, "game" } +}; + +static inline Uint16 read_u16(const BytePusher* vm, Uint32 addr) { + const Uint8* ptr = &vm->ram[addr]; + return ((Uint16)ptr[0] << 8) | ((Uint16)ptr[1]); +} + +static inline Uint32 read_u24(const BytePusher* vm, Uint32 addr) { + const Uint8* ptr = &vm->ram[addr]; + return ((Uint32)ptr[0] << 16) | ((Uint32)ptr[1] << 8) | ((Uint32)ptr[2]); +} + +static void set_status(BytePusher* vm, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + SDL_vsnprintf(vm->status, sizeof(vm->status), fmt, args); + va_end(args); + vm->status[sizeof(vm->status) - 1] = 0; + vm->status_ticks = FRAMES_PER_SECOND * 3; +} + +static bool load(BytePusher* vm, SDL_IOStream* stream, bool closeio) { + size_t bytes_read = 0; + bool ok = true; + + SDL_memset(vm->ram, 0, RAM_SIZE); + + if (!stream) { + return false; + } + + while (bytes_read < RAM_SIZE) { + size_t read = SDL_ReadIO(stream, &vm->ram[bytes_read], RAM_SIZE - bytes_read); + bytes_read += read; + if (read == 0) { + ok = SDL_GetIOStatus(stream) == SDL_IO_STATUS_EOF; + break; + } + } + if (closeio) { + SDL_CloseIO(stream); + } + + SDL_ClearAudioStream(vm->audiostream); + + vm->display_help = !ok; + return ok; +} + +static const char* filename(const char* path) { + size_t i = SDL_strlen(path) + 1; + while (i > 0) { + i -= 1; + if (path[i] == '/' || path[i] == '\\') { + return path + i + 1; + } + } + return path; +} + +static bool load_file(BytePusher* vm, const char* path) { + if (load(vm, SDL_IOFromFile(path, "rb"), true)) { + set_status(vm, "loaded %s", filename(path)); + return true; + } else { + set_status(vm, "load failed: %s", filename(path)); + return false; + } +} + +static void print(BytePusher* vm, int x, int y, const char* str) { + SDL_SetRenderDrawColor(vm->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderDebugText(vm->renderer, (float)(x + 1), (float)(y + 1), str); + SDL_SetRenderDrawColor(vm->renderer, 0xff, 0xff, 0xff, SDL_ALPHA_OPAQUE); + SDL_RenderDebugText(vm->renderer, (float)x, (float)y, str); + SDL_SetRenderDrawColor(vm->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); +} + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { + BytePusher* vm; + SDL_Palette* palette; + SDL_Rect usable_bounds; + SDL_AudioSpec audiospec = { SDL_AUDIO_S8, 1, SAMPLES_PER_FRAME * FRAMES_PER_SECOND }; + SDL_DisplayID primary_display; + SDL_PropertiesID texprops; + int zoom = 2; + int i; + Uint8 r, g, b; + (void)argc; + (void)argv; + + if (!SDL_SetAppMetadata("SDL 3 BytePusher", "1.0", "com.example.SDL3BytePusher")) { + return SDL_APP_FAILURE; + } + + for (i = 0; i < (int)SDL_arraysize(extended_metadata); i++) { + if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) { + return SDL_APP_FAILURE; + } + } + + if (!SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO)) { + return SDL_APP_FAILURE; + } + + if (!(vm = (BytePusher *)SDL_calloc(1, sizeof(*vm)))) { + return SDL_APP_FAILURE; + } + *(BytePusher**)appstate = vm; + + vm->display_help = true; + + primary_display = SDL_GetPrimaryDisplay(); + if (SDL_GetDisplayUsableBounds(primary_display, &usable_bounds)) { + int zoom_w = (usable_bounds.w - usable_bounds.x) * 2 / 3 / SCREEN_W; + int zoom_h = (usable_bounds.h - usable_bounds.y) * 2 / 3 / SCREEN_H; + zoom = zoom_w < zoom_h ? zoom_w : zoom_h; + if (zoom < 1) { + zoom = 1; + } + } + + if (!SDL_CreateWindowAndRenderer("SDL 3 BytePusher", + SCREEN_W * zoom, SCREEN_H * zoom, SDL_WINDOW_RESIZABLE, + &vm->window, &vm->renderer + )) { + return SDL_APP_FAILURE; + } + + if (!SDL_SetRenderLogicalPresentation( + vm->renderer, SCREEN_W, SCREEN_H, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE + )) { + return SDL_APP_FAILURE; + } + + if (!(vm->screen = SDL_CreateSurfaceFrom( + SCREEN_W, SCREEN_H, SDL_PIXELFORMAT_INDEX8, vm->screenbuf, SCREEN_W + ))) { + return SDL_APP_FAILURE; + } + + if (!(palette = SDL_CreateSurfacePalette(vm->screen))) { + return SDL_APP_FAILURE; + } + i = 0; + for (r = 0; r < 6; ++r) { + for (g = 0; g < 6; ++g) { + for (b = 0; b < 6; ++b, ++i) { + SDL_Color color = { (Uint8)(r * 0x33), (Uint8)(g * 0x33), (Uint8)(b * 0x33), SDL_ALPHA_OPAQUE }; + palette->colors[i] = color; + } + } + } + for (; i < 256; ++i) { + SDL_Color color = { 0, 0, 0, SDL_ALPHA_OPAQUE }; + palette->colors[i] = color; + } + + texprops = SDL_CreateProperties(); + SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STREAMING); + SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, SCREEN_W); + SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, SCREEN_H); + vm->screentex = SDL_CreateTextureWithProperties(vm->renderer, texprops); + SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_TARGET); + vm->rendertarget = SDL_CreateTextureWithProperties(vm->renderer, texprops); + SDL_DestroyProperties(texprops); + if (!vm->screentex || !vm->rendertarget) { + return SDL_APP_FAILURE; + } + SDL_SetTextureScaleMode(vm->screentex, SDL_SCALEMODE_NEAREST); + SDL_SetTextureScaleMode(vm->rendertarget, SDL_SCALEMODE_NEAREST); + + if (!(vm->audiostream = SDL_OpenAudioDeviceStream( + SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audiospec, NULL, NULL + ))) { + return SDL_APP_FAILURE; + } + SDL_SetAudioStreamGain(vm->audiostream, 0.1f); /* examples are loud! */ + SDL_ResumeAudioStreamDevice(vm->audiostream); + + set_status(vm, "renderer: %s", SDL_GetRendererName(vm->renderer)); + + vm->last_tick = SDL_GetTicksNS(); + vm->tick_acc = NS_PER_SECOND; + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void* appstate) { + BytePusher* vm = (BytePusher*)appstate; + + Uint64 tick = SDL_GetTicksNS(); + Uint64 delta = tick - vm->last_tick; + bool updated, skip_audio; + + vm->last_tick = tick; + + vm->tick_acc += delta * FRAMES_PER_SECOND; + updated = vm->tick_acc >= NS_PER_SECOND; + skip_audio = vm->tick_acc >= MAX_AUDIO_LATENCY_FRAMES * NS_PER_SECOND; + + if (skip_audio) { + // don't let audio fall too far behind + SDL_ClearAudioStream(vm->audiostream); + } + + while (vm->tick_acc >= NS_PER_SECOND) { + Uint32 pc; + int i; + + vm->tick_acc -= NS_PER_SECOND; + + vm->ram[IO_KEYBOARD] = (Uint8)(vm->keystate >> 8); + vm->ram[IO_KEYBOARD + 1] = (Uint8)(vm->keystate); + + pc = read_u24(vm, IO_PC); + for (i = 0; i < SCREEN_W * SCREEN_H; ++i) { + Uint32 src = read_u24(vm, pc); + Uint32 dst = read_u24(vm, pc + 3); + vm->ram[dst] = vm->ram[src]; + pc = read_u24(vm, pc + 6); + } + + if (!skip_audio || vm->tick_acc < NS_PER_SECOND) { + SDL_PutAudioStreamData( + vm->audiostream, + &vm->ram[(Uint32)read_u16(vm, IO_AUDIO_BANK) << 8], + SAMPLES_PER_FRAME + ); + } + } + + if (updated) { + SDL_Surface *tex; + + SDL_SetRenderTarget(vm->renderer, vm->rendertarget); + + if (!SDL_LockTextureToSurface(vm->screentex, NULL, &tex)) { + return SDL_APP_FAILURE; + } + vm->screen->pixels = &vm->ram[(Uint32)vm->ram[IO_SCREEN_PAGE] << 16]; + SDL_BlitSurface(vm->screen, NULL, tex, NULL); + SDL_UnlockTexture(vm->screentex); + + SDL_RenderTexture(vm->renderer, vm->screentex, NULL, NULL); + } + + if (vm->display_help) { + print(vm, 4, 4, "Drop a BytePusher file in this"); + print(vm, 8, 12, "window to load and run it!"); + print(vm, 4, 28, "Press ENTER to switch between"); + print(vm, 8, 36, "positional and symbolic input."); + } + + if (vm->status_ticks > 0) { + vm->status_ticks -= 1; + print(vm, 4, SCREEN_H - 12, vm->status); + } + + SDL_SetRenderTarget(vm->renderer, NULL); + SDL_RenderClear(vm->renderer); + SDL_RenderTexture(vm->renderer, vm->rendertarget, NULL, NULL); + SDL_RenderPresent(vm->renderer); + + return SDL_APP_CONTINUE; +} + +static Uint16 keycode_mask(SDL_Keycode key) { + int index; + if (key >= SDLK_0 && key <= SDLK_9) { + index = key - SDLK_0; + } else if (key >= SDLK_A && key <= SDLK_F) { + index = key - SDLK_A + 10; + } else { + return 0; + } + return (Uint16)1 << index; +} + +static Uint16 scancode_mask(SDL_Scancode scancode) { + int index; + switch (scancode) { + case SDL_SCANCODE_1: index = 0x1; break; + case SDL_SCANCODE_2: index = 0x2; break; + case SDL_SCANCODE_3: index = 0x3; break; + case SDL_SCANCODE_4: index = 0xc; break; + case SDL_SCANCODE_Q: index = 0x4; break; + case SDL_SCANCODE_W: index = 0x5; break; + case SDL_SCANCODE_E: index = 0x6; break; + case SDL_SCANCODE_R: index = 0xd; break; + case SDL_SCANCODE_A: index = 0x7; break; + case SDL_SCANCODE_S: index = 0x8; break; + case SDL_SCANCODE_D: index = 0x9; break; + case SDL_SCANCODE_F: index = 0xe; break; + case SDL_SCANCODE_Z: index = 0xa; break; + case SDL_SCANCODE_X: index = 0x0; break; + case SDL_SCANCODE_C: index = 0xb; break; + case SDL_SCANCODE_V: index = 0xf; break; + default: return 0; + } + return (Uint16)1 << index; +} + +SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { + BytePusher* vm = (BytePusher*)appstate; + + switch (event->type) { + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + + case SDL_EVENT_DROP_FILE: + load_file(vm, event->drop.data); + break; + + case SDL_EVENT_KEY_DOWN: +#ifndef __EMSCRIPTEN__ + if (event->key.key == SDLK_ESCAPE) { + return SDL_APP_SUCCESS; + } +#endif + if (event->key.key == SDLK_RETURN) { + vm->positional_input = !vm->positional_input; + vm->keystate = 0; + if (vm->positional_input) { + set_status(vm, "switched to positional input"); + } else { + set_status(vm, "switched to symbolic input"); + } + } + if (vm->positional_input) { + vm->keystate |= scancode_mask(event->key.scancode); + } else { + vm->keystate |= keycode_mask(event->key.key); + } + break; + + case SDL_EVENT_KEY_UP: + if (vm->positional_input) { + vm->keystate &= ~scancode_mask(event->key.scancode); + } else { + vm->keystate &= ~keycode_mask(event->key.key); + } + break; + } + + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void* appstate, SDL_AppResult result) { + if (result == SDL_APP_FAILURE) { + SDL_Log("Error: %s", SDL_GetError()); + } + if (appstate) { + BytePusher* vm = (BytePusher*)appstate; + SDL_DestroyAudioStream(vm->audiostream); + SDL_DestroyTexture(vm->rendertarget); + SDL_DestroyTexture(vm->screentex); + SDL_DestroySurface(vm->screen); + SDL_DestroyRenderer(vm->renderer); + SDL_DestroyWindow(vm->window); + SDL_free(vm); + } +} diff --git a/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/onmouseover.webp new file mode 100644 index 0000000..b99e7dd Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/thumbnail.png b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/thumbnail.png new file mode 100644 index 0000000..891aa8f Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/demo/description.txt b/src/contrib/SDL-3.2.20/examples/demo/description.txt new file mode 100644 index 0000000..77bcbb7 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/description.txt @@ -0,0 +1 @@ +Full game and app demos \ No newline at end of file diff --git a/src/contrib/SDL-3.2.20/examples/highlight-plugin.lua b/src/contrib/SDL-3.2.20/examples/highlight-plugin.lua new file mode 100644 index 0000000..9598ec9 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/highlight-plugin.lua @@ -0,0 +1,79 @@ +-- This code adapted from https://gitlab.com/saalen/highlight/-/wikis/Plug-Ins + +-- first add a description of what the plug-in does +Description="Add wiki.libsdl.org reference links to HTML, LaTeX or RTF output" + +-- define the plugin categories (ie. supported output formats; languages) +Categories = { "c", "c++" } + +-- the syntaxUpdate function contains code related to syntax recognition +function syntaxUpdate(desc) + + -- if the current file is not C/C++ file we exit + if desc~="C and C++" then + return + end + + -- this function returns a qt-project reference link of the given token + function getURL(token) + -- generate the URL + url='https://wiki.libsdl.org/SDL3/'.. token + + -- embed the URL in a hyperlink according to the output format + -- first HTML, then LaTeX and RTF + if (HL_OUTPUT== HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then + return ''.. token .. '' + elseif (HL_OUTPUT == HL_FORMAT_LATEX) then + return '\\href{'..url..'}{'..token..'}' + elseif (HL_OUTPUT == HL_FORMAT_RTF) then + return '{{\\field{\\*\\fldinst HYPERLINK "' + ..url..'" }{\\fldrslt\\ul\\ulc0 '..token..'}}}' + end + end + + -- the Decorate function will be invoked for every recognized token + function Decorate(token, state) + + -- we are only interested in keywords, preprocessor or default items + if (state ~= HL_STANDARD and state ~= HL_KEYWORD and + state ~=HL_PREPROC) then + return + end + + -- SDL keywords start with SDL_ + -- if this pattern applies to the token, we return the URL + -- if we return nothing, the token is outputted as is + if ( (token == "Uint8") or (token == "Uint16") or (token == "Uint32") or (token == "Uint64") or + (token == "Sint8") or (token == "Sint16") or (token == "Sint32") or (token == "Sint64") or + (string.find(token, "SDL_") == 1) ) then + return getURL(token) + end + + end +end + +-- the themeUpdate function contains code related to the theme +function themeUpdate(desc) + -- the Injections table can be used to add style information to the theme + + -- HTML: we add additional CSS style information to beautify hyperlinks, + -- they should have the same color as their surrounding tags + if (HL_OUTPUT == HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then + Injections[#Injections+1]= + "a.hl, a.hl:visited {color:inherit;font-weight:inherit;text-decoration:none}" + + -- LaTeX: hyperlinks require the hyperref package, so we add this here + -- the colorlinks and pdfborderstyle options remove ugly boxes in the output + elseif (HL_OUTPUT==HL_FORMAT_LATEX) then + Injections[#Injections+1]= + "\\usepackage[colorlinks=false, pdfborderstyle={/S/U/W 1}]{hyperref}" + end +end + +-- let highlight load the chunks +Plugins={ + { Type="lang", Chunk=syntaxUpdate }, + { Type="theme", Chunk=themeUpdate }, +} + diff --git a/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/README.txt b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/README.txt new file mode 100644 index 0000000..89e2bee --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/README.txt @@ -0,0 +1,2 @@ +This example code looks for the current joystick state once per frame, +and draws a visual representation of it. diff --git a/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/joystick-polling.c b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/joystick-polling.c new file mode 100644 index 0000000..6eb23b8 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/joystick-polling.c @@ -0,0 +1,193 @@ +/* + * This example code looks for the current joystick state once per frame, + * and draws a visual representation of it. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +/* Joysticks are low-level interfaces: there's something with a bunch of + buttons, axes and hats, in no understood order or position. This is + a flexible interface, but you'll need to build some sort of configuration + UI to let people tell you what button, etc, does what. On top of this + interface, SDL offers the "gamepad" API, which works with lots of devices, + and knows how to map arbitrary buttons and such to look like an + Xbox/PlayStation/etc gamepad. This is easier, and better, for many games, + but isn't necessarily a good fit for complex apps and hardware. A flight + simulator, a realistic racing game, etc, might want this interface instead + of gamepads. */ + +/* SDL can handle multiple joysticks, but for simplicity, this program only + deals with the first stick it sees. */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Joystick *joystick = NULL; +static SDL_Color colors[64]; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int i; + + SDL_SetAppMetadata("Example Input Joystick Polling", "1.0", "com.example.input-joystick-polling"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/input/joystick-polling", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + for (i = 0; i < SDL_arraysize(colors); i++) { + colors[i].r = SDL_rand(255); + colors[i].g = SDL_rand(255); + colors[i].b = SDL_rand(255); + colors[i].a = 255; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } else if (event->type == SDL_EVENT_JOYSTICK_ADDED) { + /* this event is sent for each hotplugged stick, but also each already-connected joystick during SDL_Init(). */ + if (joystick == NULL) { /* we don't have a stick yet and one was added, open it! */ + joystick = SDL_OpenJoystick(event->jdevice.which); + if (!joystick) { + SDL_Log("Failed to open joystick ID %u: %s", (unsigned int) event->jdevice.which, SDL_GetError()); + } + } + } else if (event->type == SDL_EVENT_JOYSTICK_REMOVED) { + if (joystick && (SDL_GetJoystickID(joystick) == event->jdevice.which)) { + SDL_CloseJoystick(joystick); /* our joystick was unplugged. */ + joystick = NULL; + } + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + int winw = 640, winh = 480; + const char *text = "Plug in a joystick, please."; + float x, y; + int i; + + if (joystick) { /* we have a stick opened? */ + text = SDL_GetJoystickName(joystick); + } + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_GetWindowSize(window, &winw, &winh); + + /* note that you can get input as events, instead of polling, which is + better since it won't miss button presses if the system is lagging, + but often times checking the current state per-frame is good enough, + and maybe better if you'd rather _drop_ inputs due to lag. */ + + if (joystick) { /* we have a stick opened? */ + const float size = 30.0f; + int total; + + /* draw axes as bars going across middle of screen. We don't know if it's an X or Y or whatever axis, so we can't do more than this. */ + total = SDL_GetNumJoystickAxes(joystick); + y = (winh - (total * size)) / 2; + x = ((float) winw) / 2.0f; + for (i = 0; i < total; i++) { + const SDL_Color *color = &colors[i % SDL_arraysize(colors)]; + const float val = (((float) SDL_GetJoystickAxis(joystick, i)) / 32767.0f); /* make it -1.0f to 1.0f */ + const float dx = x + (val * x); + const SDL_FRect dst = { dx, y, x - SDL_fabsf(dx), size }; + SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a); + SDL_RenderFillRect(renderer, &dst); + y += size; + } + + /* draw buttons as blocks across top of window. We only know the button numbers, but not where they are on the device. */ + total = SDL_GetNumJoystickButtons(joystick); + x = (winw - (total * size)) / 2; + for (i = 0; i < total; i++) { + const SDL_Color *color = &colors[i % SDL_arraysize(colors)]; + const SDL_FRect dst = { x, 0.0f, size, size }; + if (SDL_GetJoystickButton(joystick, i)) { + SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a); + } else { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + } + SDL_RenderFillRect(renderer, &dst); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, color->a); + SDL_RenderRect(renderer, &dst); /* outline it */ + x += size; + } + + /* draw hats across the bottom of the screen. */ + total = SDL_GetNumJoystickHats(joystick); + x = ((winw - (total * (size * 2.0f))) / 2.0f) + (size / 2.0f); + y = ((float) winh) - size; + for (i = 0; i < total; i++) { + const SDL_Color *color = &colors[i % SDL_arraysize(colors)]; + const float thirdsize = size / 3.0f; + const SDL_FRect cross[] = { { x, y + thirdsize, size, thirdsize }, { x + thirdsize, y, thirdsize, size } }; + const Uint8 hat = SDL_GetJoystickHat(joystick, i); + + SDL_SetRenderDrawColor(renderer, 90, 90, 90, 255); + SDL_RenderFillRects(renderer, cross, SDL_arraysize(cross)); + + SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a); + + if (hat & SDL_HAT_UP) { + const SDL_FRect dst = { x + thirdsize, y, thirdsize, thirdsize }; + SDL_RenderFillRect(renderer, &dst); + } + + if (hat & SDL_HAT_RIGHT) { + const SDL_FRect dst = { x + (thirdsize * 2), y + thirdsize, thirdsize, thirdsize }; + SDL_RenderFillRect(renderer, &dst); + } + + if (hat & SDL_HAT_DOWN) { + const SDL_FRect dst = { x + thirdsize, y + (thirdsize * 2), thirdsize, thirdsize }; + SDL_RenderFillRect(renderer, &dst); + } + + if (hat & SDL_HAT_LEFT) { + const SDL_FRect dst = { x, y + thirdsize, thirdsize, thirdsize }; + SDL_RenderFillRect(renderer, &dst); + } + + x += size * 2; + } + } + + x = (((float) winw) - (SDL_strlen(text) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f; + y = (((float) winh) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2.0f; + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderDebugText(renderer, x, y, text); + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + if (joystick) { + SDL_CloseJoystick(joystick); + } + + /* SDL will clean up the window/renderer for us. */ +} diff --git a/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/onmouseover.webp new file mode 100644 index 0000000..484539c Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/thumbnail.png b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/thumbnail.png new file mode 100644 index 0000000..4faebba Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/README.txt b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/README.txt new file mode 100644 index 0000000..d87ac0a --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/README.txt @@ -0,0 +1,2 @@ +This example code looks for joystick input in the event handler, and +reports any changes as a flood of info. diff --git a/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/joystick-events.c b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/joystick-events.c new file mode 100644 index 0000000..cc01d84 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/joystick-events.c @@ -0,0 +1,232 @@ +/* + * This example code looks for joystick input in the event handler, and + * reports any changes as a flood of info. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +/* Joysticks are low-level interfaces: there's something with a bunch of + buttons, axes and hats, in no understood order or position. This is + a flexible interface, but you'll need to build some sort of configuration + UI to let people tell you what button, etc, does what. On top of this + interface, SDL offers the "gamepad" API, which works with lots of devices, + and knows how to map arbitrary buttons and such to look like an + Xbox/PlayStation/etc gamepad. This is easier, and better, for many games, + but isn't necessarily a good fit for complex apps and hardware. A flight + simulator, a realistic racing game, etc, might want this interface instead + of gamepads. */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Color colors[64]; + +#define MOTION_EVENT_COOLDOWN 40 + +typedef struct EventMessage +{ + char *str; + SDL_Color color; + Uint64 start_ticks; + struct EventMessage *next; +} EventMessage; + +static EventMessage messages; +static EventMessage *messages_tail = &messages; + +static const char *hat_state_string(Uint8 state) +{ + switch (state) { + case SDL_HAT_CENTERED: return "CENTERED"; + case SDL_HAT_UP: return "UP"; + case SDL_HAT_RIGHT: return "RIGHT"; + case SDL_HAT_DOWN: return "DOWN"; + case SDL_HAT_LEFT: return "LEFT"; + case SDL_HAT_RIGHTUP: return "RIGHT+UP"; + case SDL_HAT_RIGHTDOWN: return "RIGHT+DOWN"; + case SDL_HAT_LEFTUP: return "LEFT+UP"; + case SDL_HAT_LEFTDOWN: return "LEFT+DOWN"; + default: break; + } + return "UNKNOWN"; +} + +static const char *battery_state_string(SDL_PowerState state) +{ + switch (state) { + case SDL_POWERSTATE_ERROR: return "ERROR"; + case SDL_POWERSTATE_UNKNOWN: return "UNKNOWN"; + case SDL_POWERSTATE_ON_BATTERY: return "ON BATTERY"; + case SDL_POWERSTATE_NO_BATTERY: return "NO BATTERY"; + case SDL_POWERSTATE_CHARGING: return "CHARGING"; + case SDL_POWERSTATE_CHARGED: return "CHARGED"; + default: break; + } + return "UNKNOWN"; +} + +static void add_message(SDL_JoystickID jid, const char *fmt, ...) +{ + const SDL_Color *color = &colors[((size_t) jid) % SDL_arraysize(colors)]; + EventMessage *msg = NULL; + char *str = NULL; + va_list ap; + + msg = (EventMessage *) SDL_calloc(1, sizeof (*msg)); + if (!msg) { + return; // oh well. + } + + va_start(ap, fmt); + SDL_vasprintf(&str, fmt, ap); + va_end(ap); + if (!str) { + SDL_free(msg); + return; // oh well. + } + + msg->str = str; + SDL_copyp(&msg->color, color); + msg->start_ticks = SDL_GetTicks(); + msg->next = NULL; + + messages_tail->next = msg; + messages_tail = msg; +} + + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int i; + + SDL_SetAppMetadata("Example Input Joystick Events", "1.0", "com.example.input-joystick-events"); + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/input/joystick-events", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + colors[0].r = colors[0].g = colors[0].b = colors[0].a = 255; + for (i = 1; i < SDL_arraysize(colors); i++) { + colors[i].r = SDL_rand(255); + colors[i].g = SDL_rand(255); + colors[i].b = SDL_rand(255); + colors[i].a = 255; + } + + add_message(0, "Please plug in a joystick."); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } else if (event->type == SDL_EVENT_JOYSTICK_ADDED) { + /* this event is sent for each hotplugged stick, but also each already-connected joystick during SDL_Init(). */ + const SDL_JoystickID which = event->jdevice.which; + SDL_Joystick *joystick = SDL_OpenJoystick(which); + if (!joystick) { + add_message(which, "Joystick #%u add, but not opened: %s", (unsigned int) which, SDL_GetError()); + } else { + add_message(which, "Joystick #%u ('%s') added", (unsigned int) which, SDL_GetJoystickName(joystick)); + } + } else if (event->type == SDL_EVENT_JOYSTICK_REMOVED) { + const SDL_JoystickID which = event->jdevice.which; + SDL_Joystick *joystick = SDL_GetJoystickFromID(which); + if (joystick) { + SDL_CloseJoystick(joystick); /* the joystick was unplugged. */ + } + add_message(which, "Joystick #%u removed", (unsigned int) which); + } else if (event->type == SDL_EVENT_JOYSTICK_AXIS_MOTION) { + static Uint64 axis_motion_cooldown_time = 0; /* these are spammy, only show every X milliseconds. */ + const Uint64 now = SDL_GetTicks(); + if (now >= axis_motion_cooldown_time) { + const SDL_JoystickID which = event->jaxis.which; + axis_motion_cooldown_time = now + MOTION_EVENT_COOLDOWN; + add_message(which, "Joystick #%u axis %d -> %d", (unsigned int) which, (int) event->jaxis.axis, (int) event->jaxis.value); + } + } else if (event->type == SDL_EVENT_JOYSTICK_BALL_MOTION) { + static Uint64 ball_motion_cooldown_time = 0; /* these are spammy, only show every X milliseconds. */ + const Uint64 now = SDL_GetTicks(); + if (now >= ball_motion_cooldown_time) { + const SDL_JoystickID which = event->jball.which; + ball_motion_cooldown_time = now + MOTION_EVENT_COOLDOWN; + add_message(which, "Joystick #%u ball %d -> %d, %d", (unsigned int) which, (int) event->jball.ball, (int) event->jball.xrel, (int) event->jball.yrel); + } + } else if (event->type == SDL_EVENT_JOYSTICK_HAT_MOTION) { + const SDL_JoystickID which = event->jhat.which; + add_message(which, "Joystick #%u hat %d -> %s", (unsigned int) which, (int) event->jhat.hat, hat_state_string(event->jhat.value)); + } else if ((event->type == SDL_EVENT_JOYSTICK_BUTTON_UP) || (event->type == SDL_EVENT_JOYSTICK_BUTTON_DOWN)) { + const SDL_JoystickID which = event->jbutton.which; + add_message(which, "Joystick #%u button %d -> %s", (unsigned int) which, (int) event->jbutton.button, event->jbutton.down ? "PRESSED" : "RELEASED"); + } else if (event->type == SDL_EVENT_JOYSTICK_BATTERY_UPDATED) { + const SDL_JoystickID which = event->jbattery.which; + add_message(which, "Joystick #%u battery -> %s - %d%%", (unsigned int) which, battery_state_string(event->jbattery.state), event->jbattery.percent); + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const Uint64 now = SDL_GetTicks(); + const float msg_lifetime = 3500.0f; /* milliseconds a message lives for. */ + EventMessage *msg = messages.next; + float prev_y = 0.0f; + int winw = 640, winh = 480; + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_GetWindowSize(window, &winw, &winh); + + while (msg) { + float x, y; + const float life_percent = ((float) (now - msg->start_ticks)) / msg_lifetime; + if (life_percent >= 1.0f) { /* msg is done. */ + messages.next = msg->next; + if (messages_tail == msg) { + messages_tail = &messages; + } + SDL_free(msg->str); + SDL_free(msg); + msg = messages.next; + continue; + } + x = (((float) winw) - (SDL_strlen(msg->str) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f; + y = ((float) winh) * life_percent; + if ((prev_y != 0.0f) && ((prev_y - y) < ((float) SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE))) { + msg->start_ticks = now; + break; // wait for the previous message to tick up a little. + } + + SDL_SetRenderDrawColor(renderer, msg->color.r, msg->color.g, msg->color.b, (Uint8) (((float) msg->color.a) * (1.0f - life_percent))); + SDL_RenderDebugText(renderer, x, y, msg->str); + + prev_y = y; + msg = msg->next; + } + + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. We let the joysticks leak. */ +} diff --git a/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/onmouseover.webp new file mode 100644 index 0000000..05a9b42 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/thumbnail.png b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/thumbnail.png new file mode 100644 index 0000000..07f3ff1 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/README.txt b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/README.txt new file mode 100644 index 0000000..693cda8 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/README.txt @@ -0,0 +1,3 @@ +You need something with a pen/stylus for this to work. + +This takes pen input and draws lines. Lines are darker when you press harder. diff --git a/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/drawing-lines.c b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/drawing-lines.c new file mode 100644 index 0000000..d0d78ea --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/drawing-lines.c @@ -0,0 +1,121 @@ +/* + * This example code reads pen/stylus input and draws lines. Darker lines + * for harder pressure. + * + * SDL can track multiple pens, but for simplicity here, this assumes any + * pen input we see was from one device. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *render_target = NULL; +static float pressure = 0.0f; +static float previous_touch_x = -1.0f; +static float previous_touch_y = -1.0f; +static float tilt_x = 0.0f; +static float tilt_y = 0.0f; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int w, h; + + SDL_SetAppMetadata("Example Pen Drawing Lines", "1.0", "com.example.pen-drawing-lines"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/pen/drawing-lines", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* we make a render target so we can draw lines to it and not have to record and redraw every pen stroke each frame. + Instead rendering a frame for us is a single texture draw. */ + + /* make sure the render target matches output size (for hidpi displays, etc) so drawing matches the pen's position on a tablet display. */ + SDL_GetRenderOutputSize(renderer, &w, &h); + render_target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h); + if (!render_target) { + SDL_Log("Couldn't create render target: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* just blank the render target to gray to start. */ + SDL_SetRenderTarget(renderer, render_target); + SDL_SetRenderDrawColor(renderer, 100, 100, 100, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + SDL_SetRenderTarget(renderer, NULL); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + + /* There are several events that track the specific stages of pen activity, + but we're only going to look for motion and pressure, for simplicity. */ + if (event->type == SDL_EVENT_PEN_MOTION) { + /* you can check for when the pen is touching, but if pressure > 0.0f, it's definitely touching! */ + if (pressure > 0.0f) { + if (previous_touch_x >= 0.0f) { /* only draw if we're moving while touching */ + /* draw with the alpha set to the pressure, so you effectively get a fainter line for lighter presses. */ + SDL_SetRenderTarget(renderer, render_target); + SDL_SetRenderDrawColorFloat(renderer, 0, 0, 0, pressure); + SDL_RenderLine(renderer, previous_touch_x, previous_touch_y, event->pmotion.x, event->pmotion.y); + } + previous_touch_x = event->pmotion.x; + previous_touch_y = event->pmotion.y; + } else { + previous_touch_x = previous_touch_y = -1.0f; + } + } else if (event->type == SDL_EVENT_PEN_AXIS) { + if (event->paxis.axis == SDL_PEN_AXIS_PRESSURE) { + pressure = event->paxis.value; /* remember new pressure for later draws. */ + } else if(event->paxis.axis == SDL_PEN_AXIS_XTILT) { + tilt_x = event->paxis.value; + } else if(event->paxis.axis == SDL_PEN_AXIS_YTILT) { + tilt_y = event->paxis.value; + } + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + char debug_text[1024]; + + /* make sure we're drawing to the window and not the render target */ + SDL_SetRenderTarget(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); /* just in case. */ + SDL_RenderTexture(renderer, render_target, NULL, NULL); + SDL_snprintf(debug_text, sizeof(debug_text), "Tilt: %f %f", tilt_x, tilt_y); + SDL_RenderDebugText(renderer, 0, 8, debug_text); + SDL_RenderPresent(renderer); + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(render_target); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/onmouseover.webp new file mode 100644 index 0000000..f9c4d3d Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/thumbnail.png b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/thumbnail.png new file mode 100644 index 0000000..3403d35 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/01-clear/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/README.txt new file mode 100644 index 0000000..ce9ef81 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/README.txt @@ -0,0 +1,3 @@ +This example code creates an SDL window and renderer, and then clears the +window to a different color every frame, so you'll effectively get a window +that's smoothly fading between colors. diff --git a/src/contrib/SDL-3.2.20/examples/renderer/01-clear/clear.c b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/clear.c new file mode 100644 index 0000000..5b2b7dc --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/clear.c @@ -0,0 +1,68 @@ +/* + * This example code creates an SDL window and renderer, and then clears the + * window to a different color every frame, so you'll effectively get a window + * that's smoothly fading between colors. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("Example Renderer Clear", "1.0", "com.example.renderer-clear"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */ + /* choose the color for the frame we will draw. The sine wave trick makes it fade between colors smoothly. */ + const float red = (float) (0.5 + 0.5 * SDL_sin(now)); + const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3)); + const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3)); + SDL_SetRenderDrawColorFloat(renderer, red, green, blue, SDL_ALPHA_OPAQUE_FLOAT); /* new color, full alpha. */ + + /* clear the window to the draw color. */ + SDL_RenderClear(renderer); + + /* put the newly-cleared rendering on the screen. */ + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/01-clear/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/onmouseover.webp new file mode 100644 index 0000000..a0062fe Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/01-clear/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/thumbnail.png new file mode 100644 index 0000000..b255675 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/README.txt new file mode 100644 index 0000000..82da8e5 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/README.txt @@ -0,0 +1,7 @@ +This example creates an SDL window and renderer, and then draws some lines, +rectangles and points to it every frame. + +This is just a quick overview of simple drawing primitives; futher examples +will explore them in more detail. + + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/primitives.c b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/primitives.c new file mode 100644 index 0000000..5cfd731 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/primitives.c @@ -0,0 +1,95 @@ +/* + * This example creates an SDL window and renderer, and then draws some lines, + * rectangles and points to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_FPoint points[500]; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int i; + + SDL_SetAppMetadata("Example Renderer Primitives", "1.0", "com.example.renderer-primitives"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/primitives", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* set up some random points */ + for (i = 0; i < SDL_arraysize(points); i++) { + points[i].x = (SDL_randf() * 440.0f) + 100.0f; + points[i].y = (SDL_randf() * 280.0f) + 100.0f; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect rect; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 33, 33, 33, SDL_ALPHA_OPAQUE); /* dark gray, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* draw a filled rectangle in the middle of the canvas. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */ + rect.x = rect.y = 100; + rect.w = 440; + rect.h = 280; + SDL_RenderFillRect(renderer, &rect); + + /* draw some points across the canvas. */ + SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */ + SDL_RenderPoints(renderer, points, SDL_arraysize(points)); + + /* draw a unfilled rectangle in-set a little bit. */ + SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */ + rect.x += 30; + rect.y += 30; + rect.w -= 60; + rect.h -= 60; + SDL_RenderRect(renderer, &rect); + + /* draw two lines in an X across the whole canvas. */ + SDL_SetRenderDrawColor(renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /* yellow, full alpha */ + SDL_RenderLine(renderer, 0, 0, 640, 480); + SDL_RenderLine(renderer, 0, 480, 640, 0); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/thumbnail.png new file mode 100644 index 0000000..4ddf2ab Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/03-lines/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/README.txt new file mode 100644 index 0000000..4abeab6 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, and then draws a something +roughly like a Christmas tree with nothing but lines, every frame. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/03-lines/lines.c b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/lines.c new file mode 100644 index 0000000..54f7eb1 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/lines.c @@ -0,0 +1,93 @@ +/* + * This example creates an SDL window and renderer, and then draws some lines + * to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("Example Renderer Lines", "1.0", "com.example.renderer-lines"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/lines", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + int i; + + /* Lines (line segments, really) are drawn in terms of points: a set of + X and Y coordinates, one set for each end of the line. + (0, 0) is the top left of the window, and larger numbers go down + and to the right. This isn't how geometry works, but this is pretty + standard in 2D graphics. */ + static const SDL_FPoint line_points[] = { + { 100, 354 }, { 220, 230 }, { 140, 230 }, { 320, 100 }, { 500, 230 }, + { 420, 230 }, { 540, 354 }, { 400, 354 }, { 100, 354 } + }; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 100, 100, 100, SDL_ALPHA_OPAQUE); /* grey, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* You can draw lines, one at a time, like these brown ones... */ + SDL_SetRenderDrawColor(renderer, 127, 49, 32, SDL_ALPHA_OPAQUE); + SDL_RenderLine(renderer, 240, 450, 400, 450); + SDL_RenderLine(renderer, 240, 356, 400, 356); + SDL_RenderLine(renderer, 240, 356, 240, 450); + SDL_RenderLine(renderer, 400, 356, 400, 450); + + /* You can also draw a series of connected lines in a single batch... */ + SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); + SDL_RenderLines(renderer, line_points, SDL_arraysize(line_points)); + + /* here's a bunch of lines drawn out from a center point in a circle. */ + /* we randomize the color of each line, so it functions as animation. */ + for (i = 0; i < 360; i++) { + const float size = 30.0f; + const float x = 320.0f; + const float y = 95.0f - (size / 2.0f); + SDL_SetRenderDrawColor(renderer, SDL_rand(256), SDL_rand(256), SDL_rand(256), SDL_ALPHA_OPAQUE); + SDL_RenderLine(renderer, x, y, x + SDL_sinf((float) i) * size, y + SDL_cosf((float) i) * size); + } + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/03-lines/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/onmouseover.webp new file mode 100644 index 0000000..5d3b3fc Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/03-lines/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/thumbnail.png new file mode 100644 index 0000000..9d0ff10 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/04-points/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/04-points/README.txt new file mode 100644 index 0000000..00e9419 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/04-points/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, and then draws a bunch of +single points, moving across the screen. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/04-points/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/04-points/onmouseover.webp new file mode 100644 index 0000000..04582da Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/04-points/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/04-points/points.c b/src/contrib/SDL-3.2.20/examples/renderer/04-points/points.c new file mode 100644 index 0000000..b7b5c21 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/04-points/points.c @@ -0,0 +1,118 @@ +/* + * This example creates an SDL window and renderer, and then draws some points + * to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static Uint64 last_time = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +#define NUM_POINTS 500 +#define MIN_PIXELS_PER_SECOND 30 /* move at least this many pixels per second. */ +#define MAX_PIXELS_PER_SECOND 60 /* move this many pixels per second at most. */ + +/* (track everything as parallel arrays instead of a array of structs, + so we can pass the coordinates to the renderer in a single function call.) */ + +/* Points are plotted as a set of X and Y coordinates. + (0, 0) is the top left of the window, and larger numbers go down + and to the right. This isn't how geometry works, but this is pretty + standard in 2D graphics. */ +static SDL_FPoint points[NUM_POINTS]; +static float point_speeds[NUM_POINTS]; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int i; + + SDL_SetAppMetadata("Example Renderer Points", "1.0", "com.example.renderer-points"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/points", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* set up the data for a bunch of points. */ + for (i = 0; i < SDL_arraysize(points); i++) { + points[i].x = SDL_randf() * ((float) WINDOW_WIDTH); + points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT); + point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND)); + } + + last_time = SDL_GetTicks(); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const Uint64 now = SDL_GetTicks(); + const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */ + int i; + + /* let's move all our points a little for a new frame. */ + for (i = 0; i < SDL_arraysize(points); i++) { + const float distance = elapsed * point_speeds[i]; + points[i].x += distance; + points[i].y += distance; + if ((points[i].x >= WINDOW_WIDTH) || (points[i].y >= WINDOW_HEIGHT)) { + /* off the screen; restart it elsewhere! */ + if (SDL_rand(2)) { + points[i].x = SDL_randf() * ((float) WINDOW_WIDTH); + points[i].y = 0.0f; + } else { + points[i].x = 0.0f; + points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT); + } + point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND)); + } + } + + last_time = now; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */ + SDL_RenderPoints(renderer, points, SDL_arraysize(points)); /* draw all the points! */ + + /* You can also draw single points with SDL_RenderPoint(), but it's + cheaper (sometimes significantly so) to do them all at once. */ + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/04-points/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/04-points/thumbnail.png new file mode 100644 index 0000000..5627113 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/04-points/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/README.txt new file mode 100644 index 0000000..26613c7 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, and then draws a few +rectangles that change size each frame. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/onmouseover.webp new file mode 100644 index 0000000..cdfd376 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/rectangles.c b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/rectangles.c new file mode 100644 index 0000000..3aa7242 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/rectangles.c @@ -0,0 +1,112 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * rectangles to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("Example Renderer Rectangles", "1.0", "com.example.renderer-rectangles"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/rectangles", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect rects[16]; + const Uint64 now = SDL_GetTicks(); + int i; + + /* we'll have the rectangles grow and shrink over a few seconds. */ + const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; + const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Rectangles are comprised of set of X and Y coordinates, plus width and + height. (0, 0) is the top left of the window, and larger numbers go + down and to the right. This isn't how geometry works, but this is + pretty standard in 2D graphics. */ + + /* Let's draw a single rectangle (square, really). */ + rects[0].x = rects[0].y = 100; + rects[0].w = rects[0].h = 100 + (100 * scale); + SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */ + SDL_RenderRect(renderer, &rects[0]); + + /* Now let's draw several rectangles with one function call. */ + for (i = 0; i < 3; i++) { + const float size = (i+1) * 50.0f; + rects[i].w = rects[i].h = size + (size * scale); + rects[i].x = (WINDOW_WIDTH - rects[i].w) / 2; /* center it. */ + rects[i].y = (WINDOW_HEIGHT - rects[i].h) / 2; /* center it. */ + } + SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */ + SDL_RenderRects(renderer, rects, 3); /* draw three rectangles at once */ + + /* those were rectangle _outlines_, really. You can also draw _filled_ rectangles! */ + rects[0].x = 400; + rects[0].y = 50; + rects[0].w = 100 + (100 * scale); + rects[0].h = 50 + (50 * scale); + SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */ + SDL_RenderFillRect(renderer, &rects[0]); + + /* ...and also fill a bunch of rectangles at once... */ + for (i = 0; i < SDL_arraysize(rects); i++) { + const float w = (float) (WINDOW_WIDTH / SDL_arraysize(rects)); + const float h = i * 8.0f; + rects[i].x = i * w; + rects[i].y = WINDOW_HEIGHT - h; + rects[i].w = w; + rects[i].h = h; + } + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */ + SDL_RenderFillRects(renderer, rects, SDL_arraysize(rects)); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/thumbnail.png new file mode 100644 index 0000000..64e6688 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/06-textures/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/README.txt new file mode 100644 index 0000000..21c3f0b --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, loads a texture from a +.bmp file, and then draws it a few times each frame. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/06-textures/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/onmouseover.webp new file mode 100644 index 0000000..467afd8 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/06-textures/textures.c b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/textures.c new file mode 100644 index 0000000..f4ad707 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/textures.c @@ -0,0 +1,127 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * textures to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Textures", "1.0", "com.example.renderer-textures"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect dst_rect; + const Uint64 now = SDL_GetTicks(); + + /* we'll have some textures move around over a few seconds. */ + const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; + const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Just draw the static texture a few times. You can think of it like a + stamp, there isn't a limit to the number of times you can draw with it. */ + + /* top left */ + dst_rect.x = (100.0f * scale); + dst_rect.y = 0.0f; + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* center this one. */ + dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f; + dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f; + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* bottom right. */ + dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) - (100.0f * scale); + dst_rect.y = (float) (WINDOW_HEIGHT - texture_height); + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/06-textures/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/thumbnail.png new file mode 100644 index 0000000..b33ba31 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/README.txt new file mode 100644 index 0000000..c250571 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, then a streaming texture that +it will update every frame before drawing it to the screen. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/onmouseover.webp new file mode 100644 index 0000000..7c29693 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/streaming-textures.c b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/streaming-textures.c new file mode 100644 index 0000000..bf309bc --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/streaming-textures.c @@ -0,0 +1,109 @@ +/* + * This example creates an SDL window and renderer, and then draws a streaming + * texture to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; + +#define TEXTURE_SIZE 150 + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("Example Renderer Streaming Textures", "1.0", "com.example.renderer-streaming-textures"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/streaming-textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE); + if (!texture) { + SDL_Log("Couldn't create streaming texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect dst_rect; + const Uint64 now = SDL_GetTicks(); + SDL_Surface *surface = NULL; + + /* we'll have some color move around over a few seconds. */ + const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; + const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; + + /* To update a streaming texture, you need to lock it first. This gets you access to the pixels. + Note that this is considered a _write-only_ operation: the buffer you get from locking + might not acutally have the existing contents of the texture, and you have to write to every + locked pixel! */ + + /* You can use SDL_LockTexture() to get an array of raw pixels, but we're going to use + SDL_LockTextureToSurface() here, because it wraps that array in a temporary SDL_Surface, + letting us use the surface drawing functions instead of lighting up individual pixels. */ + if (SDL_LockTextureToSurface(texture, NULL, &surface)) { + SDL_Rect r; + SDL_FillSurfaceRect(surface, NULL, SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, 0, 0, 0)); /* make the whole surface black */ + r.w = TEXTURE_SIZE; + r.h = TEXTURE_SIZE / 10; + r.x = 0; + r.y = (int) (((float) (TEXTURE_SIZE - r.h)) * ((scale + 1.0f) / 2.0f)); + SDL_FillSurfaceRect(surface, &r, SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, 0, 255, 0)); /* make a strip of the surface green */ + SDL_UnlockTexture(texture); /* upload the changes (and frees the temporary surface)! */ + } + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 66, 66, 66, SDL_ALPHA_OPAQUE); /* grey, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Just draw the static texture a few times. You can think of it like a + stamp, there isn't a limit to the number of times you can draw with it. */ + + /* Center this one. It'll draw the latest version of the texture we drew while it was locked. */ + dst_rect.x = ((float) (WINDOW_WIDTH - TEXTURE_SIZE)) / 2.0f; + dst_rect.y = ((float) (WINDOW_HEIGHT - TEXTURE_SIZE)) / 2.0f; + dst_rect.w = dst_rect.h = (float) TEXTURE_SIZE; + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/thumbnail.png new file mode 100644 index 0000000..60c2a9f Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/README.txt new file mode 100644 index 0000000..4ae46bc --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, loads a texture from a .bmp +file, and then draws it, rotating around the center of the screen. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/onmouseover.webp new file mode 100644 index 0000000..69735ce Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/rotating-textures.c b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/rotating-textures.c new file mode 100644 index 0000000..bf318ef --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/rotating-textures.c @@ -0,0 +1,113 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * rotated textures to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Rotating Textures", "1.0", "com.example.renderer-rotating-textures"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/rotating-textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FPoint center; + SDL_FRect dst_rect; + const Uint64 now = SDL_GetTicks(); + + /* we'll have a texture rotate around over 2 seconds (2000 milliseconds). 360 degrees in a circle! */ + const float rotation = (((float) ((int) (now % 2000))) / 2000.0f) * 360.0f; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Center this one, and draw it with some rotation so it spins! */ + dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f; + dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f; + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + /* rotate it around the center of the texture; you can rotate it from a different point, too! */ + center.x = texture_width / 2.0f; + center.y = texture_height / 2.0f; + SDL_RenderTextureRotated(renderer, texture, NULL, &dst_rect, rotation, ¢er, SDL_FLIP_NONE); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/thumbnail.png new file mode 100644 index 0000000..12c51e1 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/README.txt new file mode 100644 index 0000000..e13a6ec --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, loads a texture from a .bmp +file, and then draws it, scaling it up and down. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/onmouseover.webp new file mode 100644 index 0000000..bcc967c Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/scaling-textures.c b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/scaling-textures.c new file mode 100644 index 0000000..66060ed --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/scaling-textures.c @@ -0,0 +1,110 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * textures to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Scaling Textures", "1.0", "com.example.renderer-scaling-textures"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/scaling-textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect dst_rect; + const Uint64 now = SDL_GetTicks(); + + /* we'll have the texture grow and shrink over a few seconds. */ + const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; + const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* center this one and make it grow and shrink. */ + dst_rect.w = (float) texture_width + (texture_width * scale); + dst_rect.h = (float) texture_height + (texture_height * scale); + dst_rect.x = (WINDOW_WIDTH - dst_rect.w) / 2.0f; + dst_rect.y = (WINDOW_HEIGHT - dst_rect.h) / 2.0f; + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/thumbnail.png new file mode 100644 index 0000000..c0a24c2 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/README.txt new file mode 100644 index 0000000..d76d0cc --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, loads a texture from a .bmp +file, and then draws geometry (arbitrary polygons) using it. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/geometry.c b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/geometry.c new file mode 100644 index 0000000..77ff863 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/geometry.c @@ -0,0 +1,166 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * geometry (arbitrary polygons) to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Geometry", "1.0", "com.example.renderer-geometry"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/geometry", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const Uint64 now = SDL_GetTicks(); + + /* we'll have the triangle grow and shrink over a few seconds. */ + const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; + const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; + const float size = 200.0f + (200.0f * scale); + + SDL_Vertex vertices[4]; + int i; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Draw a single triangle with a different color at each vertex. Center this one and make it grow and shrink. */ + /* You always draw triangles with this, but you can string triangles together to form polygons. */ + SDL_zeroa(vertices); + vertices[0].position.x = ((float) WINDOW_WIDTH) / 2.0f; + vertices[0].position.y = (((float) WINDOW_HEIGHT) - size) / 2.0f; + vertices[0].color.r = 1.0f; + vertices[0].color.a = 1.0f; + vertices[1].position.x = (((float) WINDOW_WIDTH) + size) / 2.0f; + vertices[1].position.y = (((float) WINDOW_HEIGHT) + size) / 2.0f; + vertices[1].color.g = 1.0f; + vertices[1].color.a = 1.0f; + vertices[2].position.x = (((float) WINDOW_WIDTH) - size) / 2.0f; + vertices[2].position.y = (((float) WINDOW_HEIGHT) + size) / 2.0f; + vertices[2].color.b = 1.0f; + vertices[2].color.a = 1.0f; + + SDL_RenderGeometry(renderer, NULL, vertices, 3, NULL, 0); + + /* you can also map a texture to the geometry! Texture coordinates go from 0.0f to 1.0f. That will be the location + in the texture bound to this vertex. */ + SDL_zeroa(vertices); + vertices[0].position.x = 10.0f; + vertices[0].position.y = 10.0f; + vertices[0].color.r = vertices[0].color.g = vertices[0].color.b = vertices[0].color.a = 1.0f; + vertices[0].tex_coord.x = 0.0f; + vertices[0].tex_coord.y = 0.0f; + vertices[1].position.x = 150.0f; + vertices[1].position.y = 10.0f; + vertices[1].color.r = vertices[1].color.g = vertices[1].color.b = vertices[1].color.a = 1.0f; + vertices[1].tex_coord.x = 1.0f; + vertices[1].tex_coord.y = 0.0f; + vertices[2].position.x = 10.0f; + vertices[2].position.y = 150.0f; + vertices[2].color.r = vertices[2].color.g = vertices[2].color.b = vertices[2].color.a = 1.0f; + vertices[2].tex_coord.x = 0.0f; + vertices[2].tex_coord.y = 1.0f; + SDL_RenderGeometry(renderer, texture, vertices, 3, NULL, 0); + + /* Did that only draw half of the texture? You can do multiple triangles sharing some vertices, + using indices, to get the whole thing on the screen: */ + + /* Let's just move this over so it doesn't overlap... */ + for (i = 0; i < 3; i++) { + vertices[i].position.x += 450; + } + + /* we need one more vertex, since the two triangles can share two of them. */ + vertices[3].position.x = 600.0f; + vertices[3].position.y = 150.0f; + vertices[3].color.r = vertices[3].color.g = vertices[3].color.b = vertices[3].color.a = 1.0f; + vertices[3].tex_coord.x = 1.0f; + vertices[3].tex_coord.y = 1.0f; + + /* And an index to tell it to reuse some of the vertices between triangles... */ + { + /* 4 vertices, but 6 actual places they used. Indices need less bandwidth to transfer and can reorder vertices easily! */ + const int indices[] = { 0, 1, 2, 1, 2, 3 }; + SDL_RenderGeometry(renderer, texture, vertices, 4, indices, SDL_arraysize(indices)); + } + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/onmouseover.webp new file mode 100644 index 0000000..37a518c Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/thumbnail.png new file mode 100644 index 0000000..89195fb Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/README.txt new file mode 100644 index 0000000..66f233b --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, loads a texture from a +.bmp file, and then draws it a few times each frame, adjusting the colors. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/color-mods.c b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/color-mods.c new file mode 100644 index 0000000..8877232 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/color-mods.c @@ -0,0 +1,134 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * textures to it every frame, adjusting their color. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Color Mods", "1.0", "com.example.renderer-color-mods"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/color-mods", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect dst_rect; + const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */ + /* choose the modulation values for the center texture. The sine wave trick makes it fade between colors smoothly. */ + const float red = (float) (0.5 + 0.5 * SDL_sin(now)); + const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3)); + const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3)); + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Just draw the static texture a few times. You can think of it like a + stamp, there isn't a limit to the number of times you can draw with it. */ + + /* Color modulation multiplies each pixel's red, green, and blue intensities by the mod values, + so multiplying by 1.0f will leave a color intensity alone, 0.0f will shut off that color + completely, etc. */ + + /* top left; let's make this one blue! */ + dst_rect.x = 0.0f; + dst_rect.y = 0.0f; + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + SDL_SetTextureColorModFloat(texture, 0.0f, 0.0f, 1.0f); /* kill all red and green. */ + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* center this one, and have it cycle through red/green/blue modulations. */ + dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f; + dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f; + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + SDL_SetTextureColorModFloat(texture, red, green, blue); + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* bottom right; let's make this one red! */ + dst_rect.x = (float) (WINDOW_WIDTH - texture_width); + dst_rect.y = (float) (WINDOW_HEIGHT - texture_height); + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + SDL_SetTextureColorModFloat(texture, 1.0f, 0.0f, 0.0f); /* kill all green and blue. */ + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/onmouseover.webp new file mode 100644 index 0000000..2157063 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/thumbnail.png new file mode 100644 index 0000000..d471112 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/README.txt new file mode 100644 index 0000000..9da7c7a --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/README.txt @@ -0,0 +1,4 @@ +This example creates an SDL window and renderer, loads a texture +from a .bmp file, and then draws it a few times each frame, adjusting +the viewport before each draw. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/thumbnail.png new file mode 100644 index 0000000..bad5521 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/viewport.c b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/viewport.c new file mode 100644 index 0000000..0a6c015 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/viewport.c @@ -0,0 +1,136 @@ +/* + * This example creates an SDL window and renderer, and then draws some + * textures to it every frame, adjusting the viewport. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Viewport", "1.0", "com.example.renderer-viewport"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/viewport", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + SDL_FRect dst_rect = { 0, 0, (float) texture_width, (float) texture_height }; + SDL_Rect viewport; + + /* Setting a viewport has the effect of limiting the area that rendering + can happen, and making coordinate (0, 0) live somewhere else in the + window. It does _not_ scale rendering to fit the viewport. */ + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Draw once with the whole window as the viewport. */ + viewport.x = 0; + viewport.y = 0; + viewport.w = WINDOW_WIDTH / 2; + viewport.h = WINDOW_HEIGHT / 2; + SDL_SetRenderViewport(renderer, NULL); /* NULL means "use the whole window" */ + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* top right quarter of the window. */ + viewport.x = WINDOW_WIDTH / 2; + viewport.y = WINDOW_HEIGHT / 2; + viewport.w = WINDOW_WIDTH / 2; + viewport.h = WINDOW_HEIGHT / 2; + SDL_SetRenderViewport(renderer, &viewport); + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* bottom 20% of the window. Note it clips the width! */ + viewport.x = 0; + viewport.y = WINDOW_HEIGHT - (WINDOW_HEIGHT / 5); + viewport.w = WINDOW_WIDTH / 5; + viewport.h = WINDOW_HEIGHT / 5; + SDL_SetRenderViewport(renderer, &viewport); + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + /* what happens if you try to draw above the viewport? It should clip! */ + viewport.x = 100; + viewport.y = 200; + viewport.w = WINDOW_WIDTH; + viewport.h = WINDOW_HEIGHT; + SDL_SetRenderViewport(renderer, &viewport); + dst_rect.y = -50; + SDL_RenderTexture(renderer, texture, NULL, &dst_rect); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/README.txt new file mode 100644 index 0000000..48c9f1f --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/README.txt @@ -0,0 +1,5 @@ +This example creates an SDL window and renderer, loads a texture +from a .bmp file, and stretches it across the window. Each frame, we move +the clipping rectangle around, so only a small square of the texture is +actually drawn. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/cliprect.c b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/cliprect.c new file mode 100644 index 0000000..058072c --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/cliprect.c @@ -0,0 +1,137 @@ +/* + * This example creates an SDL window and renderer, and then draws a scene + * to it every frame, while sliding around a clipping rectangle. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 +#define CLIPRECT_SIZE 250 +#define CLIPRECT_SPEED 200 /* pixels per second */ + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static SDL_FPoint cliprect_position; +static SDL_FPoint cliprect_direction; +static Uint64 last_time = 0; + +/* A lot of this program is examples/renderer/02-primitives, so we have a good + visual that we can slide a clip rect around. The actual new magic in here + is the SDL_SetRenderClipRect() function. */ + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Clipping Rectangle", "1.0", "com.example.renderer-cliprect"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/cliprect", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + cliprect_direction.x = cliprect_direction.y = 1.0f; + + last_time = SDL_GetTicks(); + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const SDL_Rect cliprect = { (int) SDL_roundf(cliprect_position.x), (int) SDL_roundf(cliprect_position.y), CLIPRECT_SIZE, CLIPRECT_SIZE }; + const Uint64 now = SDL_GetTicks(); + const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */ + const float distance = elapsed * CLIPRECT_SPEED; + + /* Set a new clipping rectangle position */ + cliprect_position.x += distance * cliprect_direction.x; + if (cliprect_position.x < 0.0f) { + cliprect_position.x = 0.0f; + cliprect_direction.x = 1.0f; + } else if (cliprect_position.x >= (WINDOW_WIDTH - CLIPRECT_SIZE)) { + cliprect_position.x = (WINDOW_WIDTH - CLIPRECT_SIZE) - 1; + cliprect_direction.x = -1.0f; + } + + cliprect_position.y += distance * cliprect_direction.y; + if (cliprect_position.y < 0.0f) { + cliprect_position.y = 0.0f; + cliprect_direction.y = 1.0f; + } else if (cliprect_position.y >= (WINDOW_HEIGHT - CLIPRECT_SIZE)) { + cliprect_position.y = (WINDOW_HEIGHT - CLIPRECT_SIZE) - 1; + cliprect_direction.y = -1.0f; + } + SDL_SetRenderClipRect(renderer, &cliprect); + + last_time = now; + + /* okay, now draw! */ + + /* Note that SDL_RenderClear is _not_ affected by the clipping rectangle! */ + SDL_SetRenderDrawColor(renderer, 33, 33, 33, SDL_ALPHA_OPAQUE); /* grey, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* stretch the texture across the entire window. Only the piece in the + clipping rectangle will actually render, though! */ + SDL_RenderTexture(renderer, texture, NULL, NULL); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/onmouseover.webp new file mode 100644 index 0000000..943eeef Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/thumbnail.png new file mode 100644 index 0000000..127e6fa Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/README.txt new file mode 100644 index 0000000..dd474e6 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/README.txt @@ -0,0 +1,12 @@ +This example creates an SDL window and renderer, and draws a +rotating texture to it, reads back the rendered pixels, converts them to +black and white, and then draws the converted image to a corner of the +screen. + +This isn't necessarily an efficient thing to do--in real life one might +want to do this sort of thing with a render target--but it's just a visual +example of how to use SDL_RenderReadPixels(). + +A better, but less visual, use of SDL_RenderReadPixels() is to make +screenshots: you grab the current contents of the screen, and save the pixels +as a bitmap file or whatever. diff --git a/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/onmouseover.webp b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/onmouseover.webp new file mode 100644 index 0000000..bb4e5c4 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/onmouseover.webp differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/read-pixels.c b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/read-pixels.c new file mode 100644 index 0000000..556b490 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/read-pixels.c @@ -0,0 +1,178 @@ +/* + * This example creates an SDL window and renderer, and draws a + * rotating texture to it, reads back the rendered pixels, converts them to + * black and white, and then draws the converted image to a corner of the + * screen. + * + * This isn't necessarily an efficient thing to do--in real life one might + * want to do this sort of thing with a render target--but it's just a visual + * example of how to use SDL_RenderReadPixels(). + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; +static int texture_width = 0; +static int texture_height = 0; +static SDL_Texture *converted_texture = NULL; +static int converted_texture_width = 0; +static int converted_texture_height = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_Surface *surface = NULL; + char *bmp_path = NULL; + + SDL_SetAppMetadata("Example Renderer Read Pixels", "1.0", "com.example.renderer-read-pixels"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/read-pixels", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D + engines refer to these as "sprites." We'll do a static texture (upload once, draw many + times) with data from a bitmap file. */ + + /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access. + Load a .bmp into a surface, move it to a texture from there. */ + SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */ + surface = SDL_LoadBMP(bmp_path); + if (!surface) { + SDL_Log("Couldn't load bitmap: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_free(bmp_path); /* done with this, the file is loaded. */ + + texture_width = surface->w; + texture_height = surface->h; + + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + SDL_Log("Couldn't create static texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const Uint64 now = SDL_GetTicks(); + SDL_Surface *surface; + SDL_FPoint center; + SDL_FRect dst_rect; + + /* we'll have a texture rotate around over 2 seconds (2000 milliseconds). 360 degrees in a circle! */ + const float rotation = (((float) ((int) (now % 2000))) / 2000.0f) * 360.0f; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + /* Center this one, and draw it with some rotation so it spins! */ + dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f; + dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f; + dst_rect.w = (float) texture_width; + dst_rect.h = (float) texture_height; + /* rotate it around the center of the texture; you can rotate it from a different point, too! */ + center.x = texture_width / 2.0f; + center.y = texture_height / 2.0f; + SDL_RenderTextureRotated(renderer, texture, NULL, &dst_rect, rotation, ¢er, SDL_FLIP_NONE); + + /* this next whole thing is _super_ expensive. Seriously, don't do this in real life. */ + + /* Download the pixels of what has just been rendered. This has to wait for the GPU to finish rendering it and everything before it, + and then make an expensive copy from the GPU to system RAM! */ + surface = SDL_RenderReadPixels(renderer, NULL); + + /* This is also expensive, but easier: convert the pixels to a format we want. */ + if (surface && (surface->format != SDL_PIXELFORMAT_RGBA8888) && (surface->format != SDL_PIXELFORMAT_BGRA8888)) { + SDL_Surface *converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA8888); + SDL_DestroySurface(surface); + surface = converted; + } + + if (surface) { + /* Rebuild converted_texture if the dimensions have changed (window resized, etc). */ + if ((surface->w != converted_texture_width) || (surface->h != converted_texture_height)) { + SDL_DestroyTexture(converted_texture); + converted_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, surface->w, surface->h); + if (!converted_texture) { + SDL_Log("Couldn't (re)create conversion texture: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + converted_texture_width = surface->w; + converted_texture_height = surface->h; + } + + /* Turn each pixel into either black or white. This is a lousy technique but it works here. + In real life, something like Floyd-Steinberg dithering might work + better: https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering*/ + int x, y; + for (y = 0; y < surface->h; y++) { + Uint32 *pixels = (Uint32 *) (((Uint8 *) surface->pixels) + (y * surface->pitch)); + for (x = 0; x < surface->w; x++) { + Uint8 *p = (Uint8 *) (&pixels[x]); + const Uint32 average = (((Uint32) p[1]) + ((Uint32) p[2]) + ((Uint32) p[3])) / 3; + if (average == 0) { + p[0] = p[3] = 0xFF; p[1] = p[2] = 0; /* make pure black pixels red. */ + } else { + p[1] = p[2] = p[3] = (average > 50) ? 0xFF : 0x00; /* make everything else either black or white. */ + } + } + } + + /* upload the processed pixels back into a texture. */ + SDL_UpdateTexture(converted_texture, NULL, surface->pixels, surface->pitch); + SDL_DestroySurface(surface); + + /* draw the texture to the top-left of the screen. */ + dst_rect.x = dst_rect.y = 0.0f; + dst_rect.w = ((float) WINDOW_WIDTH) / 4.0f; + dst_rect.h = ((float) WINDOW_HEIGHT) / 4.0f; + SDL_RenderTexture(renderer, converted_texture, NULL, &dst_rect); + } + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + SDL_DestroyTexture(converted_texture); + SDL_DestroyTexture(texture); + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/thumbnail.png new file mode 100644 index 0000000..8da02ac Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/README.txt b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/README.txt new file mode 100644 index 0000000..0f0c868 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/README.txt @@ -0,0 +1,4 @@ +This example creates an SDL window and renderer, and draws some text +using SDL_RenderDebugText(). This is not quality text rendering, but it can +be helpful for simple apps, debugging, or showing something in a pinch. + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/debug-text.c b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/debug-text.c new file mode 100644 index 0000000..62005e6 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/debug-text.c @@ -0,0 +1,80 @@ +/* + * This example creates an SDL window and renderer, and then draws some text + * using SDL_RenderDebugText() every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("Example Renderer Debug Texture", "1.0", "com.example.renderer-debug-text"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/debug-text", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const int charsize = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */ + SDL_RenderDebugText(renderer, 272, 100, "Hello world!"); + SDL_RenderDebugText(renderer, 224, 150, "This is some debug text."); + + SDL_SetRenderDrawColor(renderer, 51, 102, 255, SDL_ALPHA_OPAQUE); /* light blue, full alpha */ + SDL_RenderDebugText(renderer, 184, 200, "You can do it in different colors."); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */ + + SDL_SetRenderScale(renderer, 4.0f, 4.0f); + SDL_RenderDebugText(renderer, 14, 65, "It can be scaled."); + SDL_SetRenderScale(renderer, 1.0f, 1.0f); + SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣"); + + SDL_RenderDebugTextFormat(renderer, (float) ((WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000); + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/thumbnail.png b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/thumbnail.png new file mode 100644 index 0000000..f08e469 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/thumbnail.png differ diff --git a/src/contrib/SDL-3.2.20/examples/template-category.html b/src/contrib/SDL-3.2.20/examples/template-category.html new file mode 100644 index 0000000..909b2c6 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/template-category.html @@ -0,0 +1,41 @@ + + + + + + + @project_name@ Examples: @category_description@ + + + + + + + + + + + +
+ @project_name@ Examples +
+
+ +

@project_name@ examples: @category_description@

+
@examples_list_html@
+
+ + diff --git a/src/contrib/SDL-3.2.20/examples/template-homepage.html b/src/contrib/SDL-3.2.20/examples/template-homepage.html new file mode 100644 index 0000000..46951b2 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/template-homepage.html @@ -0,0 +1,41 @@ + + + + + + + @project_name@ Examples + + + + + + + + + + + +
+ SDL Examples +
+
+ +

@project_name@ examples

+ + @homepage_list_html@ +
+ + diff --git a/src/contrib/SDL-3.2.20/examples/template-placeholder.png b/src/contrib/SDL-3.2.20/examples/template-placeholder.png new file mode 100644 index 0000000..202df95 Binary files /dev/null and b/src/contrib/SDL-3.2.20/examples/template-placeholder.png differ diff --git a/src/contrib/SDL-3.2.20/examples/template.c b/src/contrib/SDL-3.2.20/examples/template.c new file mode 100644 index 0000000..6719cc9 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/template.c @@ -0,0 +1,53 @@ +/* + * This example code $WHAT_IT_DOES. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; + + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("Example HUMAN READABLE NAME", "1.0", "com.example.CATEGORY-NAME"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/CATEGORY/NAME", 640, 480, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + /* SDL will clean up the window/renderer for us. */ +} + diff --git a/src/contrib/SDL-3.2.20/examples/template.css b/src/contrib/SDL-3.2.20/examples/template.css new file mode 100644 index 0000000..8e86723 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/template.css @@ -0,0 +1,284 @@ +/** from ghwikipp.css */ +:root { + color-scheme: dark light; /* both supported */ +} + +body { + background-color: white; + padding: 2vw; + color: #333; + max-width: 1200px; + margin: 0 auto; + font-size: 16px; + line-height: 1.5; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + overflow-wrap: break-word; +} + +a { + color: #0969da; + /* text-decoration: none; */ +} + +a:visited { + color: #064998; +} + +h1 { + border-bottom: 2px solid #efefef; +} + +h2 { + border-bottom: 1px solid #efefef; +} + +p { + max-width: 85ch; +} + +li { + max-width: 85ch; +} + +div.sourceCode { + background-color: #f6f8fa; + max-width: 100%; + padding: 16px; +} + +code { + background-color: #f6f8fa; + padding: 0px; + font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, + "Liberation Mono", monospace; +} + +table { + border: 1px solid #808080; + border-collapse: collapse; +} + +td { + border: 1px solid #808080; + padding: 5px; +} + +tr:nth-child(even) { + background-color: #f6f8fa; +} + +.wikitopbanner { + background-color: #efefef; + padding: 10px; + margin-bottom: 10px; + width: auto; +} + +.wikibottombanner { + background-color: #efefef; + padding: 10px; + margin-top: 10px; + width: auto; +} + +.alertBox { + background-color: #f8d7da; + border: 1px solid #f5c6cb; + max-width: 60%; + padding: 10; + margin: auto; +} + +.anchorImage { + visibility: hidden; + padding-left: 0.2em; + color: #fff; +} + +.anchorText:hover .anchorImage { + visibility: visible; +} + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #efefef; + margin: 1em 0; + padding: 0; +} + +/* Text and background color for dark mode */ +@media (prefers-color-scheme: dark) { + body { + color: #e6edf3; + background-color: #0d1117; + } + + h1 { + border-color: rgba(48, 54, 61, 0.7); + } + + h2 { + border-color: rgba(48, 54, 61, 0.7); + } + + hr { + border-color: rgba(48, 54, 61, 0.7); + } + + div.sourceCode { + background-color: #161b22; + } + + code { + background-color: #161b22; + } + + a { + color: #4493f8; + } + + a:visited { + color: #2f66ad; + } + + table { + border-color: rgba(48, 54, 61, 0.7); + } + + td { + border-color: rgba(48, 54, 61, 0.7); + } + + tr:nth-child(even) { + background-color: #161b22; + } + + .wikitopbanner { + background-color: #263040; + } + + .wikibottombanner { + background-color: #263040; + } + + .anchorText:hover .anchorImage { + filter: invert(100%); + } +} + +@media print { + body { + font-size: 12px; + } + + table { + font-size: inherit; + } + + a:visited { + color: #0969da; + } + + .wikitopbanner, + .anchorText, + .wikibottombanner { + display: none; + } +} + +/** additional (& overrides) for examples */ +header { + background-color: #efefef; + padding: 10px; + font-size: 2rem; +} + +header > a, +header > a:hover, +header > a:visited { + color: inherit; + text-decoration: none; +} + +.breadcrumb { + padding: 0.75rem 0.75rem; +} + +.breadcrumb ul { + display: flex; + flex-wrap: wrap; + list-style: none; + margin: 0; + padding: 0; +} + +.breadcrumb li:not(:last-child)::after { + display: inline-block; + margin: 0 0.25rem; + content: "»"; +} + +.list { + display: flex; + flex-flow: row wrap; + gap: 24px; +} + +.list > a > div { + width: 200px; + border: 5px solid #efefef; + border-radius: 5px; + background: #efefef; + + display: flex; + flex-flow: column nowrap; + + transition: border 0.25s; +} + +.list > a > div:hover { + border-color: #064998; +} + +.list > a > div > img { + width: 100%; + border-radius: 5px; +} + +.list > a > div > div { + text-align: center; +} + +.list > a, +.list > a:visited { + display: block; + color: inherit; + text-decoration: none; +} +.list > a:hover { + color: #0969da; +} + +@media (prefers-color-scheme: dark) { + header { + background-color: #263040; + } + + .breadcrumb li:not(:last-child)::after { + color: #efefef; + } + + .list > a > div { + border-color: #333; + background: #333; + } +} + +@media only screen and (max-width: 992px) { + .list > a > div { + width: 150px; + } +} diff --git a/src/contrib/SDL-3.2.20/examples/template.html b/src/contrib/SDL-3.2.20/examples/template.html new file mode 100644 index 0000000..3e43946 --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/template.html @@ -0,0 +1,292 @@ + + + + + + + @project_name@ Example: @category_name@/@example_name@ + + + + + + + + + + + + +
+ SDL Examples +
+
+
+ +
+
@description@
+
+ +
+
+ +
+ +
+ +
+ +
+
@htmlified_source_code@
+
+ + + + + + + -- cgit v1.2.3