summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/examples
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-08-30 16:53:58 -0700
committer3gg <3gg@shellblade.net>2025-08-30 16:53:58 -0700
commit6aaedb813fa11ba0679c3051bc2eb28646b9506c (patch)
tree34acbfc9840e02cb4753e6306ea7ce978bf8b58e /src/contrib/SDL-3.2.20/examples
parent8f228ade99dd3d4c8da9b78ade1815c9adf85c8f (diff)
Update to SDL3
Diffstat (limited to 'src/contrib/SDL-3.2.20/examples')
-rw-r--r--src/contrib/SDL-3.2.20/examples/CMakeLists.txt382
-rw-r--r--src/contrib/SDL-3.2.20/examples/README.md67
-rw-r--r--src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/README.txt6
-rw-r--r--src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/load-bitmaps.c125
-rw-r--r--src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/thumbnail.pngbin0 -> 76234 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/asyncio/description.txt1
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/README.txt5
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/01-simple-playback/simple-playback.c103
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/README.txt5
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/02-simple-playback-callback/simple-playback-callback.c115
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/03-load-wav/README.txt5
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/03-load-wav/load-wav.c103
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/README.txt5
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/04-multiple-streams/multiple-streams.c135
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/onmouseover.webpbin0 -> 176470 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/audio/thumbnail.pngbin0 -> 14221 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/README.txt1
-rw-r--r--src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/onmouseover.webpbin0 -> 346856 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/read-and-draw.c113
-rw-r--r--src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/thumbnail.pngbin0 -> 239597 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/categories.txt13
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/01-snake/README.txt1
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/01-snake/onmouseover.webpbin0 -> 30996 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/01-snake/snake.c350
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/01-snake/thumbnail.pngbin0 -> 2958 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/README.txt1
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/onmouseover.webpbin0 -> 468022 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/thumbnail.pngbin0 -> 25191 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c480
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/README.txt7
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/infinite-monkeys.c377
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/onmouseover.webpbin0 -> 95578 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/thumbnail.pngbin0 -> 7740 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/README.txt4
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/bytepusher.c416
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/onmouseover.webpbin0 -> 430096 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/thumbnail.pngbin0 -> 23851 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/demo/description.txt1
-rw-r--r--src/contrib/SDL-3.2.20/examples/highlight-plugin.lua79
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/README.txt2
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/joystick-polling.c193
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/onmouseover.webpbin0 -> 47840 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/thumbnail.pngbin0 -> 5940 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/02-joystick-events/README.txt2
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/02-joystick-events/joystick-events.c232
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/02-joystick-events/onmouseover.webpbin0 -> 2302260 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/input/02-joystick-events/thumbnail.pngbin0 -> 30785 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/drawing-lines.c121
-rw-r--r--src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/onmouseover.webpbin0 -> 28346 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/thumbnail.pngbin0 -> 2042 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/01-clear/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/01-clear/clear.c68
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/01-clear/onmouseover.webpbin0 -> 69392 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/01-clear/thumbnail.pngbin0 -> 2070 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/02-primitives/README.txt7
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/02-primitives/primitives.c95
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/02-primitives/thumbnail.pngbin0 -> 8761 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/03-lines/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/03-lines/lines.c93
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/03-lines/onmouseover.webpbin0 -> 66034 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/03-lines/thumbnail.pngbin0 -> 28130 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/04-points/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/04-points/onmouseover.webpbin0 -> 155796 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/04-points/points.c118
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/04-points/thumbnail.pngbin0 -> 8114 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/onmouseover.webpbin0 -> 75754 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/rectangles.c112
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/thumbnail.pngbin0 -> 3634 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/06-textures/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/06-textures/onmouseover.webpbin0 -> 605954 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/06-textures/textures.c127
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/06-textures/thumbnail.pngbin0 -> 238654 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/onmouseover.webpbin0 -> 17160 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/streaming-textures.c109
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/thumbnail.pngbin0 -> 3552 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/onmouseover.webpbin0 -> 312998 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/rotating-textures.c113
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/thumbnail.pngbin0 -> 91098 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/onmouseover.webpbin0 -> 318914 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/scaling-textures.c110
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/thumbnail.pngbin0 -> 83431 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/10-geometry/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/10-geometry/geometry.c166
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/10-geometry/onmouseover.webpbin0 -> 119254 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/10-geometry/thumbnail.pngbin0 -> 57164 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/README.txt3
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/color-mods.c134
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/onmouseover.webpbin0 -> 278286 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/thumbnail.pngbin0 -> 122439 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/14-viewport/README.txt4
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/14-viewport/thumbnail.pngbin0 -> 146306 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/14-viewport/viewport.c136
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/README.txt5
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/cliprect.c137
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/onmouseover.webpbin0 -> 260400 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/thumbnail.pngbin0 -> 87025 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/README.txt12
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/onmouseover.webpbin0 -> 482380 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/read-pixels.c178
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/thumbnail.pngbin0 -> 102838 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/README.txt4
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/debug-text.c80
-rw-r--r--src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/thumbnail.pngbin0 -> 4344 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/template-category.html41
-rw-r--r--src/contrib/SDL-3.2.20/examples/template-homepage.html41
-rw-r--r--src/contrib/SDL-3.2.20/examples/template-placeholder.pngbin0 -> 34957 bytes
-rw-r--r--src/contrib/SDL-3.2.20/examples/template.c53
-rw-r--r--src/contrib/SDL-3.2.20/examples/template.css284
-rw-r--r--src/contrib/SDL-3.2.20/examples/template.html292
114 files changed, 6002 insertions, 0 deletions
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 @@
1#
2# CMake script for building the SDL examples
3#
4
5list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
6
7include(CheckIncludeFile)
8include(CheckStructHasMember)
9include(CMakePushCheckState)
10include(sdlcompilers)
11
12if(SDL_EXAMPLES_LINK_SHARED)
13 set(sdl_name_component SDL3-shared)
14else()
15 set(sdl_name_component SDL3-static)
16endif()
17set(HAVE_EXAMPLES_LINK_SHARED "${SDL_EXAMPLES_LINK_SHARED}" PARENT_SCOPE)
18
19# CMake incorrectly detects opengl32.lib being present on MSVC ARM64
20if(NOT (MSVC AND SDL_CPU_ARM64))
21 # Prefer GLVND, if present
22 set(OpenGL_GL_PREFERENCE GLVND)
23 find_package(OpenGL)
24endif()
25
26set(SDL_EXAMPLE_EXECUTABLES)
27
28if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
29 set(example_bin_dir "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
30 if(NOT IS_ABSOLUTE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
31 set(example_bin_dir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
32 endif()
33else()
34 set(example_bin_dir "${CMAKE_CURRENT_BINARY_DIR}")
35endif()
36if(NOT CMAKE_VERSION VERSION_LESS 3.20)
37 get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
38 set(example_bin_dir "${example_bin_dir}$<$<BOOL:${is_multi_config}>:/$<CONFIG>>")
39endif()
40
41file(GLOB RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/*.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/*.wav ${CMAKE_CURRENT_SOURCE_DIR}/../test/*.hex)
42
43set(RESOURCE_FILE_NAMES)
44set(RESOURCE_FILES_BINDIR)
45foreach(resource_file IN LISTS RESOURCE_FILES)
46 get_filename_component(res_file_name ${resource_file} NAME)
47 list(APPEND RESOURCE_FILE_NAMES "${res_file_name}")
48 set(resource_file_bindir "${example_bin_dir}/${res_file_name}")
49 add_custom_command(OUTPUT "${resource_file_bindir}"
50 COMMAND "${CMAKE_COMMAND}" -E copy "${resource_file}" "${resource_file_bindir}"
51 DEPENDS "${resource_file}"
52 )
53 list(APPEND RESOURCE_FILES_BINDIR "${resource_file_bindir}")
54endforeach()
55add_custom_target(copy-sdl-example-resources
56 DEPENDS "${RESOURCE_FILES_BINDIR}"
57)
58
59macro(add_sdl_example_executable TARGET)
60 cmake_parse_arguments(AST "BUILD_DEPENDENT" "" "SOURCES;DATAFILES" ${ARGN})
61 if(AST_UNPARSED_ARGUMENTS)
62 message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}")
63 endif()
64 if(NOT AST_SOURCES)
65 message(FATAL_ERROR "add_sdl_example_executable needs at least one source")
66 endif()
67 set(EXTRA_SOURCES "")
68 if(AST_DATAFILES)
69 list(APPEND EXTRA_SOURCES ${DATAFILES})
70 endif()
71 if(ANDROID)
72 add_library(${TARGET} SHARED ${AST_SOURCES} ${EXTRA_SOURCES})
73 else()
74 add_executable(${TARGET} ${AST_SOURCES} ${EXTRA_SOURCES})
75 endif()
76 SDL_AddCommonCompilerFlags(${TARGET})
77 target_include_directories(${TARGET} PRIVATE "${SDL3_SOURCE_DIR}/src/video/khronos")
78 target_link_libraries(${TARGET} PRIVATE SDL3::${sdl_name_component})
79
80 list(APPEND SDL_EXAMPLE_EXECUTABLES ${TARGET})
81 if(AST_DATAFILES)
82 if(PSP OR PS2)
83 add_custom_command(TARGET ${TARGET} POST_BUILD
84 COMMAND ${CMAKE_COMMAND} ARGS -E make_directory $<TARGET_FILE_DIR:${TARGET}>/sdl-${TARGET}
85 COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${AST_DATAFILES} $<TARGET_FILE_DIR:${TARGET}>/sdl-${TARGET}
86 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
87 )
88 else()
89 add_dependencies(${TARGET} copy-sdl-example-resources)
90 endif()
91 if(APPLE)
92 # Make sure resource files get installed into macOS/iOS .app bundles.
93 set_target_properties(${TARGET} PROPERTIES RESOURCE "${AST_DATAFILES}")
94 endif()
95 if(EMSCRIPTEN)
96 foreach(res IN LISTS AST_DATAFILES)
97 get_filename_component(res_name "${res}" NAME)
98 target_link_options(${TARGET} PRIVATE "SHELL:--embed-file ${res}@${res_name}")
99 endforeach()
100 endif()
101 set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$<TARGET_FILE_DIR:${TARGET}>/$<JOIN:${AST_DATAFILES},$<SEMICOLON>$<TARGET_FILE_DIR:${TARGET}>/>")
102 endif()
103
104 if(WINDOWS)
105 # CET support was added in VS 16.7
106 if(MSVC_VERSION GREATER 1926 AND CMAKE_GENERATOR_PLATFORM MATCHES "Win32|x64")
107 set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -CETCOMPAT")
108 endif()
109 elseif(PSP)
110 target_link_libraries(${TARGET} PRIVATE GL)
111 elseif(EMSCRIPTEN)
112 set_property(TARGET ${TARGET} PROPERTY SUFFIX ".html")
113 target_link_options(${TARGET} PRIVATE -sALLOW_MEMORY_GROWTH=1)
114 endif()
115
116 if(OPENGL_FOUND)
117 target_compile_definitions(${TARGET} PRIVATE HAVE_OPENGL)
118 endif()
119
120 # FIXME: only add "${SDL3_BINARY_DIR}/include-config-$<LOWER_CASE:$<CONFIG>>" + include paths of external dependencies
121 target_include_directories(${TARGET} PRIVATE "$<TARGET_PROPERTY:SDL3::${sdl_name_component},INCLUDE_DIRECTORIES>")
122endmacro()
123
124add_sdl_example_executable(renderer-clear SOURCES renderer/01-clear/clear.c)
125add_sdl_example_executable(renderer-primitives SOURCES renderer/02-primitives/primitives.c)
126add_sdl_example_executable(renderer-lines SOURCES renderer/03-lines/lines.c)
127add_sdl_example_executable(renderer-points SOURCES renderer/04-points/points.c)
128add_sdl_example_executable(renderer-rectangles SOURCES renderer/05-rectangles/rectangles.c)
129add_sdl_example_executable(renderer-textures SOURCES renderer/06-textures/textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
130add_sdl_example_executable(renderer-streaming-textures SOURCES renderer/07-streaming-textures/streaming-textures.c)
131add_sdl_example_executable(renderer-rotating-textures SOURCES renderer/08-rotating-textures/rotating-textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
132add_sdl_example_executable(renderer-scaling-textures SOURCES renderer/09-scaling-textures/scaling-textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
133add_sdl_example_executable(renderer-geometry SOURCES renderer/10-geometry/geometry.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
134add_sdl_example_executable(renderer-color-mods SOURCES renderer/11-color-mods/color-mods.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
135add_sdl_example_executable(renderer-viewport SOURCES renderer/14-viewport/viewport.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
136add_sdl_example_executable(renderer-cliprect SOURCES renderer/15-cliprect/cliprect.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
137add_sdl_example_executable(renderer-read-pixels SOURCES renderer/17-read-pixels/read-pixels.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp)
138add_sdl_example_executable(renderer-debug-text SOURCES renderer/18-debug-text/debug-text.c)
139add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c)
140add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c)
141add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav)
142add_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)
143add_sdl_example_executable(input-joystick-polling SOURCES input/01-joystick-polling/joystick-polling.c)
144add_sdl_example_executable(input-joystick-events SOURCES input/02-joystick-events/joystick-events.c)
145add_sdl_example_executable(camera-read-and-draw SOURCES camera/01-read-and-draw/read-and-draw.c)
146add_sdl_example_executable(pen-drawing-lines SOURCES pen/01-drawing-lines/drawing-lines.c)
147add_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)
148add_sdl_example_executable(demo-snake SOURCES demo/01-snake/snake.c)
149add_sdl_example_executable(demo-woodeneye-008 SOURCES demo/02-woodeneye-008/woodeneye-008.c)
150add_sdl_example_executable(demo-infinite-monkeys SOURCES demo/03-infinite-monkeys/infinite-monkeys.c)
151add_sdl_example_executable(demo-bytepusher SOURCES demo/04-bytepusher/bytepusher.c)
152
153# When you add an example, remember to add the Visual Studio project as well:
154# - Add a new example in examples/
155# - Run python VisualC/examples/generate.py
156# - Take note of the newly generated .vcxproj files
157# - Modify the .vcxproj files if necessary (adding content such as BMP or WAV files)
158# - Open VisualC/SDL.sln in Visual Studio or JetBrains Rider
159# - Locate the appropriate folder in the Solution Explorer
160# - Add the newly generated projects: Right click -> Add -> Existing project...
161# - Test if they work
162# - Save the SDL.sln solution
163
164if(PSP)
165 # Build EBOOT files if building for PSP
166 foreach(APP ${SDL_EXAMPLE_EXECUTABLES})
167 create_pbp_file(
168 TARGET ${APP}
169 TITLE SDL-${APP}
170 ICON_PATH NULL
171 BACKGROUND_PATH NULL
172 PREVIEW_PATH NULL
173 OUTPUT_DIR $<TARGET_FILE_DIR:${APP}>/sdl-${APP}
174 )
175 endforeach()
176endif()
177
178if(N3DS)
179 set(ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/romfs")
180 file(MAKE_DIRECTORY "${ROMFS_DIR}")
181 file(COPY ${RESOURCE_FILES} DESTINATION "${ROMFS_DIR}")
182
183 foreach(APP ${SDL_EXAMPLE_EXECUTABLES})
184 get_target_property(TARGET_BINARY_DIR ${APP} BINARY_DIR)
185 set(SMDH_FILE "${TARGET_BINARY_DIR}/${APP}.smdh")
186 ctr_generate_smdh("${SMDH_FILE}"
187 NAME "SDL-${APP}"
188 DESCRIPTION "SDL3 Test suite"
189 AUTHOR "SDL3 Contributors"
190 ICON "${CMAKE_CURRENT_SOURCE_DIR}/../test/n3ds/logo48x48.png"
191 )
192 ctr_create_3dsx(
193 ${APP}
194 ROMFS "${ROMFS_DIR}"
195 SMDH "${SMDH_FILE}"
196 )
197 endforeach()
198endif()
199
200if(RISCOS)
201 set(SDL_EXAMPLE_EXECUTABLES_AIF)
202 foreach(APP ${SDL_EXAMPLE_EXECUTABLES})
203 set_property(TARGET ${APP} APPEND_STRING PROPERTY LINK_FLAGS " -static")
204 add_custom_command(
205 OUTPUT ${APP},ff8
206 COMMAND elf2aif ${APP} ${APP},ff8
207 DEPENDS ${APP}
208 )
209 add_custom_target(${APP}-aif ALL DEPENDS ${APP},ff8)
210 list(APPEND SDL_EXAMPLE_EXECUTABLES_AIF ${CMAKE_CURRENT_BINARY_DIR}/${APP},ff8)
211 endforeach()
212endif()
213
214# Set Apple App ID / Bundle ID. This is needed to launch apps on some Apple
215# platforms (iOS, for example).
216if(APPLE)
217 foreach(CURRENT_TARGET ${SDL_EXAMPLE_EXECUTABLES})
218 set_target_properties("${CURRENT_TARGET}" PROPERTIES
219 MACOSX_BUNDLE_GUI_IDENTIFIER "org.libsdl.${CURRENT_TARGET}"
220 MACOSX_BUNDLE_BUNDLE_VERSION "${SDL3_VERSION}"
221 MACOSX_BUNDLE_SHORT_VERSION_STRING "${SDL3_VERSION}"
222 )
223 endforeach()
224endif()
225
226if(SDL_INSTALL_EXAMPLES)
227 if(RISCOS)
228 install(
229 FILES ${SDL_EXAMPLE_EXECUTABLES_AIF}
230 DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3
231 )
232 else()
233 install(
234 TARGETS ${SDL_EXAMPLE_EXECUTABLES}
235 DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3
236 )
237 endif()
238 if(MSVC)
239 foreach(example IN LISTS SDL_EXAMPLE_EXECUTABLES)
240 SDL_install_pdb(${example} "${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3")
241 endforeach()
242 endif()
243 install(
244 FILES ${RESOURCE_FILES}
245 DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-examples/SDL3
246 )
247endif()
248
249if(ANDROID AND TARGET SDL3::Jar)
250 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake/android")
251 find_package(SdlAndroid MODULE)
252 if(SdlAndroid_FOUND)
253 set(apks "")
254 set(packages "")
255
256 include(SdlAndroidFunctions)
257 sdl_create_android_debug_keystore(SDL_example-debug-keystore)
258 sdl_android_compile_resources(SDL_example-resources RESFOLDER ${CMAKE_CURRENT_SOURCE_DIR}/../test/android/res)
259 add_custom_target(sdl-example-apks)
260 foreach(EXAMPLE ${SDL_EXAMPLE_EXECUTABLES})
261 set(ANDROID_MANIFEST_APP_NAME "${EXAMPLE}")
262 set(ANDROID_MANIFEST_LABEL "${EXAMPLE}")
263 set(ANDROID_MANIFEST_LIB_NAME "$<TARGET_FILE_BASE_NAME:${EXAMPLE}>")
264 set(ANDROID_MANIFEST_PACKAGE "org.libsdl.sdl.example.${EXAMPLE}")
265 set(generated_manifest_path "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-src/AndroidManifest.xml")
266 string(REPLACE "." "/" JAVA_PACKAGE_DIR "${ANDROID_MANIFEST_PACKAGE}")
267 set(GENERATED_SRC_FOLDER "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-src")
268 set(GENERATED_RES_FOLDER "${GENERATED_SRC_FOLDER}/res")
269 set(JAVA_PACKAGE_DIR "${GENERATED_SRC_FOLDER}/${JAVA_PACKAGE_DIR}")
270 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/SDLEntryTestActivity.java.cmake "${JAVA_PACKAGE_DIR}/SDLEntryTestActivity.java" @ONLY)
271 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/SDLTestActivity.java.cmake "${JAVA_PACKAGE_DIR}/SDLTestActivity.java" @ONLY)
272 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/res/values/strings.xml.cmake android/res/values/strings-${EXAMPLE}.xml @ONLY)
273 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/res/xml/shortcuts.xml.cmake "${GENERATED_RES_FOLDER}/xml/shortcuts.xml" @ONLY)
274 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test/android/cmake/AndroidManifest.xml.cmake "${generated_manifest_path}" @ONLY)
275 file(GENERATE
276 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-$<CONFIG>/res/values/strings.xml"
277 INPUT "${CMAKE_CURRENT_BINARY_DIR}/android/res/values/strings-${EXAMPLE}.xml"
278 )
279
280 sdl_android_compile_resources(${EXAMPLE}-resources
281 RESOURCES
282 "${CMAKE_CURRENT_BINARY_DIR}/android/${EXAMPLE}-$<CONFIG>/res/values/strings.xml"
283 "${GENERATED_RES_FOLDER}/xml/shortcuts.xml"
284 )
285
286 sdl_android_link_resources(${EXAMPLE}-apk-linked
287 MANIFEST "${generated_manifest_path}"
288 PACKAGE ${ANDROID_MANIFEST_PACKAGE}
289 RES_TARGETS SDL_example-resources ${EXAMPLE}-resources
290 TARGET_SDK_VERSION 31
291 )
292
293 set(CMAKE_JAVA_COMPILE_FLAGS "-encoding;utf-8")
294 set(classes_path "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${EXAMPLE}-java.dir/classes")
295 # Some CMake versions have a slow `cmake -E make_directory` implementation
296 if(NOT IS_DIRECTORY "${classes_path}")
297 execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${classes_path}")
298 endif()
299 set(OUT_JAR "${CMAKE_CURRENT_BINARY_DIR}/${EXAMPLE}.jar")
300 add_custom_command(
301 OUTPUT "${OUT_JAR}"
302 COMMAND ${CMAKE_COMMAND} -E rm -rf "${classes_path}"
303 COMMAND ${CMAKE_COMMAND} -E make_directory "${classes_path}"
304 COMMAND ${Java_JAVAC_EXECUTABLE}
305 -source 1.8 -target 1.8
306 -bootclasspath "$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>"
307 "${JAVA_PACKAGE_DIR}/SDLEntryTestActivity.java"
308 "${JAVA_PACKAGE_DIR}/SDLTestActivity.java"
309 $<TARGET_PROPERTY:${EXAMPLE}-apk-linked,JAVA_R>
310 -cp "$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>:${SDL_ANDROID_PLATFORM_ANDROID_JAR}"
311 -d "${classes_path}"
312 COMMAND ${Java_JAR_EXECUTABLE} cf "${OUT_JAR}" -C "${classes_path}" .
313 DEPENDS $<TARGET_PROPERTY:${EXAMPLE}-apk-linked,OUTPUTS> "$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>" "${JAVA_PACKAGE_DIR}/SDLTestActivity.java" "${JAVA_PACKAGE_DIR}/SDLEntryTestActivity.java"
314 )
315 add_custom_target(${EXAMPLE}-jar DEPENDS "${OUT_JAR}")
316 set_property(TARGET ${EXAMPLE}-jar PROPERTY OUTPUT "${OUT_JAR}")
317
318 set(dexworkdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${EXAMPLE}-dex.dir")
319 # Some CMake versions have a slow `cmake -E make_directory` implementation
320 if(NOT IS_DIRECTORY "${dexworkdir}")
321 execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${dexworkdir}")
322 endif()
323 set(classes_dex_base_name "classes.dex")
324 set(classes_dex "${dexworkdir}/${classes_dex_base_name}")
325 add_custom_command(
326 OUTPUT "${classes_dex}"
327 COMMAND SdlAndroid::d8
328 $<TARGET_PROPERTY:${EXAMPLE}-jar,OUTPUT>
329 $<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>
330 --lib "${SDL_ANDROID_PLATFORM_ANDROID_JAR}"
331 --output "${dexworkdir}"
332 DEPENDS $<TARGET_PROPERTY:${EXAMPLE}-jar,OUTPUT> $<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>
333 )
334 add_custom_target(${EXAMPLE}-dex DEPENDS "${classes_dex}")
335 set_property(TARGET ${EXAMPLE}-dex PROPERTY OUTPUT "${classes_dex}")
336 set_property(TARGET ${EXAMPLE}-dex PROPERTY OUTPUT_BASE_NAME "${classes_dex_base_name}")
337
338 sdl_add_to_apk_unaligned(${EXAMPLE}-unaligned-apk
339 APK_IN ${EXAMPLE}-apk-linked
340 OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/intermediates"
341 ASSETS ${RESOURCE_FILES}
342 NATIVE_LIBS SDL3::SDL3-shared ${EXAMPLE}
343 DEX ${EXAMPLE}-dex
344 )
345
346 sdl_apk_align(${EXAMPLE}-aligned-apk ${EXAMPLE}-unaligned-apk
347 OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/intermediates"
348 )
349 sdl_apk_sign(${EXAMPLE}-apk ${EXAMPLE}-aligned-apk
350 KEYSTORE SDL_example-debug-keystore
351 )
352 add_dependencies(sdl-example-apks ${EXAMPLE}-apk)
353
354 if(TARGET SdlAndroid::adb)
355 add_custom_target(install-${EXAMPLE}
356 COMMAND "${CMAKE_COMMAND}" -DACTION=install "-DAPKS=$<TARGET_PROPERTY:${EXAMPLE}-apk,OUTPUT>" -P "${SDL3_SOURCE_DIR}/cmake/android/SdlAndroidScript.cmake"
357 DEPENDS "${EXAMPLE}-apk"
358 )
359 add_custom_target(start-${EXAMPLE}
360 COMMAND "${ADB_BIN}" shell am start-activity -S "${ANDROID_MANIFEST_PACKAGE}/.SDLTestActivity"
361 )
362 add_custom_target(build-install-start-${EXAMPLE}
363 COMMAND "${CMAKE_COMMAND}" -DACTION=build-install-run "-DEXECUTABLES=${EXAMPLE}" "-DBUILD_FOLDER=${CMAKE_BINARY_DIR}" -P "${SDL3_SOURCE_DIR}/cmake/android/SdlAndroidScript.cmake"
364 )
365 endif()
366
367 list(APPEND packages "${ANDROID_MANIFEST_PACKAGE}")
368 list(APPEND install_targets install-${EXAMPLE})
369 endforeach()
370
371 if(TARGET SdlAndroid::adb)
372 add_custom_target(install-sdl-example-apks
373 DEPENDS ${install_targets}
374 VERBATIM
375 )
376 add_custom_target(uninstall-sdl-example-apks
377 COMMAND "${CMAKE_COMMAND}" "-DADB=$<TARGET_FILE:SdlAndroid::adb>" -DACTION=uninstall "-DPACKAGES=${packages}" -P "${SDL3_SOURCE_DIR}/cmake/android/SdlAndroidScript.cmake"
378 VERBATIM
379 )
380 endif()
381 endif()
382endif()
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 @@
1# Examples
2
3## What is this?
4
5In here are a collection of standalone SDL application examples. Unless
6otherwise stated, they should work on all supported platforms out of the box.
7If they don't [please file a bug to let us know](https://github.com/libsdl-org/SDL/issues/new).
8
9
10## What is this SDL_AppIterate thing?
11
12SDL can optionally build apps as a collection of callbacks instead of the
13usual program structure that starts and ends in a function called `main`.
14The examples use this format for two reasons.
15
16First, it allows the examples to work when built as web applications without
17a pile of ugly `#ifdef`s, and all of these examples are published on the web
18at [examples.libsdl.org](https://examples.libsdl.org/), so you can easily see
19them in action.
20
21Second, it's example code! The callbacks let us cleanly break the program up
22into the four logical pieces most apps care about:
23
24- Program startup
25- Event handling
26- What the program actually does in a single frame
27- Program shutdown
28
29A detailed technical explanation of these callbacks is in
30docs/README-main-functions.md (or view that page on the web on
31[the wiki](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3)).
32
33
34## I would like to build and run these examples myself.
35
36When you build SDL with CMake, you can add `-DSDL_EXAMPLES=On` to the
37CMake command line. When you build SDL, these examples will be built with it.
38
39But most of these can just be built as a single .c file, as long as you point
40your compiler at SDL3's headers and link against SDL.
41
42
43## What is the license on the example code? Can I paste this into my project?
44
45All code in the examples directory is considered public domain! You can do
46anything you like with it, including copy/paste it into your closed-source
47project, sell it, and pretend you wrote it yourself. We do not require you to
48give us credit for this code (but we always appreciate if you do!).
49
50This is only true for the examples directory. The rest of SDL falls under the
51[zlib license](https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt).
52
53
54## What is template.html and highlight-plugin.lua in this directory?
55
56This is what [examples.libsdl.org](https://examples.libsdl.org/) uses when
57generating the web versions of these example programs. You can ignore this,
58unless you are improving it, in which case we definitely would love to hear
59from you!
60
61
62## What is template.c in this directory?
63
64If writing new examples, this is the skeleton code we start from, to keep
65everything consistent. You can ignore it.
66
67
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 @@
1This example code loads a few bitmap files from disk using the asynchronous
2i/o, and then draws it to the window. It uses a task group to watch multiple
3reads and deal with them in whatever order they finish.
4
5Note that for a single tiny file like this, you'd probably not want to bother
6with 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 @@
1/*
2 * This example code loads a bitmap with asynchronous i/o and renders it.
3 *
4 * This code is public domain. Feel free to use it for any purpose!
5 */
6
7#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
8#include <SDL3/SDL.h>
9#include <SDL3/SDL_main.h>
10
11/* We will use this renderer to draw into this window every frame. */
12static SDL_Window *window = NULL;
13static SDL_Renderer *renderer = NULL;
14static SDL_AsyncIOQueue *queue = NULL;
15
16#define TOTAL_TEXTURES 4
17static const char * const bmps[TOTAL_TEXTURES] = { "sample.bmp", "gamepad_front.bmp", "speaker.bmp", "icon2x.bmp" };
18static SDL_Texture *textures[TOTAL_TEXTURES];
19static const SDL_FRect texture_rects[TOTAL_TEXTURES] = {
20 { 116, 156, 408, 167 },
21 { 20, 200, 96, 60 },
22 { 525, 180, 96, 96 },
23 { 288, 375, 64, 64 }
24};
25
26/* This function runs once at startup. */
27SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
28{
29 int i;
30
31 if (!SDL_Init(SDL_INIT_VIDEO)) {
32 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
33 return SDL_APP_FAILURE;
34 }
35
36 if (!SDL_CreateWindowAndRenderer("examples/asyncio/load-bitmaps", 640, 480, 0, &window, &renderer)) {
37 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
38 return SDL_APP_FAILURE;
39 }
40
41 queue = SDL_CreateAsyncIOQueue();
42 if (!queue) {
43 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create async i/o queue!", SDL_GetError(), NULL);
44 return SDL_APP_FAILURE;
45 }
46
47 /* Load some .bmp files asynchronously from wherever the app is being run from, put them in the same queue. */
48 for (i = 0; i < SDL_arraysize(bmps); i++) {
49 char *path = NULL;
50 SDL_asprintf(&path, "%s%s", SDL_GetBasePath(), bmps[i]); /* allocate a string of the full file path */
51 /* you _should) check for failure, but we'll just go on without files here. */
52 SDL_LoadFileAsync(path, queue, (void *) bmps[i]); /* attach the filename as app-specific data, so we can see it later. */
53 SDL_free(path);
54 }
55
56 return SDL_APP_CONTINUE; /* carry on with the program! */
57}
58
59/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
60SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
61{
62 if (event->type == SDL_EVENT_QUIT) {
63 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
64 }
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs once per frame, and is the heart of the program. */
70SDL_AppResult SDL_AppIterate(void *appstate)
71{
72 SDL_AsyncIOOutcome outcome;
73 int i;
74
75 if (SDL_GetAsyncIOResult(queue, &outcome)) { /* a .bmp file load has finished? */
76 if (outcome.result == SDL_ASYNCIO_COMPLETE) {
77 /* this might be _any_ of the bmps; they might finish loading in any order. */
78 for (i = 0; i < SDL_arraysize(bmps); i++) {
79 /* this doesn't need a strcmp because we gave the pointer from this array to SDL_LoadFileAsync */
80 if (outcome.userdata == bmps[i]) {
81 break;
82 }
83 }
84
85 if (i < SDL_arraysize(bmps)) { /* (just in case.) */
86 SDL_Surface *surface = SDL_LoadBMP_IO(SDL_IOFromConstMem(outcome.buffer, (size_t) outcome.bytes_transferred), true);
87 if (surface) { /* the renderer is not multithreaded, so create the texture here once the data loads. */
88 textures[i] = SDL_CreateTextureFromSurface(renderer, surface);
89 if (!textures[i]) {
90 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create texture!", SDL_GetError(), NULL);
91 return SDL_APP_FAILURE;
92 }
93 SDL_DestroySurface(surface);
94 }
95 }
96 }
97 SDL_free(outcome.buffer);
98 }
99
100 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
101 SDL_RenderClear(renderer);
102
103 for (i = 0; i < SDL_arraysize(textures); i++) {
104 SDL_RenderTexture(renderer, textures[i], NULL, &texture_rects[i]);
105 }
106
107 SDL_RenderPresent(renderer);
108
109 return SDL_APP_CONTINUE; /* carry on with the program! */
110}
111
112/* This function runs once at shutdown. */
113void SDL_AppQuit(void *appstate, SDL_AppResult result)
114{
115 int i;
116
117 SDL_DestroyAsyncIOQueue(queue);
118
119 for (i = 0; i < SDL_arraysize(textures); i++) {
120 SDL_DestroyTexture(textures[i]);
121 }
122
123 /* SDL will clean up the window/renderer for us. */
124}
125
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/asyncio/01-load-bitmaps/thumbnail.png
Binary files 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 @@
1If you're running this in a web browser, you need to click the window before you'll hear anything!
2
3This example code creates a simple audio stream for playing sound, and
4generates a sine wave sound effect for it to play as time goes on. This is the
5simplest 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 @@
1/*
2 * This example code creates a simple audio stream for playing sound, and
3 * generates a sine wave sound effect for it to play as time goes on. This
4 * is the simplest way to get up and running with procedural sound.
5 *
6 * This code is public domain. Feel free to use it for any purpose!
7 */
8
9#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
10#include <SDL3/SDL.h>
11#include <SDL3/SDL_main.h>
12
13/* We will use this renderer to draw into this window every frame. */
14static SDL_Window *window = NULL;
15static SDL_Renderer *renderer = NULL;
16static SDL_AudioStream *stream = NULL;
17static int current_sine_sample = 0;
18
19/* This function runs once at startup. */
20SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
21{
22 SDL_AudioSpec spec;
23
24 SDL_SetAppMetadata("Example Audio Simple Playback", "1.0", "com.example.audio-simple-playback");
25
26 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
27 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
28 return SDL_APP_FAILURE;
29 }
30
31 /* we don't _need_ a window for audio-only things but it's good policy to have one. */
32 if (!SDL_CreateWindowAndRenderer("examples/audio/simple-playback", 640, 480, 0, &window, &renderer)) {
33 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
34 return SDL_APP_FAILURE;
35 }
36
37 /* We're just playing a single thing here, so we'll use the simplified option.
38 We are always going to feed audio in as mono, float32 data at 8000Hz.
39 The stream will convert it to whatever the hardware wants on the other side. */
40 spec.channels = 1;
41 spec.format = SDL_AUDIO_F32;
42 spec.freq = 8000;
43 stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);
44 if (!stream) {
45 SDL_Log("Couldn't create audio stream: %s", SDL_GetError());
46 return SDL_APP_FAILURE;
47 }
48
49 /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */
50 SDL_ResumeAudioStreamDevice(stream);
51
52 return SDL_APP_CONTINUE; /* carry on with the program! */
53}
54
55/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
56SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
57{
58 if (event->type == SDL_EVENT_QUIT) {
59 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
60 }
61 return SDL_APP_CONTINUE; /* carry on with the program! */
62}
63
64/* This function runs once per frame, and is the heart of the program. */
65SDL_AppResult SDL_AppIterate(void *appstate)
66{
67 /* see if we need to feed the audio stream more data yet.
68 We're being lazy here, but if there's less than half a second queued, generate more.
69 A sine wave is unchanging audio--easy to stream--but for video games, you'll want
70 to generate significantly _less_ audio ahead of time! */
71 const int minimum_audio = (8000 * sizeof (float)) / 2; /* 8000 float samples per second. Half of that. */
72 if (SDL_GetAudioStreamQueued(stream) < minimum_audio) {
73 static float samples[512]; /* this will feed 512 samples each frame until we get to our maximum. */
74 int i;
75
76 /* generate a 440Hz pure tone */
77 for (i = 0; i < SDL_arraysize(samples); i++) {
78 const int freq = 440;
79 const float phase = current_sine_sample * freq / 8000.0f;
80 samples[i] = SDL_sinf(phase * 2 * SDL_PI_F);
81 current_sine_sample++;
82 }
83
84 /* wrapping around to avoid floating-point errors */
85 current_sine_sample %= 8000;
86
87 /* feed the new data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */
88 SDL_PutAudioStreamData(stream, samples, sizeof (samples));
89 }
90
91 /* we're not doing anything with the renderer, so just blank it out. */
92 SDL_RenderClear(renderer);
93 SDL_RenderPresent(renderer);
94
95 return SDL_APP_CONTINUE; /* carry on with the program! */
96}
97
98/* This function runs once at shutdown. */
99void SDL_AppQuit(void *appstate, SDL_AppResult result)
100{
101 /* SDL will clean up the window/renderer for us. */
102}
103
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 @@
1If you're running this in a web browser, you need to click the window before you'll hear anything!
2
3This example code creates a simple audio stream for playing sound, and
4generates a sine wave sound effect for it to play as time goes on. Unlike
5the 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 @@
1/*
2 * This example code creates a simple audio stream for playing sound, and
3 * generates a sine wave sound effect for it to play as time goes on. Unlike
4 * the previous example, this uses a callback to generate sound.
5 *
6 * This might be the path of least resistance if you're moving an SDL2
7 * program's audio code to SDL3.
8 *
9 * This code is public domain. Feel free to use it for any purpose!
10 */
11
12#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
13#include <SDL3/SDL.h>
14#include <SDL3/SDL_main.h>
15
16/* We will use this renderer to draw into this window every frame. */
17static SDL_Window *window = NULL;
18static SDL_Renderer *renderer = NULL;
19static SDL_AudioStream *stream = NULL;
20static int current_sine_sample = 0;
21
22/* this function will be called (usually in a background thread) when the audio stream is consuming data. */
23static void SDLCALL FeedTheAudioStreamMore(void *userdata, SDL_AudioStream *astream, int additional_amount, int total_amount)
24{
25 /* total_amount is how much data the audio stream is eating right now, additional_amount is how much more it needs
26 than what it currently has queued (which might be zero!). You can supply any amount of data here; it will take what
27 it needs and use the extra later. If you don't give it enough, it will take everything and then feed silence to the
28 hardware for the rest. Ideally, though, we always give it what it needs and no extra, so we aren't buffering more
29 than necessary. */
30 additional_amount /= sizeof (float); /* convert from bytes to samples */
31 while (additional_amount > 0) {
32 float samples[128]; /* this will feed 128 samples each iteration until we have enough. */
33 const int total = SDL_min(additional_amount, SDL_arraysize(samples));
34 int i;
35
36 /* generate a 440Hz pure tone */
37 for (i = 0; i < total; i++) {
38 const int freq = 440;
39 const float phase = current_sine_sample * freq / 8000.0f;
40 samples[i] = SDL_sinf(phase * 2 * SDL_PI_F);
41 current_sine_sample++;
42 }
43
44 /* wrapping around to avoid floating-point errors */
45 current_sine_sample %= 8000;
46
47 /* feed the new data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */
48 SDL_PutAudioStreamData(astream, samples, total * sizeof (float));
49 additional_amount -= total; /* subtract what we've just fed the stream. */
50 }
51}
52
53/* This function runs once at startup. */
54SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
55{
56 SDL_AudioSpec spec;
57
58 SDL_SetAppMetadata("Example Simple Audio Playback Callback", "1.0", "com.example.audio-simple-playback-callback");
59
60 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
61 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
62 return SDL_APP_FAILURE;
63 }
64
65 /* we don't _need_ a window for audio-only things but it's good policy to have one. */
66 if (!SDL_CreateWindowAndRenderer("examples/audio/simple-playback-callback", 640, 480, 0, &window, &renderer)) {
67 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
68 return SDL_APP_FAILURE;
69 }
70
71 /* We're just playing a single thing here, so we'll use the simplified option.
72 We are always going to feed audio in as mono, float32 data at 8000Hz.
73 The stream will convert it to whatever the hardware wants on the other side. */
74 spec.channels = 1;
75 spec.format = SDL_AUDIO_F32;
76 spec.freq = 8000;
77 stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, FeedTheAudioStreamMore, NULL);
78 if (!stream) {
79 SDL_Log("Couldn't create audio stream: %s", SDL_GetError());
80 return SDL_APP_FAILURE;
81 }
82
83 /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */
84 SDL_ResumeAudioStreamDevice(stream);
85
86 return SDL_APP_CONTINUE; /* carry on with the program! */
87}
88
89/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
90SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
91{
92 if (event->type == SDL_EVENT_QUIT) {
93 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
94 }
95 return SDL_APP_CONTINUE; /* carry on with the program! */
96}
97
98/* This function runs once per frame, and is the heart of the program. */
99SDL_AppResult SDL_AppIterate(void *appstate)
100{
101 /* we're not doing anything with the renderer, so just blank it out. */
102 SDL_RenderClear(renderer);
103 SDL_RenderPresent(renderer);
104
105 /* all the work of feeding the audio stream is happening in a callback in a background thread. */
106
107 return SDL_APP_CONTINUE; /* carry on with the program! */
108}
109
110/* This function runs once at shutdown. */
111void SDL_AppQuit(void *appstate, SDL_AppResult result)
112{
113 /* SDL will clean up the window/renderer for us. */
114}
115
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 @@
1If you're running this in a web browser, you need to click the window before you'll hear anything!
2
3This example code creates a simple audio stream for playing sound, and
4loads a .wav file that is pushed through the stream in a loop.
5
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 @@
1/*
2 * This example code creates a simple audio stream for playing sound, and
3 * loads a .wav file that is pushed through the stream in a loop.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 *
7 * The .wav file is a sample from Will Provost's song, The Living Proof,
8 * used with permission.
9 *
10 * From the album The Living Proof
11 * Publisher: 5 Guys Named Will
12 * Copyright 1996 Will Provost
13 * https://itunes.apple.com/us/album/the-living-proof/id4153978
14 * http://www.amazon.com/The-Living-Proof-Will-Provost/dp/B00004R8RH
15 */
16
17#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
18#include <SDL3/SDL.h>
19#include <SDL3/SDL_main.h>
20
21/* We will use this renderer to draw into this window every frame. */
22static SDL_Window *window = NULL;
23static SDL_Renderer *renderer = NULL;
24static SDL_AudioStream *stream = NULL;
25static Uint8 *wav_data = NULL;
26static Uint32 wav_data_len = 0;
27
28/* This function runs once at startup. */
29SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
30{
31 SDL_AudioSpec spec;
32 char *wav_path = NULL;
33
34 SDL_SetAppMetadata("Example Audio Load Wave", "1.0", "com.example.audio-load-wav");
35
36 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
37 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
38 return SDL_APP_FAILURE;
39 }
40
41 /* we don't _need_ a window for audio-only things but it's good policy to have one. */
42 if (!SDL_CreateWindowAndRenderer("examples/audio/load-wav", 640, 480, 0, &window, &renderer)) {
43 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
44 return SDL_APP_FAILURE;
45 }
46
47 /* Load the .wav file from wherever the app is being run from. */
48 SDL_asprintf(&wav_path, "%ssample.wav", SDL_GetBasePath()); /* allocate a string of the full file path */
49 if (!SDL_LoadWAV(wav_path, &spec, &wav_data, &wav_data_len)) {
50 SDL_Log("Couldn't load .wav file: %s", SDL_GetError());
51 return SDL_APP_FAILURE;
52 }
53
54 SDL_free(wav_path); /* done with this string. */
55
56 /* Create our audio stream in the same format as the .wav file. It'll convert to what the audio hardware wants. */
57 stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);
58 if (!stream) {
59 SDL_Log("Couldn't create audio stream: %s", SDL_GetError());
60 return SDL_APP_FAILURE;
61 }
62
63 /* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */
64 SDL_ResumeAudioStreamDevice(stream);
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 /* see if we need to feed the audio stream more data yet.
82 We're being lazy here, but if there's less than the entire wav file left to play,
83 just shove a whole copy of it into the queue, so we always have _tons_ of
84 data queued for playback. */
85 if (SDL_GetAudioStreamQueued(stream) < (int)wav_data_len) {
86 /* feed more data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */
87 SDL_PutAudioStreamData(stream, wav_data, wav_data_len);
88 }
89
90 /* we're not doing anything with the renderer, so just blank it out. */
91 SDL_RenderClear(renderer);
92 SDL_RenderPresent(renderer);
93
94 return SDL_APP_CONTINUE; /* carry on with the program! */
95}
96
97/* This function runs once at shutdown. */
98void SDL_AppQuit(void *appstate, SDL_AppResult result)
99{
100 SDL_free(wav_data); /* strictly speaking, this isn't necessary because the process is ending, but it's good policy. */
101 /* SDL will clean up the window/renderer for us. */
102}
103
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 @@
1If you're running this in a web browser, you need to click the window before you'll hear anything!
2
3This example code loads two .wav files, puts them an audio streams and binds
4them for playback, repeating both sounds on loop. This shows several streams
5mixing 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 @@
1/*
2 * This example code loads two .wav files, puts them an audio streams and
3 * binds them for playback, repeating both sounds on loop. This shows several
4 * streams mixing into a single playback device.
5 *
6 * This code is public domain. Feel free to use it for any purpose!
7 */
8
9#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
10#include <SDL3/SDL.h>
11#include <SDL3/SDL_main.h>
12
13/* We will use this renderer to draw into this window every frame. */
14static SDL_Window *window = NULL;
15static SDL_Renderer *renderer = NULL;
16static SDL_AudioDeviceID audio_device = 0;
17
18/* things that are playing sound (the audiostream itself, plus the original data, so we can refill to loop. */
19typedef struct Sound {
20 Uint8 *wav_data;
21 Uint32 wav_data_len;
22 SDL_AudioStream *stream;
23} Sound;
24
25static Sound sounds[2];
26
27static bool init_sound(const char *fname, Sound *sound)
28{
29 bool retval = false;
30 SDL_AudioSpec spec;
31 char *wav_path = NULL;
32
33 /* Load the .wav files from wherever the app is being run from. */
34 SDL_asprintf(&wav_path, "%s%s", SDL_GetBasePath(), fname); /* allocate a string of the full file path */
35 if (!SDL_LoadWAV(wav_path, &spec, &sound->wav_data, &sound->wav_data_len)) {
36 SDL_Log("Couldn't load .wav file: %s", SDL_GetError());
37 return false;
38 }
39
40 /* Create an audio stream. Set the source format to the wav's format (what
41 we'll input), leave the dest format NULL here (it'll change to what the
42 device wants once we bind it). */
43 sound->stream = SDL_CreateAudioStream(&spec, NULL);
44 if (!sound->stream) {
45 SDL_Log("Couldn't create audio stream: %s", SDL_GetError());
46 } else if (!SDL_BindAudioStream(audio_device, sound->stream)) { /* once bound, it'll start playing when there is data available! */
47 SDL_Log("Failed to bind '%s' stream to device: %s", fname, SDL_GetError());
48 } else {
49 retval = true; /* success! */
50 }
51
52 SDL_free(wav_path); /* done with this string. */
53 return retval;
54}
55
56
57/* This function runs once at startup. */
58SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
59{
60
61 SDL_SetAppMetadata("Example Audio Multiple Streams", "1.0", "com.example.audio-multiple-streams");
62
63 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
64 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
65 return SDL_APP_FAILURE;
66 }
67
68 if (!SDL_CreateWindowAndRenderer("examples/audio/multiple-streams", 640, 480, 0, &window, &renderer)) {
69 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
70 return SDL_APP_FAILURE;
71 }
72
73 /* open the default audio device in whatever format it prefers; our audio streams will adjust to it. */
74 audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL);
75 if (audio_device == 0) {
76 SDL_Log("Couldn't open audio device: %s", SDL_GetError());
77 return SDL_APP_FAILURE;
78 }
79
80 if (!init_sound("sample.wav", &sounds[0])) {
81 return SDL_APP_FAILURE;
82 } else if (!init_sound("sword.wav", &sounds[1])) {
83 return SDL_APP_FAILURE;
84 }
85
86 return SDL_APP_CONTINUE; /* carry on with the program! */
87}
88
89/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
90SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
91{
92 if (event->type == SDL_EVENT_QUIT) {
93 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
94 }
95 return SDL_APP_CONTINUE; /* carry on with the program! */
96}
97
98/* This function runs once per frame, and is the heart of the program. */
99SDL_AppResult SDL_AppIterate(void *appstate)
100{
101 int i;
102
103 for (i = 0; i < SDL_arraysize(sounds); i++) {
104 /* If less than a full copy of the audio is queued for playback, put another copy in there.
105 This is overkill, but easy when lots of RAM is cheap. One could be more careful and
106 queue less at a time, as long as the stream doesn't run dry. */
107 if (SDL_GetAudioStreamQueued(sounds[i].stream) < ((int) sounds[i].wav_data_len)) {
108 SDL_PutAudioStreamData(sounds[i].stream, sounds[i].wav_data, (int) sounds[i].wav_data_len);
109 }
110 }
111
112 /* just blank the screen. */
113 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
114 SDL_RenderClear(renderer);
115 SDL_RenderPresent(renderer);
116
117 return SDL_APP_CONTINUE; /* carry on with the program! */
118}
119
120/* This function runs once at shutdown. */
121void SDL_AppQuit(void *appstate, SDL_AppResult result)
122{
123 int i;
124
125 SDL_CloseAudioDevice(audio_device);
126
127 for (i = 0; i < SDL_arraysize(sounds); i++) {
128 if (sounds[i].stream) {
129 SDL_DestroyAudioStream(sounds[i].stream);
130 }
131 SDL_free(sounds[i].wav_data);
132 }
133
134 /* SDL will clean up the window/renderer for us. */
135}
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/audio/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/audio/thumbnail.png
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/onmouseover.webp
Binary files 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 @@
1/*
2 * This example code reads frames from a camera and draws it to the screen.
3 *
4 * This is a very simple approach that is often Good Enough. You can get
5 * fancier with this: multiple cameras, front/back facing cameras on phones,
6 * color spaces, choosing formats and framerates...this just requests
7 * _anything_ and goes with what it is handed.
8 *
9 * This code is public domain. Feel free to use it for any purpose!
10 */
11
12#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
13#include <SDL3/SDL.h>
14#include <SDL3/SDL_main.h>
15
16/* We will use this renderer to draw into this window every frame. */
17static SDL_Window *window = NULL;
18static SDL_Renderer *renderer = NULL;
19static SDL_Camera *camera = NULL;
20static SDL_Texture *texture = NULL;
21
22
23/* This function runs once at startup. */
24SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
25{
26 SDL_CameraID *devices = NULL;
27 int devcount = 0;
28
29 SDL_SetAppMetadata("Example Camera Read and Draw", "1.0", "com.example.camera-read-and-draw");
30
31 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA)) {
32 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
33 return SDL_APP_FAILURE;
34 }
35
36 if (!SDL_CreateWindowAndRenderer("examples/camera/read-and-draw", 640, 480, 0, &window, &renderer)) {
37 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
38 return SDL_APP_FAILURE;
39 }
40
41 devices = SDL_GetCameras(&devcount);
42 if (devices == NULL) {
43 SDL_Log("Couldn't enumerate camera devices: %s", SDL_GetError());
44 return SDL_APP_FAILURE;
45 } else if (devcount == 0) {
46 SDL_Log("Couldn't find any camera devices! Please connect a camera and try again.");
47 return SDL_APP_FAILURE;
48 }
49
50 camera = SDL_OpenCamera(devices[0], NULL); // just take the first thing we see in any format it wants.
51 SDL_free(devices);
52 if (camera == NULL) {
53 SDL_Log("Couldn't open camera: %s", SDL_GetError());
54 return SDL_APP_FAILURE;
55 }
56
57 return SDL_APP_CONTINUE; /* carry on with the program! */
58}
59
60/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
61SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
62{
63 if (event->type == SDL_EVENT_QUIT) {
64 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
65 } else if (event->type == SDL_EVENT_CAMERA_DEVICE_APPROVED) {
66 SDL_Log("Camera use approved by user!");
67 } else if (event->type == SDL_EVENT_CAMERA_DEVICE_DENIED) {
68 SDL_Log("Camera use denied by user!");
69 return SDL_APP_FAILURE;
70 }
71 return SDL_APP_CONTINUE; /* carry on with the program! */
72}
73
74/* This function runs once per frame, and is the heart of the program. */
75SDL_AppResult SDL_AppIterate(void *appstate)
76{
77 Uint64 timestampNS = 0;
78 SDL_Surface *frame = SDL_AcquireCameraFrame(camera, &timestampNS);
79
80 if (frame != NULL) {
81 /* Some platforms (like Emscripten) don't know _what_ the camera offers
82 until the user gives permission, so we build the texture and resize
83 the window when we get a first frame from the camera. */
84 if (!texture) {
85 SDL_SetWindowSize(window, frame->w, frame->h); /* Resize the window to match */
86 texture = SDL_CreateTexture(renderer, frame->format, SDL_TEXTUREACCESS_STREAMING, frame->w, frame->h);
87 }
88
89 if (texture) {
90 SDL_UpdateTexture(texture, NULL, frame->pixels, frame->pitch);
91 }
92
93 SDL_ReleaseCameraFrame(camera, frame);
94 }
95
96 SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, SDL_ALPHA_OPAQUE);
97 SDL_RenderClear(renderer);
98 if (texture) { /* draw the latest camera frame, if available. */
99 SDL_RenderTexture(renderer, texture, NULL, NULL);
100 }
101 SDL_RenderPresent(renderer);
102
103 return SDL_APP_CONTINUE; /* carry on with the program! */
104}
105
106/* This function runs once at shutdown. */
107void SDL_AppQuit(void *appstate, SDL_AppResult result)
108{
109 SDL_CloseCamera(camera);
110 SDL_DestroyTexture(texture);
111 /* SDL will clean up the window/renderer for us. */
112}
113
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/camera/01-read-and-draw/thumbnail.png
Binary files 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 @@
1# Blank lines and lines that start with '#' in this file are ignored.
2
3# Categories, by directory name, go in here, in the order they should be
4# listed on the main page. If this file is missing, it'll assume any
5# subdirectory is a category and sort them alphabetically.
6
7renderer
8input
9audio
10camera
11asyncio
12pen
13demo
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/01-snake/onmouseover.webp
Binary files 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 @@
1/*
2 * Logic implementation of the Snake game. It is designed to efficiently
3 * represent the state of the game in memory.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12#define STEP_RATE_IN_MILLISECONDS 125
13#define SNAKE_BLOCK_SIZE_IN_PIXELS 24
14#define SDL_WINDOW_WIDTH (SNAKE_BLOCK_SIZE_IN_PIXELS * SNAKE_GAME_WIDTH)
15#define SDL_WINDOW_HEIGHT (SNAKE_BLOCK_SIZE_IN_PIXELS * SNAKE_GAME_HEIGHT)
16
17#define SNAKE_GAME_WIDTH 24U
18#define SNAKE_GAME_HEIGHT 18U
19#define SNAKE_MATRIX_SIZE (SNAKE_GAME_WIDTH * SNAKE_GAME_HEIGHT)
20
21#define THREE_BITS 0x7U /* ~CHAR_MAX >> (CHAR_BIT - SNAKE_CELL_MAX_BITS) */
22#define SHIFT(x, y) (((x) + ((y) * SNAKE_GAME_WIDTH)) * SNAKE_CELL_MAX_BITS)
23
24typedef enum
25{
26 SNAKE_CELL_NOTHING = 0U,
27 SNAKE_CELL_SRIGHT = 1U,
28 SNAKE_CELL_SUP = 2U,
29 SNAKE_CELL_SLEFT = 3U,
30 SNAKE_CELL_SDOWN = 4U,
31 SNAKE_CELL_FOOD = 5U
32} SnakeCell;
33
34#define SNAKE_CELL_MAX_BITS 3U /* floor(log2(SNAKE_CELL_FOOD)) + 1 */
35
36typedef enum
37{
38 SNAKE_DIR_RIGHT,
39 SNAKE_DIR_UP,
40 SNAKE_DIR_LEFT,
41 SNAKE_DIR_DOWN
42} SnakeDirection;
43
44typedef struct
45{
46 unsigned char cells[(SNAKE_MATRIX_SIZE * SNAKE_CELL_MAX_BITS) / 8U];
47 char head_xpos;
48 char head_ypos;
49 char tail_xpos;
50 char tail_ypos;
51 char next_dir;
52 char inhibit_tail_step;
53 unsigned occupied_cells;
54} SnakeContext;
55
56typedef struct
57{
58 SDL_Window *window;
59 SDL_Renderer *renderer;
60 SnakeContext snake_ctx;
61 Uint64 last_step;
62} AppState;
63
64SnakeCell snake_cell_at(const SnakeContext *ctx, char x, char y)
65{
66 const int shift = SHIFT(x, y);
67 unsigned short range;
68 SDL_memcpy(&range, ctx->cells + (shift / 8), sizeof(range));
69 return (SnakeCell)((range >> (shift % 8)) & THREE_BITS);
70}
71
72static void set_rect_xy_(SDL_FRect *r, short x, short y)
73{
74 r->x = (float)(x * SNAKE_BLOCK_SIZE_IN_PIXELS);
75 r->y = (float)(y * SNAKE_BLOCK_SIZE_IN_PIXELS);
76}
77
78static void put_cell_at_(SnakeContext *ctx, char x, char y, SnakeCell ct)
79{
80 const int shift = SHIFT(x, y);
81 const int adjust = shift % 8;
82 unsigned char *const pos = ctx->cells + (shift / 8);
83 unsigned short range;
84 SDL_memcpy(&range, pos, sizeof(range));
85 range &= ~(THREE_BITS << adjust); /* clear bits */
86 range |= (ct & THREE_BITS) << adjust;
87 SDL_memcpy(pos, &range, sizeof(range));
88}
89
90static int are_cells_full_(SnakeContext *ctx)
91{
92 return ctx->occupied_cells == SNAKE_GAME_WIDTH * SNAKE_GAME_HEIGHT;
93}
94
95static void new_food_pos_(SnakeContext *ctx)
96{
97 while (true) {
98 const char x = (char) SDL_rand(SNAKE_GAME_WIDTH);
99 const char y = (char) SDL_rand(SNAKE_GAME_HEIGHT);
100 if (snake_cell_at(ctx, x, y) == SNAKE_CELL_NOTHING) {
101 put_cell_at_(ctx, x, y, SNAKE_CELL_FOOD);
102 break;
103 }
104 }
105}
106
107void snake_initialize(SnakeContext *ctx)
108{
109 int i;
110 SDL_zeroa(ctx->cells);
111 ctx->head_xpos = ctx->tail_xpos = SNAKE_GAME_WIDTH / 2;
112 ctx->head_ypos = ctx->tail_ypos = SNAKE_GAME_HEIGHT / 2;
113 ctx->next_dir = SNAKE_DIR_RIGHT;
114 ctx->inhibit_tail_step = ctx->occupied_cells = 4;
115 --ctx->occupied_cells;
116 put_cell_at_(ctx, ctx->tail_xpos, ctx->tail_ypos, SNAKE_CELL_SRIGHT);
117 for (i = 0; i < 4; i++) {
118 new_food_pos_(ctx);
119 ++ctx->occupied_cells;
120 }
121}
122
123void snake_redir(SnakeContext *ctx, SnakeDirection dir)
124{
125 SnakeCell ct = snake_cell_at(ctx, ctx->head_xpos, ctx->head_ypos);
126 if ((dir == SNAKE_DIR_RIGHT && ct != SNAKE_CELL_SLEFT) ||
127 (dir == SNAKE_DIR_UP && ct != SNAKE_CELL_SDOWN) ||
128 (dir == SNAKE_DIR_LEFT && ct != SNAKE_CELL_SRIGHT) ||
129 (dir == SNAKE_DIR_DOWN && ct != SNAKE_CELL_SUP)) {
130 ctx->next_dir = dir;
131 }
132}
133
134static void wrap_around_(char *val, char max)
135{
136 if (*val < 0) {
137 *val = max - 1;
138 } else if (*val > max - 1) {
139 *val = 0;
140 }
141}
142
143void snake_step(SnakeContext *ctx)
144{
145 const SnakeCell dir_as_cell = (SnakeCell)(ctx->next_dir + 1);
146 SnakeCell ct;
147 char prev_xpos;
148 char prev_ypos;
149 /* Move tail forward */
150 if (--ctx->inhibit_tail_step == 0) {
151 ++ctx->inhibit_tail_step;
152 ct = snake_cell_at(ctx, ctx->tail_xpos, ctx->tail_ypos);
153 put_cell_at_(ctx, ctx->tail_xpos, ctx->tail_ypos, SNAKE_CELL_NOTHING);
154 switch (ct) {
155 case SNAKE_CELL_SRIGHT:
156 ctx->tail_xpos++;
157 break;
158 case SNAKE_CELL_SUP:
159 ctx->tail_ypos--;
160 break;
161 case SNAKE_CELL_SLEFT:
162 ctx->tail_xpos--;
163 break;
164 case SNAKE_CELL_SDOWN:
165 ctx->tail_ypos++;
166 break;
167 default:
168 break;
169 }
170 wrap_around_(&ctx->tail_xpos, SNAKE_GAME_WIDTH);
171 wrap_around_(&ctx->tail_ypos, SNAKE_GAME_HEIGHT);
172 }
173 /* Move head forward */
174 prev_xpos = ctx->head_xpos;
175 prev_ypos = ctx->head_ypos;
176 switch (ctx->next_dir) {
177 case SNAKE_DIR_RIGHT:
178 ++ctx->head_xpos;
179 break;
180 case SNAKE_DIR_UP:
181 --ctx->head_ypos;
182 break;
183 case SNAKE_DIR_LEFT:
184 --ctx->head_xpos;
185 break;
186 case SNAKE_DIR_DOWN:
187 ++ctx->head_ypos;
188 break;
189 }
190 wrap_around_(&ctx->head_xpos, SNAKE_GAME_WIDTH);
191 wrap_around_(&ctx->head_ypos, SNAKE_GAME_HEIGHT);
192 /* Collisions */
193 ct = snake_cell_at(ctx, ctx->head_xpos, ctx->head_ypos);
194 if (ct != SNAKE_CELL_NOTHING && ct != SNAKE_CELL_FOOD) {
195 snake_initialize(ctx);
196 return;
197 }
198 put_cell_at_(ctx, prev_xpos, prev_ypos, dir_as_cell);
199 put_cell_at_(ctx, ctx->head_xpos, ctx->head_ypos, dir_as_cell);
200 if (ct == SNAKE_CELL_FOOD) {
201 if (are_cells_full_(ctx)) {
202 snake_initialize(ctx);
203 return;
204 }
205 new_food_pos_(ctx);
206 ++ctx->inhibit_tail_step;
207 ++ctx->occupied_cells;
208 }
209}
210
211static SDL_AppResult handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code)
212{
213 switch (key_code) {
214 /* Quit. */
215 case SDL_SCANCODE_ESCAPE:
216 case SDL_SCANCODE_Q:
217 return SDL_APP_SUCCESS;
218 /* Restart the game as if the program was launched. */
219 case SDL_SCANCODE_R:
220 snake_initialize(ctx);
221 break;
222 /* Decide new direction of the snake. */
223 case SDL_SCANCODE_RIGHT:
224 snake_redir(ctx, SNAKE_DIR_RIGHT);
225 break;
226 case SDL_SCANCODE_UP:
227 snake_redir(ctx, SNAKE_DIR_UP);
228 break;
229 case SDL_SCANCODE_LEFT:
230 snake_redir(ctx, SNAKE_DIR_LEFT);
231 break;
232 case SDL_SCANCODE_DOWN:
233 snake_redir(ctx, SNAKE_DIR_DOWN);
234 break;
235 default:
236 break;
237 }
238 return SDL_APP_CONTINUE;
239}
240
241SDL_AppResult SDL_AppIterate(void *appstate)
242{
243 AppState *as = (AppState *)appstate;
244 SnakeContext *ctx = &as->snake_ctx;
245 const Uint64 now = SDL_GetTicks();
246 SDL_FRect r;
247 unsigned i;
248 unsigned j;
249 int ct;
250
251 // run game logic if we're at or past the time to run it.
252 // if we're _really_ behind the time to run it, run it
253 // several times.
254 while ((now - as->last_step) >= STEP_RATE_IN_MILLISECONDS) {
255 snake_step(ctx);
256 as->last_step += STEP_RATE_IN_MILLISECONDS;
257 }
258
259 r.w = r.h = SNAKE_BLOCK_SIZE_IN_PIXELS;
260 SDL_SetRenderDrawColor(as->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
261 SDL_RenderClear(as->renderer);
262 for (i = 0; i < SNAKE_GAME_WIDTH; i++) {
263 for (j = 0; j < SNAKE_GAME_HEIGHT; j++) {
264 ct = snake_cell_at(ctx, i, j);
265 if (ct == SNAKE_CELL_NOTHING)
266 continue;
267 set_rect_xy_(&r, i, j);
268 if (ct == SNAKE_CELL_FOOD)
269 SDL_SetRenderDrawColor(as->renderer, 80, 80, 255, SDL_ALPHA_OPAQUE);
270 else /* body */
271 SDL_SetRenderDrawColor(as->renderer, 0, 128, 0, SDL_ALPHA_OPAQUE);
272 SDL_RenderFillRect(as->renderer, &r);
273 }
274 }
275 SDL_SetRenderDrawColor(as->renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /*head*/
276 set_rect_xy_(&r, ctx->head_xpos, ctx->head_ypos);
277 SDL_RenderFillRect(as->renderer, &r);
278 SDL_RenderPresent(as->renderer);
279 return SDL_APP_CONTINUE;
280}
281
282static const struct
283{
284 const char *key;
285 const char *value;
286} extended_metadata[] =
287{
288 { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/01-snake/" },
289 { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" },
290 { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" },
291 { SDL_PROP_APP_METADATA_TYPE_STRING, "game" }
292};
293
294SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
295{
296 size_t i;
297
298 if (!SDL_SetAppMetadata("Example Snake game", "1.0", "com.example.Snake")) {
299 return SDL_APP_FAILURE;
300 }
301
302 for (i = 0; i < SDL_arraysize(extended_metadata); i++) {
303 if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) {
304 return SDL_APP_FAILURE;
305 }
306 }
307
308 if (!SDL_Init(SDL_INIT_VIDEO)) {
309 return SDL_APP_FAILURE;
310 }
311
312 AppState *as = (AppState *)SDL_calloc(1, sizeof(AppState));
313 if (!as) {
314 return SDL_APP_FAILURE;
315 }
316
317 *appstate = as;
318
319 if (!SDL_CreateWindowAndRenderer("examples/demo/snake", SDL_WINDOW_WIDTH, SDL_WINDOW_HEIGHT, 0, &as->window, &as->renderer)) {
320 return SDL_APP_FAILURE;
321 }
322
323 snake_initialize(&as->snake_ctx);
324
325 as->last_step = SDL_GetTicks();
326
327 return SDL_APP_CONTINUE;
328}
329
330SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
331{
332 SnakeContext *ctx = &((AppState *)appstate)->snake_ctx;
333 switch (event->type) {
334 case SDL_EVENT_QUIT:
335 return SDL_APP_SUCCESS;
336 case SDL_EVENT_KEY_DOWN:
337 return handle_key_event_(ctx, event->key.scancode);
338 }
339 return SDL_APP_CONTINUE;
340}
341
342void SDL_AppQuit(void *appstate, SDL_AppResult result)
343{
344 if (appstate != NULL) {
345 AppState *as = (AppState *)appstate;
346 SDL_DestroyRenderer(as->renderer);
347 SDL_DestroyWindow(as->window);
348 SDL_free(as);
349 }
350}
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/01-snake/thumbnail.png
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/thumbnail.png
Binary files 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 @@
1/*
2 * This code is public domain. Feel free to use it for any purpose!
3 */
4
5#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
6#include <SDL3/SDL.h>
7#include <SDL3/SDL_main.h>
8
9#define MAP_BOX_SCALE 16
10#define MAP_BOX_EDGES_LEN (12 + MAP_BOX_SCALE * 2)
11#define MAX_PLAYER_COUNT 4
12#define CIRCLE_DRAW_SIDES 32
13#define CIRCLE_DRAW_SIDES_LEN (CIRCLE_DRAW_SIDES + 1)
14
15typedef struct {
16 SDL_MouseID mouse;
17 SDL_KeyboardID keyboard;
18 double pos[3];
19 double vel[3];
20 unsigned int yaw;
21 int pitch;
22 float radius, height;
23 unsigned char color[3];
24 unsigned char wasd;
25} Player;
26
27typedef struct {
28 SDL_Window *window;
29 SDL_Renderer *renderer;
30 int player_count;
31 Player players[MAX_PLAYER_COUNT];
32 float edges[MAP_BOX_EDGES_LEN][6];
33} AppState;
34
35static const struct {
36 const char *key;
37 const char *value;
38} extended_metadata[] = {
39 { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/02-woodeneye-008/" },
40 { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" },
41 { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" },
42 { SDL_PROP_APP_METADATA_TYPE_STRING, "game" }
43};
44
45static int whoseMouse(SDL_MouseID mouse, const Player players[], int players_len)
46{
47 int i;
48 for (i = 0; i < players_len; i++) {
49 if (players[i].mouse == mouse) return i;
50 }
51 return -1;
52}
53
54static int whoseKeyboard(SDL_KeyboardID keyboard, const Player players[], int players_len)
55{
56 int i;
57 for (i = 0; i < players_len; i++) {
58 if (players[i].keyboard == keyboard) return i;
59 }
60 return -1;
61}
62
63static void shoot(int shooter, Player players[], int players_len)
64{
65 int i, j;
66 double x0 = players[shooter].pos[0];
67 double y0 = players[shooter].pos[1];
68 double z0 = players[shooter].pos[2];
69 double bin_rad = SDL_PI_D / 2147483648.0;
70 double yaw_rad = bin_rad * players[shooter].yaw;
71 double pitch_rad = bin_rad * players[shooter].pitch;
72 double cos_yaw = SDL_cos( yaw_rad);
73 double sin_yaw = SDL_sin( yaw_rad);
74 double cos_pitch = SDL_cos(pitch_rad);
75 double sin_pitch = SDL_sin(pitch_rad);
76 double vx = -sin_yaw*cos_pitch;
77 double vy = sin_pitch;
78 double vz = -cos_yaw*cos_pitch;
79 for (i = 0; i < players_len; i++) {
80 if (i == shooter) continue;
81 Player *target = &(players[i]);
82 int hit = 0;
83 for (j = 0; j < 2; j++) {
84 double r = target->radius;
85 double h = target->height;
86 double dx = target->pos[0] - x0;
87 double dy = target->pos[1] - y0 + (j == 0 ? 0 : r - h);
88 double dz = target->pos[2] - z0;
89 double vd = vx*dx + vy*dy + vz*dz;
90 double dd = dx*dx + dy*dy + dz*dz;
91 double vv = vx*vx + vy*vy + vz*vz;
92 double rr = r * r;
93 if (vd < 0) continue;
94 if (vd * vd >= vv * (dd - rr)) hit += 1;
95 }
96 if (hit) {
97 target->pos[0] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256;
98 target->pos[1] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256;
99 target->pos[2] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256;
100 }
101 }
102}
103
104static void update(Player *players, int players_len, Uint64 dt_ns)
105{
106 int i;
107 for (i = 0; i < players_len; i++) {
108 Player *player = &players[i];
109 double rate = 6.0;
110 double time = (double)dt_ns * 1e-9;
111 double drag = SDL_exp(-time * rate);
112 double diff = 1.0 - drag;
113 double mult = 60.0;
114 double grav = 25.0;
115 double yaw = (double)player->yaw;
116 double rad = yaw * SDL_PI_D / 2147483648.0;
117 double cos = SDL_cos(rad);
118 double sin = SDL_sin(rad);
119 unsigned char wasd = player->wasd;
120 double dirX = (wasd & 8 ? 1.0 : 0.0) - (wasd & 2 ? 1.0 : 0.0);
121 double dirZ = (wasd & 4 ? 1.0 : 0.0) - (wasd & 1 ? 1.0 : 0.0);
122 double norm = dirX * dirX + dirZ * dirZ;
123 double accX = mult * (norm == 0 ? 0 : ( cos*dirX + sin*dirZ) / SDL_sqrt(norm));
124 double accZ = mult * (norm == 0 ? 0 : (-sin*dirX + cos*dirZ) / SDL_sqrt(norm));
125 double velX = player->vel[0];
126 double velY = player->vel[1];
127 double velZ = player->vel[2];
128 player->vel[0] -= velX * diff;
129 player->vel[1] -= grav * time;
130 player->vel[2] -= velZ * diff;
131 player->vel[0] += diff * accX / rate;
132 player->vel[2] += diff * accZ / rate;
133 player->pos[0] += (time - diff/rate) * accX / rate + diff * velX / rate;
134 player->pos[1] += -0.5 * grav * time * time + velY * time;
135 player->pos[2] += (time - diff/rate) * accZ / rate + diff * velZ / rate;
136 double scale = (double)MAP_BOX_SCALE;
137 double bound = scale - player->radius;
138 double posX = SDL_max(SDL_min(bound, player->pos[0]), -bound);
139 double posY = SDL_max(SDL_min(bound, player->pos[1]), player->height - scale);
140 double posZ = SDL_max(SDL_min(bound, player->pos[2]), -bound);
141 if (player->pos[0] != posX) player->vel[0] = 0;
142 if (player->pos[1] != posY) player->vel[1] = (wasd & 16) ? 8.4375 : 0;
143 if (player->pos[2] != posZ) player->vel[2] = 0;
144 player->pos[0] = posX;
145 player->pos[1] = posY;
146 player->pos[2] = posZ;
147 }
148}
149
150static void drawCircle(SDL_Renderer *renderer, float r, float x, float y)
151{
152 float ang;
153 SDL_FPoint points[CIRCLE_DRAW_SIDES_LEN];
154 int i;
155 for (i = 0; i < CIRCLE_DRAW_SIDES_LEN; i++) {
156 ang = 2.0f * SDL_PI_F * (float)i / (float)CIRCLE_DRAW_SIDES;
157 points[i].x = x + r * SDL_cosf(ang);
158 points[i].y = y + r * SDL_sinf(ang);
159 }
160 SDL_RenderLines(renderer, (const SDL_FPoint*)&points, CIRCLE_DRAW_SIDES_LEN);
161}
162
163static void drawClippedSegment(
164 SDL_Renderer *renderer,
165 float ax, float ay, float az,
166 float bx, float by, float bz,
167 float x, float y, float z, float w)
168{
169 if (az >= -w && bz >= -w) return;
170 float dx = ax - bx;
171 float dy = ay - by;
172 if (az > -w) {
173 float t = (-w - bz) / (az - bz);
174 ax = bx + dx * t;
175 ay = by + dy * t;
176 az = -w;
177 } else if (bz > -w) {
178 float t = (-w - az) / (bz - az);
179 bx = ax - dx * t;
180 by = ay - dy * t;
181 bz = -w;
182 }
183 ax = -z * ax / az;
184 ay = -z * ay / az;
185 bx = -z * bx / bz;
186 by = -z * by / bz;
187 SDL_RenderLine(renderer, x + ax, y - ay, x + bx, y - by);
188}
189
190static char debug_string[32];
191static void draw(SDL_Renderer *renderer, const float (*edges)[6], const Player players[], int players_len)
192{
193 int w, h, i, j, k;
194 if (!SDL_GetRenderOutputSize(renderer, &w, &h)) {
195 return;
196 }
197 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
198 SDL_RenderClear(renderer);
199 if (players_len > 0) {
200 float wf = (float)w;
201 float hf = (float)h;
202 int part_hor = players_len > 2 ? 2 : 1;
203 int part_ver = players_len > 1 ? 2 : 1;
204 float size_hor = wf / ((float)part_hor);
205 float size_ver = hf / ((float)part_ver);
206 for (i = 0; i < players_len; i++) {
207 const Player *player = &players[i];
208 float mod_x = (float)(i % part_hor);
209 float mod_y = (float)(i / part_hor);
210 float hor_origin = (mod_x + 0.5f) * size_hor;
211 float ver_origin = (mod_y + 0.5f) * size_ver;
212 float cam_origin = (float)(0.5 * SDL_sqrt(size_hor * size_hor + size_ver * size_ver));
213 float hor_offset = mod_x * size_hor;
214 float ver_offset = mod_y * size_ver;
215 SDL_Rect rect;
216 rect.x = (int)hor_offset;
217 rect.y = (int)ver_offset;
218 rect.w = (int)size_hor;
219 rect.h = (int)size_ver;
220 SDL_SetRenderClipRect(renderer, &rect);
221 double x0 = player->pos[0];
222 double y0 = player->pos[1];
223 double z0 = player->pos[2];
224 double bin_rad = SDL_PI_D / 2147483648.0;
225 double yaw_rad = bin_rad * player->yaw;
226 double pitch_rad = bin_rad * player->pitch;
227 double cos_yaw = SDL_cos( yaw_rad);
228 double sin_yaw = SDL_sin( yaw_rad);
229 double cos_pitch = SDL_cos(pitch_rad);
230 double sin_pitch = SDL_sin(pitch_rad);
231 double mat[9] = {
232 cos_yaw , 0, -sin_yaw ,
233 sin_yaw*sin_pitch, cos_pitch, cos_yaw*sin_pitch,
234 sin_yaw*cos_pitch, -sin_pitch, cos_yaw*cos_pitch
235 };
236 SDL_SetRenderDrawColor(renderer, 64, 64, 64, 255);
237 for (k = 0; k < MAP_BOX_EDGES_LEN; k++) {
238 const float *line = edges[k];
239 float ax = (float)(mat[0] * (line[0] - x0) + mat[1] * (line[1] - y0) + mat[2] * (line[2] - z0));
240 float ay = (float)(mat[3] * (line[0] - x0) + mat[4] * (line[1] - y0) + mat[5] * (line[2] - z0));
241 float az = (float)(mat[6] * (line[0] - x0) + mat[7] * (line[1] - y0) + mat[8] * (line[2] - z0));
242 float bx = (float)(mat[0] * (line[3] - x0) + mat[1] * (line[4] - y0) + mat[2] * (line[5] - z0));
243 float by = (float)(mat[3] * (line[3] - x0) + mat[4] * (line[4] - y0) + mat[5] * (line[5] - z0));
244 float bz = (float)(mat[6] * (line[3] - x0) + mat[7] * (line[4] - y0) + mat[8] * (line[5] - z0));
245 drawClippedSegment(renderer, ax, ay, az, bx, by, bz, hor_origin, ver_origin, cam_origin, 1);
246 }
247 for (j = 0; j < players_len; j++) {
248 if (i == j) continue;
249 const Player *target = &players[j];
250 SDL_SetRenderDrawColor(renderer, target->color[0], target->color[1], target->color[2], 255);
251 for (k = 0; k < 2; k++) {
252 double rx = target->pos[0] - player->pos[0];
253 double ry = target->pos[1] - player->pos[1] + (target->radius - target->height) * (float)k;
254 double rz = target->pos[2] - player->pos[2];
255 double dx = mat[0] * rx + mat[1] * ry + mat[2] * rz;
256 double dy = mat[3] * rx + mat[4] * ry + mat[5] * rz;
257 double dz = mat[6] * rx + mat[7] * ry + mat[8] * rz;
258 double r_eff = target->radius * cam_origin / dz;
259 if (!(dz < 0)) continue;
260 drawCircle(renderer, (float)(r_eff), (float)(hor_origin - cam_origin*dx/dz), (float)(ver_origin + cam_origin*dy/dz));
261 }
262 }
263 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
264 SDL_RenderLine(renderer, hor_origin, ver_origin-10, hor_origin, ver_origin+10);
265 SDL_RenderLine(renderer, hor_origin-10, ver_origin, hor_origin+10, ver_origin);
266 }
267 }
268 SDL_SetRenderClipRect(renderer, 0);
269 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
270 SDL_RenderDebugText(renderer, 0, 0, debug_string);
271 SDL_RenderPresent(renderer);
272}
273
274static void initPlayers(Player *players, int len)
275{
276 int i;
277 for (i = 0; i < len; i++) {
278 players[i].pos[0] = 8.0 * (i & 1 ? -1.0 : 1.0);
279 players[i].pos[1] = 0;
280 players[i].pos[2] = 8.0 * (i & 1 ? -1.0 : 1.0) * (i & 2 ? -1.0 : 1.0);
281 players[i].vel[0] = 0;
282 players[i].vel[1] = 0;
283 players[i].vel[2] = 0;
284 players[i].yaw = 0x20000000 + (i & 1 ? 0x80000000 : 0) + (i & 2 ? 0x40000000 : 0);
285 players[i].pitch = -0x08000000;
286 players[i].radius = 0.5f;
287 players[i].height = 1.5f;
288 players[i].wasd = 0;
289 players[i].mouse = 0;
290 players[i].keyboard = 0;
291 players[i].color[0] = (1 << (i / 2)) & 2 ? 0 : 0xff;
292 players[i].color[1] = (1 << (i / 2)) & 1 ? 0 : 0xff;
293 players[i].color[2] = (1 << (i / 2)) & 4 ? 0 : 0xff;
294 players[i].color[0] = (i & 1) ? players[i].color[0] : ~players[i].color[0];
295 players[i].color[1] = (i & 1) ? players[i].color[1] : ~players[i].color[1];
296 players[i].color[2] = (i & 1) ? players[i].color[2] : ~players[i].color[2];
297 }
298}
299
300static void initEdges(int scale, float (*edges)[6], int edges_len)
301{
302 int i, j;
303 const float r = (float)scale;
304 const int map[24] = {
305 0,1 , 1,3 , 3,2 , 2,0 ,
306 7,6 , 6,4 , 4,5 , 5,7 ,
307 6,2 , 3,7 , 0,4 , 5,1
308 };
309 for(i = 0; i < 12; i++) {
310 for (j = 0; j < 3; j++) {
311 edges[i][j+0] = (map[i*2+0] & (1 << j) ? r : -r);
312 edges[i][j+3] = (map[i*2+1] & (1 << j) ? r : -r);
313 }
314 }
315 for(i = 0; i < scale; i++) {
316 float d = (float)(i * 2);
317 for (j = 0; j < 2; j++) {
318 edges[i+12][3*j+0] = j ? r : -r;
319 edges[i+12][3*j+1] = -r;
320 edges[i+12][3*j+2] = d-r;
321 edges[i+12+scale][3*j+0] = d-r;
322 edges[i+12+scale][3*j+1] = -r;
323 edges[i+12+scale][3*j+2] = j ? r : -r;
324 }
325 }
326}
327
328SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
329{
330 if (!SDL_SetAppMetadata("Example splitscreen shooter game", "1.0", "com.example.woodeneye-008")) {
331 return SDL_APP_FAILURE;
332 }
333 int i;
334 for (i = 0; i < SDL_arraysize(extended_metadata); i++) {
335 if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) {
336 return SDL_APP_FAILURE;
337 }
338 }
339
340 AppState *as = SDL_calloc(1, sizeof(AppState));
341 if (!as) {
342 return SDL_APP_FAILURE;
343 } else {
344 *appstate = as;
345 }
346
347 if (!SDL_Init(SDL_INIT_VIDEO)) {
348 return SDL_APP_FAILURE;
349 }
350 if (!SDL_CreateWindowAndRenderer("examples/demo/woodeneye-008", 640, 480, 0, &as->window, &as->renderer)) {
351 return SDL_APP_FAILURE;
352 }
353
354 as->player_count = 1;
355 initPlayers(as->players, MAX_PLAYER_COUNT);
356 initEdges(MAP_BOX_SCALE, as->edges, MAP_BOX_EDGES_LEN);
357 debug_string[0] = 0;
358
359 SDL_SetRenderVSync(as->renderer, false);
360 SDL_SetWindowRelativeMouseMode(as->window, true);
361 SDL_SetHintWithPriority(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1", SDL_HINT_OVERRIDE);
362 return SDL_APP_CONTINUE;
363}
364
365SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
366{
367 AppState *as = appstate;
368 Player *players = as->players;
369 int player_count = as->player_count;
370 int i;
371 switch (event->type) {
372 case SDL_EVENT_QUIT:
373 return SDL_APP_SUCCESS;
374 break;
375 case SDL_EVENT_MOUSE_REMOVED:
376 for (i = 0; i < player_count; i++) {
377 if (players[i].mouse == event->mdevice.which) {
378 players[i].mouse = 0;
379 }
380 }
381 break;
382 case SDL_EVENT_KEYBOARD_REMOVED:
383 for (i = 0; i < player_count; i++) {
384 if (players[i].keyboard == event->kdevice.which) {
385 players[i].keyboard = 0;
386 }
387 }
388 break;
389 case SDL_EVENT_MOUSE_MOTION: {
390 SDL_MouseID id = event->motion.which;
391 int index = whoseMouse(id, players, player_count);
392 if (index >= 0) {
393 players[index].yaw -= ((int)event->motion.xrel) * 0x00080000;
394 players[index].pitch = SDL_max(-0x40000000, SDL_min(0x40000000, players[index].pitch - ((int)event->motion.yrel) * 0x00080000));
395 } else if (id) {
396 for (i = 0; i < MAX_PLAYER_COUNT; i++) {
397 if (players[i].mouse == 0) {
398 players[i].mouse = id;
399 as->player_count = SDL_max(as->player_count, i + 1);
400 break;
401 }
402 }
403 }
404 break;
405 }
406 case SDL_EVENT_MOUSE_BUTTON_DOWN: {
407 SDL_MouseID id = event->button.which;
408 int index = whoseMouse(id, players, player_count);
409 if (index >= 0) {
410 shoot(index, players, player_count);
411 }
412 break;
413 }
414 case SDL_EVENT_KEY_DOWN: {
415 SDL_Keycode sym = event->key.key;
416 SDL_KeyboardID id = event->key.which;
417 int index = whoseKeyboard(id, players, player_count);
418 if (index >= 0) {
419 if (sym == SDLK_W) players[index].wasd |= 1;
420 if (sym == SDLK_A) players[index].wasd |= 2;
421 if (sym == SDLK_S) players[index].wasd |= 4;
422 if (sym == SDLK_D) players[index].wasd |= 8;
423 if (sym == SDLK_SPACE) players[index].wasd |= 16;
424 } else if (id) {
425 for (i = 0; i < MAX_PLAYER_COUNT; i++) {
426 if (players[i].keyboard == 0) {
427 players[i].keyboard = id;
428 as->player_count = SDL_max(as->player_count, i + 1);
429 break;
430 }
431 }
432 }
433 break;
434 }
435 case SDL_EVENT_KEY_UP: {
436 SDL_Keycode sym = event->key.key;
437 SDL_KeyboardID id = event->key.which;
438 if (sym == SDLK_ESCAPE) return SDL_APP_SUCCESS;
439 int index = whoseKeyboard(id, players, player_count);
440 if (index >= 0) {
441 if (sym == SDLK_W) players[index].wasd &= 30;
442 if (sym == SDLK_A) players[index].wasd &= 29;
443 if (sym == SDLK_S) players[index].wasd &= 27;
444 if (sym == SDLK_D) players[index].wasd &= 23;
445 if (sym == SDLK_SPACE) players[index].wasd &= 15;
446 }
447 break;
448 }
449 }
450 return SDL_APP_CONTINUE;
451}
452
453SDL_AppResult SDL_AppIterate(void *appstate)
454{
455 AppState *as = appstate;
456 static Uint64 accu = 0;
457 static Uint64 last = 0;
458 static Uint64 past = 0;
459 Uint64 now = SDL_GetTicksNS();
460 Uint64 dt_ns = now - past;
461 update(as->players, as->player_count, dt_ns);
462 draw(as->renderer, (const float (*)[6])as->edges, as->players, as->player_count);
463 if (now - last > 999999999) {
464 last = now;
465 SDL_snprintf(debug_string, sizeof(debug_string), "%" SDL_PRIu64 " fps", accu);
466 accu = 0;
467 }
468 past = now;
469 accu += 1;
470 Uint64 elapsed = SDL_GetTicksNS() - now;
471 if (elapsed < 999999) {
472 SDL_DelayNS(999999 - elapsed);
473 }
474 return SDL_APP_CONTINUE;
475}
476
477void SDL_AppQuit(void *appstate, SDL_AppResult result)
478{
479 SDL_free(appstate); // just free the memory, SDL will clean up the window/renderer for us.
480} \ 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 @@
1
2How many monkeys does it take to write the complete works of Shakespeare?
3
4 Now you can find out!
5
6Cheer on your favorite monkey as they bash keyboards on their way through classic literature.
7
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 @@
1/*
2 * This code is public domain. Feel free to use it for any purpose!
3 */
4
5#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
6#include <SDL3/SDL.h>
7#include <SDL3/SDL_main.h>
8
9/* We will use this renderer to draw into this window every frame. */
10static SDL_Window *window = NULL;
11static SDL_Renderer *renderer = NULL;
12static char *text;
13static const char *end;
14static const char *progress;
15static SDL_Time start_time;
16static SDL_Time end_time;
17typedef struct {
18 Uint32 *text;
19 int length;
20} Line;
21int row = 0;
22int rows = 0;
23int cols = 0;
24static Line **lines;
25static Line monkey_chars;
26static int monkeys = 100;
27
28/* The highest and lowest scancodes a monkey can hit */
29#define MIN_MONKEY_SCANCODE SDL_SCANCODE_A
30#define MAX_MONKEY_SCANCODE SDL_SCANCODE_SLASH
31
32static const char *default_text =
33"Jabberwocky, by Lewis Carroll\n"
34"\n"
35"'Twas brillig, and the slithy toves\n"
36" Did gyre and gimble in the wabe:\n"
37"All mimsy were the borogoves,\n"
38" And the mome raths outgrabe.\n"
39"\n"
40"\"Beware the Jabberwock, my son!\n"
41" The jaws that bite, the claws that catch!\n"
42"Beware the Jubjub bird, and shun\n"
43" The frumious Bandersnatch!\"\n"
44"\n"
45"He took his vorpal sword in hand;\n"
46" Long time the manxome foe he sought-\n"
47"So rested he by the Tumtum tree\n"
48" And stood awhile in thought.\n"
49"\n"
50"And, as in uffish thought he stood,\n"
51" The Jabberwock, with eyes of flame,\n"
52"Came whiffling through the tulgey wood,\n"
53" And burbled as it came!\n"
54"\n"
55"One, two! One, two! And through and through\n"
56" The vorpal blade went snicker-snack!\n"
57"He left it dead, and with its head\n"
58" He went galumphing back.\n"
59"\n"
60"\"And hast thou slain the Jabberwock?\n"
61" Come to my arms, my beamish boy!\n"
62"O frabjous day! Callooh! Callay!\"\n"
63" He chortled in his joy.\n"
64"\n"
65"'Twas brillig, and the slithy toves\n"
66" Did gyre and gimble in the wabe:\n"
67"All mimsy were the borogoves,\n"
68" And the mome raths outgrabe.\n";
69
70
71static void FreeLines(void)
72{
73 int i;
74
75 if (rows > 0 && cols > 0) {
76 for (i = 0; i < rows; ++i) {
77 SDL_free(lines[i]->text);
78 SDL_free(lines[i]);
79 }
80 SDL_free(lines);
81 lines = NULL;
82 }
83 SDL_free(monkey_chars.text);
84 monkey_chars.text = NULL;
85}
86
87static void OnWindowSizeChanged(void)
88{
89 int w, h;
90
91 if (!SDL_GetCurrentRenderOutputSize(renderer, &w, &h)) {
92 return;
93 }
94
95 FreeLines();
96
97 row = 0;
98 rows = (h / SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) - 4;
99 cols = (w / SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE);
100 if (rows > 0 && cols > 0) {
101 int i;
102
103 lines = (Line **)SDL_malloc(rows * sizeof(Line *));
104 if (lines) {
105 for (i = 0; i < rows; ++i) {
106 lines[i] = (Line *)SDL_malloc(sizeof(Line));
107 if (!lines[i]) {
108 FreeLines();
109 break;
110 }
111 lines[i]->text = (Uint32 *)SDL_malloc(cols * sizeof(Uint32));
112 if (!lines[i]->text) {
113 FreeLines();
114 break;
115 }
116 lines[i]->length = 0;
117 }
118 }
119
120 monkey_chars.text = (Uint32 *)SDL_malloc(cols * sizeof(Uint32));
121 if (monkey_chars.text) {
122 for (i = 0; i < cols; ++i) {
123 monkey_chars.text[i] = ' ';
124 }
125 monkey_chars.length = cols;
126 }
127 }
128}
129
130/* This function runs once at startup. */
131SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
132{
133 int arg = 1;
134
135 SDL_SetAppMetadata("Infinite Monkeys", "1.0", "com.example.infinite-monkeys");
136
137 if (!SDL_Init(SDL_INIT_VIDEO)) {
138 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
139 return SDL_APP_FAILURE;
140 }
141
142 if (!SDL_CreateWindowAndRenderer("examples/demo/infinite-monkeys", 640, 480, 0, &window, &renderer)) {
143 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
144 return SDL_APP_FAILURE;
145 }
146 SDL_SetRenderVSync(renderer, 1);
147
148 if (argv[arg] && SDL_strcmp(argv[arg], "--monkeys") == 0) {
149 ++arg;
150 if (argv[arg]) {
151 monkeys = SDL_atoi(argv[arg]);
152 ++arg;
153 } else {
154 SDL_Log("Usage: %s [--monkeys N] [file.txt]", argv[0]);
155 return SDL_APP_FAILURE;
156 }
157 }
158
159 if (argv[arg]) {
160 const char *file = argv[arg];
161 size_t size;
162 text = (char *)SDL_LoadFile(file, &size);
163 if (!text) {
164 SDL_Log("Couldn't open %s: %s", file, SDL_GetError());
165 return SDL_APP_FAILURE;
166 }
167 end = text + size;
168 } else {
169 text = SDL_strdup(default_text);
170 end = text + SDL_strlen(text);
171 }
172 progress = text;
173
174 SDL_GetCurrentTime(&start_time);
175
176 OnWindowSizeChanged();
177
178 return SDL_APP_CONTINUE; /* carry on with the program! */
179}
180
181/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
182SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
183{
184 switch (event->type) {
185 case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
186 OnWindowSizeChanged();
187 break;
188 case SDL_EVENT_QUIT:
189 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
190 }
191 return SDL_APP_CONTINUE; /* carry on with the program! */
192}
193
194static void DisplayLine(float x, float y, Line *line)
195{
196 /* Allocate maximum space potentially needed for this line */
197 char *utf8 = (char *)SDL_malloc(line->length * 4 + 1);
198 if (utf8) {
199 char *spot = utf8;
200 int i;
201
202 for (i = 0; i < line->length; ++i) {
203 spot = SDL_UCS4ToUTF8(line->text[i], spot);
204 }
205 *spot = '\0';
206
207 SDL_RenderDebugText(renderer, x, y, utf8);
208 SDL_free(utf8);
209 }
210}
211
212static bool CanMonkeyType(Uint32 ch)
213{
214 SDL_Keymod modstate;
215 SDL_Scancode scancode = SDL_GetScancodeFromKey(ch, &modstate);
216 if (scancode < MIN_MONKEY_SCANCODE || scancode > MAX_MONKEY_SCANCODE) {
217 return false;
218 }
219 /* Monkeys can hit the shift key, but nothing else */
220 if ((modstate & ~SDL_KMOD_SHIFT) != 0) {
221 return false;
222 }
223 return true;
224}
225
226static void AdvanceRow(void)
227{
228 Line *line;
229
230 ++row;
231 line = lines[row % rows];
232 line->length = 0;
233}
234
235static void AddMonkeyChar(int monkey, Uint32 ch)
236{
237 if (monkey >= 0 && monkey_chars.text) {
238 monkey_chars.text[(monkey % cols)] = ch;
239 }
240
241 if (lines) {
242 if (ch == '\n') {
243 AdvanceRow();
244 } else {
245 Line *line = lines[row % rows];
246 line->text[line->length++] = ch;
247 if (line->length == cols) {
248 AdvanceRow();
249 }
250 }
251 }
252
253 SDL_StepUTF8(&progress, NULL);
254}
255
256static Uint32 GetNextChar(void)
257{
258 Uint32 ch = 0;
259 while (progress < end) {
260 const char *spot = progress;
261 ch = SDL_StepUTF8(&spot, NULL);
262 if (CanMonkeyType(ch)) {
263 break;
264 } else {
265 /* This is a freebie, monkeys can't type this */
266 AddMonkeyChar(-1, ch);
267 }
268 }
269 return ch;
270}
271
272static Uint32 MonkeyPlay(void)
273{
274 int count = (MAX_MONKEY_SCANCODE - MIN_MONKEY_SCANCODE + 1);
275 SDL_Scancode scancode = (SDL_Scancode)(MIN_MONKEY_SCANCODE + SDL_rand(count));
276 SDL_Keymod modstate = (SDL_rand(2) ? SDL_KMOD_SHIFT : 0);
277
278 return SDL_GetKeyFromScancode(scancode, modstate, false);
279}
280
281/* This function runs once per frame, and is the heart of the program. */
282SDL_AppResult SDL_AppIterate(void *appstate)
283{
284 int i, monkey;
285 Uint32 next_char = 0, ch;
286 float x, y;
287 char *caption = NULL;
288 SDL_Time now, elapsed;
289 int hours, minutes, seconds;
290 SDL_FRect rect;
291
292 for (monkey = 0; monkey < monkeys; ++monkey) {
293 if (next_char == 0) {
294 next_char = GetNextChar();
295 if (!next_char) {
296 /* All done! */
297 break;
298 }
299 }
300
301 ch = MonkeyPlay();
302 if (ch == next_char) {
303 AddMonkeyChar(monkey, ch);
304 next_char = 0;
305 }
306 }
307
308 /* Clear the screen */
309 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
310 SDL_RenderClear(renderer);
311
312 /* Show the text already decoded */
313 SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
314 x = 0.0f;
315 y = 0.0f;
316 if (lines) {
317 int row_offset = row - rows + 1;
318 if (row_offset < 0) {
319 row_offset = 0;
320 }
321 for (i = 0; i < rows; ++i) {
322 Line *line = lines[(row_offset + i) % rows];
323 DisplayLine(x, y, line);
324 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
325 }
326
327 /* Show the caption */
328 y = (float)((rows + 1) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE);
329 if (progress == end) {
330 if (!end_time) {
331 SDL_GetCurrentTime(&end_time);
332 }
333 now = end_time;
334 } else {
335 SDL_GetCurrentTime(&now);
336 }
337 elapsed = (now - start_time);
338 elapsed /= SDL_NS_PER_SECOND;
339 seconds = (int)(elapsed % 60);
340 elapsed /= 60;
341 minutes = (int)(elapsed % 60);
342 elapsed /= 60;
343 hours = (int)elapsed;
344 SDL_asprintf(&caption, "Monkeys: %d - %dH:%dM:%dS", monkeys, hours, minutes, seconds);
345 if (caption) {
346 SDL_RenderDebugText(renderer, x, y, caption);
347 SDL_free(caption);
348 }
349 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
350
351 /* Show the characters currently typed */
352 DisplayLine(x, y, &monkey_chars);
353 y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
354 }
355
356 /* Show the current progress */
357 SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
358 rect.x = x;
359 rect.y = y;
360 rect.w = ((float)(progress - text) / (end - text)) * (cols * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE);
361 rect.h = (float)SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
362 SDL_RenderFillRect(renderer, &rect);
363
364 SDL_RenderPresent(renderer);
365
366 return SDL_APP_CONTINUE; /* carry on with the program! */
367}
368
369/* This function runs once at shutdown. */
370void SDL_AppQuit(void *appstate, SDL_AppResult result)
371{
372 /* SDL will clean up the window/renderer for us. */
373
374 FreeLines();
375 SDL_free(text);
376}
377
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/03-infinite-monkeys/thumbnail.png
Binary files 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 @@
1An implementation of the BytePusher VM
2
3For example programs and more information about BytePusher, see
4https://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 @@
1/*
2 * An implementation of the BytePusher VM.
3 *
4 * For example programs and more information about BytePusher, see
5 * https://esolangs.org/wiki/BytePusher
6 *
7 * This code is public domain. Feel free to use it for any purpose!
8 */
9
10#define SDL_MAIN_USE_CALLBACKS
11#include <SDL3/SDL.h>
12#include <SDL3/SDL_main.h>
13#include <stdarg.h>
14
15#define SCREEN_W 256
16#define SCREEN_H 256
17#define RAM_SIZE 0x1000000
18#define FRAMES_PER_SECOND 60
19#define SAMPLES_PER_FRAME 256
20#define NS_PER_SECOND (Uint64)SDL_NS_PER_SECOND
21#define MAX_AUDIO_LATENCY_FRAMES 5
22
23#define IO_KEYBOARD 0
24#define IO_PC 2
25#define IO_SCREEN_PAGE 5
26#define IO_AUDIO_BANK 6
27
28typedef struct {
29 Uint8 ram[RAM_SIZE + 8];
30 Uint8 screenbuf[SCREEN_W * SCREEN_H];
31 Uint64 last_tick;
32 Uint64 tick_acc;
33 SDL_Window* window;
34 SDL_Renderer* renderer;
35 SDL_Surface* screen;
36 SDL_Texture* screentex;
37 SDL_Texture* rendertarget; /* we need this render target for text to look good */
38 SDL_AudioStream* audiostream;
39 char status[SCREEN_W / 8];
40 int status_ticks;
41 Uint16 keystate;
42 bool display_help;
43 bool positional_input;
44} BytePusher;
45
46static const struct {
47 const char *key;
48 const char *value;
49} extended_metadata[] = {
50 { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/04-bytepusher/" },
51 { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" },
52 { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" },
53 { SDL_PROP_APP_METADATA_TYPE_STRING, "game" }
54};
55
56static inline Uint16 read_u16(const BytePusher* vm, Uint32 addr) {
57 const Uint8* ptr = &vm->ram[addr];
58 return ((Uint16)ptr[0] << 8) | ((Uint16)ptr[1]);
59}
60
61static inline Uint32 read_u24(const BytePusher* vm, Uint32 addr) {
62 const Uint8* ptr = &vm->ram[addr];
63 return ((Uint32)ptr[0] << 16) | ((Uint32)ptr[1] << 8) | ((Uint32)ptr[2]);
64}
65
66static void set_status(BytePusher* vm, const char* fmt, ...) {
67 va_list args;
68 va_start(args, fmt);
69 SDL_vsnprintf(vm->status, sizeof(vm->status), fmt, args);
70 va_end(args);
71 vm->status[sizeof(vm->status) - 1] = 0;
72 vm->status_ticks = FRAMES_PER_SECOND * 3;
73}
74
75static bool load(BytePusher* vm, SDL_IOStream* stream, bool closeio) {
76 size_t bytes_read = 0;
77 bool ok = true;
78
79 SDL_memset(vm->ram, 0, RAM_SIZE);
80
81 if (!stream) {
82 return false;
83 }
84
85 while (bytes_read < RAM_SIZE) {
86 size_t read = SDL_ReadIO(stream, &vm->ram[bytes_read], RAM_SIZE - bytes_read);
87 bytes_read += read;
88 if (read == 0) {
89 ok = SDL_GetIOStatus(stream) == SDL_IO_STATUS_EOF;
90 break;
91 }
92 }
93 if (closeio) {
94 SDL_CloseIO(stream);
95 }
96
97 SDL_ClearAudioStream(vm->audiostream);
98
99 vm->display_help = !ok;
100 return ok;
101}
102
103static const char* filename(const char* path) {
104 size_t i = SDL_strlen(path) + 1;
105 while (i > 0) {
106 i -= 1;
107 if (path[i] == '/' || path[i] == '\\') {
108 return path + i + 1;
109 }
110 }
111 return path;
112}
113
114static bool load_file(BytePusher* vm, const char* path) {
115 if (load(vm, SDL_IOFromFile(path, "rb"), true)) {
116 set_status(vm, "loaded %s", filename(path));
117 return true;
118 } else {
119 set_status(vm, "load failed: %s", filename(path));
120 return false;
121 }
122}
123
124static void print(BytePusher* vm, int x, int y, const char* str) {
125 SDL_SetRenderDrawColor(vm->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
126 SDL_RenderDebugText(vm->renderer, (float)(x + 1), (float)(y + 1), str);
127 SDL_SetRenderDrawColor(vm->renderer, 0xff, 0xff, 0xff, SDL_ALPHA_OPAQUE);
128 SDL_RenderDebugText(vm->renderer, (float)x, (float)y, str);
129 SDL_SetRenderDrawColor(vm->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
130}
131
132SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
133 BytePusher* vm;
134 SDL_Palette* palette;
135 SDL_Rect usable_bounds;
136 SDL_AudioSpec audiospec = { SDL_AUDIO_S8, 1, SAMPLES_PER_FRAME * FRAMES_PER_SECOND };
137 SDL_DisplayID primary_display;
138 SDL_PropertiesID texprops;
139 int zoom = 2;
140 int i;
141 Uint8 r, g, b;
142 (void)argc;
143 (void)argv;
144
145 if (!SDL_SetAppMetadata("SDL 3 BytePusher", "1.0", "com.example.SDL3BytePusher")) {
146 return SDL_APP_FAILURE;
147 }
148
149 for (i = 0; i < (int)SDL_arraysize(extended_metadata); i++) {
150 if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) {
151 return SDL_APP_FAILURE;
152 }
153 }
154
155 if (!SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO)) {
156 return SDL_APP_FAILURE;
157 }
158
159 if (!(vm = (BytePusher *)SDL_calloc(1, sizeof(*vm)))) {
160 return SDL_APP_FAILURE;
161 }
162 *(BytePusher**)appstate = vm;
163
164 vm->display_help = true;
165
166 primary_display = SDL_GetPrimaryDisplay();
167 if (SDL_GetDisplayUsableBounds(primary_display, &usable_bounds)) {
168 int zoom_w = (usable_bounds.w - usable_bounds.x) * 2 / 3 / SCREEN_W;
169 int zoom_h = (usable_bounds.h - usable_bounds.y) * 2 / 3 / SCREEN_H;
170 zoom = zoom_w < zoom_h ? zoom_w : zoom_h;
171 if (zoom < 1) {
172 zoom = 1;
173 }
174 }
175
176 if (!SDL_CreateWindowAndRenderer("SDL 3 BytePusher",
177 SCREEN_W * zoom, SCREEN_H * zoom, SDL_WINDOW_RESIZABLE,
178 &vm->window, &vm->renderer
179 )) {
180 return SDL_APP_FAILURE;
181 }
182
183 if (!SDL_SetRenderLogicalPresentation(
184 vm->renderer, SCREEN_W, SCREEN_H, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE
185 )) {
186 return SDL_APP_FAILURE;
187 }
188
189 if (!(vm->screen = SDL_CreateSurfaceFrom(
190 SCREEN_W, SCREEN_H, SDL_PIXELFORMAT_INDEX8, vm->screenbuf, SCREEN_W
191 ))) {
192 return SDL_APP_FAILURE;
193 }
194
195 if (!(palette = SDL_CreateSurfacePalette(vm->screen))) {
196 return SDL_APP_FAILURE;
197 }
198 i = 0;
199 for (r = 0; r < 6; ++r) {
200 for (g = 0; g < 6; ++g) {
201 for (b = 0; b < 6; ++b, ++i) {
202 SDL_Color color = { (Uint8)(r * 0x33), (Uint8)(g * 0x33), (Uint8)(b * 0x33), SDL_ALPHA_OPAQUE };
203 palette->colors[i] = color;
204 }
205 }
206 }
207 for (; i < 256; ++i) {
208 SDL_Color color = { 0, 0, 0, SDL_ALPHA_OPAQUE };
209 palette->colors[i] = color;
210 }
211
212 texprops = SDL_CreateProperties();
213 SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STREAMING);
214 SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, SCREEN_W);
215 SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, SCREEN_H);
216 vm->screentex = SDL_CreateTextureWithProperties(vm->renderer, texprops);
217 SDL_SetNumberProperty(texprops, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_TARGET);
218 vm->rendertarget = SDL_CreateTextureWithProperties(vm->renderer, texprops);
219 SDL_DestroyProperties(texprops);
220 if (!vm->screentex || !vm->rendertarget) {
221 return SDL_APP_FAILURE;
222 }
223 SDL_SetTextureScaleMode(vm->screentex, SDL_SCALEMODE_NEAREST);
224 SDL_SetTextureScaleMode(vm->rendertarget, SDL_SCALEMODE_NEAREST);
225
226 if (!(vm->audiostream = SDL_OpenAudioDeviceStream(
227 SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audiospec, NULL, NULL
228 ))) {
229 return SDL_APP_FAILURE;
230 }
231 SDL_SetAudioStreamGain(vm->audiostream, 0.1f); /* examples are loud! */
232 SDL_ResumeAudioStreamDevice(vm->audiostream);
233
234 set_status(vm, "renderer: %s", SDL_GetRendererName(vm->renderer));
235
236 vm->last_tick = SDL_GetTicksNS();
237 vm->tick_acc = NS_PER_SECOND;
238
239 return SDL_APP_CONTINUE;
240}
241
242SDL_AppResult SDL_AppIterate(void* appstate) {
243 BytePusher* vm = (BytePusher*)appstate;
244
245 Uint64 tick = SDL_GetTicksNS();
246 Uint64 delta = tick - vm->last_tick;
247 bool updated, skip_audio;
248
249 vm->last_tick = tick;
250
251 vm->tick_acc += delta * FRAMES_PER_SECOND;
252 updated = vm->tick_acc >= NS_PER_SECOND;
253 skip_audio = vm->tick_acc >= MAX_AUDIO_LATENCY_FRAMES * NS_PER_SECOND;
254
255 if (skip_audio) {
256 // don't let audio fall too far behind
257 SDL_ClearAudioStream(vm->audiostream);
258 }
259
260 while (vm->tick_acc >= NS_PER_SECOND) {
261 Uint32 pc;
262 int i;
263
264 vm->tick_acc -= NS_PER_SECOND;
265
266 vm->ram[IO_KEYBOARD] = (Uint8)(vm->keystate >> 8);
267 vm->ram[IO_KEYBOARD + 1] = (Uint8)(vm->keystate);
268
269 pc = read_u24(vm, IO_PC);
270 for (i = 0; i < SCREEN_W * SCREEN_H; ++i) {
271 Uint32 src = read_u24(vm, pc);
272 Uint32 dst = read_u24(vm, pc + 3);
273 vm->ram[dst] = vm->ram[src];
274 pc = read_u24(vm, pc + 6);
275 }
276
277 if (!skip_audio || vm->tick_acc < NS_PER_SECOND) {
278 SDL_PutAudioStreamData(
279 vm->audiostream,
280 &vm->ram[(Uint32)read_u16(vm, IO_AUDIO_BANK) << 8],
281 SAMPLES_PER_FRAME
282 );
283 }
284 }
285
286 if (updated) {
287 SDL_Surface *tex;
288
289 SDL_SetRenderTarget(vm->renderer, vm->rendertarget);
290
291 if (!SDL_LockTextureToSurface(vm->screentex, NULL, &tex)) {
292 return SDL_APP_FAILURE;
293 }
294 vm->screen->pixels = &vm->ram[(Uint32)vm->ram[IO_SCREEN_PAGE] << 16];
295 SDL_BlitSurface(vm->screen, NULL, tex, NULL);
296 SDL_UnlockTexture(vm->screentex);
297
298 SDL_RenderTexture(vm->renderer, vm->screentex, NULL, NULL);
299 }
300
301 if (vm->display_help) {
302 print(vm, 4, 4, "Drop a BytePusher file in this");
303 print(vm, 8, 12, "window to load and run it!");
304 print(vm, 4, 28, "Press ENTER to switch between");
305 print(vm, 8, 36, "positional and symbolic input.");
306 }
307
308 if (vm->status_ticks > 0) {
309 vm->status_ticks -= 1;
310 print(vm, 4, SCREEN_H - 12, vm->status);
311 }
312
313 SDL_SetRenderTarget(vm->renderer, NULL);
314 SDL_RenderClear(vm->renderer);
315 SDL_RenderTexture(vm->renderer, vm->rendertarget, NULL, NULL);
316 SDL_RenderPresent(vm->renderer);
317
318 return SDL_APP_CONTINUE;
319}
320
321static Uint16 keycode_mask(SDL_Keycode key) {
322 int index;
323 if (key >= SDLK_0 && key <= SDLK_9) {
324 index = key - SDLK_0;
325 } else if (key >= SDLK_A && key <= SDLK_F) {
326 index = key - SDLK_A + 10;
327 } else {
328 return 0;
329 }
330 return (Uint16)1 << index;
331}
332
333static Uint16 scancode_mask(SDL_Scancode scancode) {
334 int index;
335 switch (scancode) {
336 case SDL_SCANCODE_1: index = 0x1; break;
337 case SDL_SCANCODE_2: index = 0x2; break;
338 case SDL_SCANCODE_3: index = 0x3; break;
339 case SDL_SCANCODE_4: index = 0xc; break;
340 case SDL_SCANCODE_Q: index = 0x4; break;
341 case SDL_SCANCODE_W: index = 0x5; break;
342 case SDL_SCANCODE_E: index = 0x6; break;
343 case SDL_SCANCODE_R: index = 0xd; break;
344 case SDL_SCANCODE_A: index = 0x7; break;
345 case SDL_SCANCODE_S: index = 0x8; break;
346 case SDL_SCANCODE_D: index = 0x9; break;
347 case SDL_SCANCODE_F: index = 0xe; break;
348 case SDL_SCANCODE_Z: index = 0xa; break;
349 case SDL_SCANCODE_X: index = 0x0; break;
350 case SDL_SCANCODE_C: index = 0xb; break;
351 case SDL_SCANCODE_V: index = 0xf; break;
352 default: return 0;
353 }
354 return (Uint16)1 << index;
355}
356
357SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
358 BytePusher* vm = (BytePusher*)appstate;
359
360 switch (event->type) {
361 case SDL_EVENT_QUIT:
362 return SDL_APP_SUCCESS;
363
364 case SDL_EVENT_DROP_FILE:
365 load_file(vm, event->drop.data);
366 break;
367
368 case SDL_EVENT_KEY_DOWN:
369#ifndef __EMSCRIPTEN__
370 if (event->key.key == SDLK_ESCAPE) {
371 return SDL_APP_SUCCESS;
372 }
373#endif
374 if (event->key.key == SDLK_RETURN) {
375 vm->positional_input = !vm->positional_input;
376 vm->keystate = 0;
377 if (vm->positional_input) {
378 set_status(vm, "switched to positional input");
379 } else {
380 set_status(vm, "switched to symbolic input");
381 }
382 }
383 if (vm->positional_input) {
384 vm->keystate |= scancode_mask(event->key.scancode);
385 } else {
386 vm->keystate |= keycode_mask(event->key.key);
387 }
388 break;
389
390 case SDL_EVENT_KEY_UP:
391 if (vm->positional_input) {
392 vm->keystate &= ~scancode_mask(event->key.scancode);
393 } else {
394 vm->keystate &= ~keycode_mask(event->key.key);
395 }
396 break;
397 }
398
399 return SDL_APP_CONTINUE;
400}
401
402void SDL_AppQuit(void* appstate, SDL_AppResult result) {
403 if (result == SDL_APP_FAILURE) {
404 SDL_Log("Error: %s", SDL_GetError());
405 }
406 if (appstate) {
407 BytePusher* vm = (BytePusher*)appstate;
408 SDL_DestroyAudioStream(vm->audiostream);
409 SDL_DestroyTexture(vm->rendertarget);
410 SDL_DestroyTexture(vm->screentex);
411 SDL_DestroySurface(vm->screen);
412 SDL_DestroyRenderer(vm->renderer);
413 SDL_DestroyWindow(vm->window);
414 SDL_free(vm);
415 }
416}
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/demo/04-bytepusher/thumbnail.png
Binary files 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 @@
1-- This code adapted from https://gitlab.com/saalen/highlight/-/wikis/Plug-Ins
2
3-- first add a description of what the plug-in does
4Description="Add wiki.libsdl.org reference links to HTML, LaTeX or RTF output"
5
6-- define the plugin categories (ie. supported output formats; languages)
7Categories = { "c", "c++" }
8
9-- the syntaxUpdate function contains code related to syntax recognition
10function syntaxUpdate(desc)
11
12 -- if the current file is not C/C++ file we exit
13 if desc~="C and C++" then
14 return
15 end
16
17 -- this function returns a qt-project reference link of the given token
18 function getURL(token)
19 -- generate the URL
20 url='https://wiki.libsdl.org/SDL3/'.. token
21
22 -- embed the URL in a hyperlink according to the output format
23 -- first HTML, then LaTeX and RTF
24 if (HL_OUTPUT== HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
25 return '<a class="hl" target="new" href="'
26 .. url .. '">'.. token .. '</a>'
27 elseif (HL_OUTPUT == HL_FORMAT_LATEX) then
28 return '\\href{'..url..'}{'..token..'}'
29 elseif (HL_OUTPUT == HL_FORMAT_RTF) then
30 return '{{\\field{\\*\\fldinst HYPERLINK "'
31 ..url..'" }{\\fldrslt\\ul\\ulc0 '..token..'}}}'
32 end
33 end
34
35 -- the Decorate function will be invoked for every recognized token
36 function Decorate(token, state)
37
38 -- we are only interested in keywords, preprocessor or default items
39 if (state ~= HL_STANDARD and state ~= HL_KEYWORD and
40 state ~=HL_PREPROC) then
41 return
42 end
43
44 -- SDL keywords start with SDL_
45 -- if this pattern applies to the token, we return the URL
46 -- if we return nothing, the token is outputted as is
47 if ( (token == "Uint8") or (token == "Uint16") or (token == "Uint32") or (token == "Uint64") or
48 (token == "Sint8") or (token == "Sint16") or (token == "Sint32") or (token == "Sint64") or
49 (string.find(token, "SDL_") == 1) ) then
50 return getURL(token)
51 end
52
53 end
54end
55
56-- the themeUpdate function contains code related to the theme
57function themeUpdate(desc)
58 -- the Injections table can be used to add style information to the theme
59
60 -- HTML: we add additional CSS style information to beautify hyperlinks,
61 -- they should have the same color as their surrounding tags
62 if (HL_OUTPUT == HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
63 Injections[#Injections+1]=
64 "a.hl, a.hl:visited {color:inherit;font-weight:inherit;text-decoration:none}"
65
66 -- LaTeX: hyperlinks require the hyperref package, so we add this here
67 -- the colorlinks and pdfborderstyle options remove ugly boxes in the output
68 elseif (HL_OUTPUT==HL_FORMAT_LATEX) then
69 Injections[#Injections+1]=
70 "\\usepackage[colorlinks=false, pdfborderstyle={/S/U/W 1}]{hyperref}"
71 end
72end
73
74-- let highlight load the chunks
75Plugins={
76 { Type="lang", Chunk=syntaxUpdate },
77 { Type="theme", Chunk=themeUpdate },
78}
79
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 @@
1This example code looks for the current joystick state once per frame,
2and 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 @@
1/*
2 * This example code looks for the current joystick state once per frame,
3 * and draws a visual representation of it.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8/* Joysticks are low-level interfaces: there's something with a bunch of
9 buttons, axes and hats, in no understood order or position. This is
10 a flexible interface, but you'll need to build some sort of configuration
11 UI to let people tell you what button, etc, does what. On top of this
12 interface, SDL offers the "gamepad" API, which works with lots of devices,
13 and knows how to map arbitrary buttons and such to look like an
14 Xbox/PlayStation/etc gamepad. This is easier, and better, for many games,
15 but isn't necessarily a good fit for complex apps and hardware. A flight
16 simulator, a realistic racing game, etc, might want this interface instead
17 of gamepads. */
18
19/* SDL can handle multiple joysticks, but for simplicity, this program only
20 deals with the first stick it sees. */
21
22#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
23#include <SDL3/SDL.h>
24#include <SDL3/SDL_main.h>
25
26/* We will use this renderer to draw into this window every frame. */
27static SDL_Window *window = NULL;
28static SDL_Renderer *renderer = NULL;
29static SDL_Joystick *joystick = NULL;
30static SDL_Color colors[64];
31
32/* This function runs once at startup. */
33SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
34{
35 int i;
36
37 SDL_SetAppMetadata("Example Input Joystick Polling", "1.0", "com.example.input-joystick-polling");
38
39 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)) {
40 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
41 return SDL_APP_FAILURE;
42 }
43
44 if (!SDL_CreateWindowAndRenderer("examples/input/joystick-polling", 640, 480, 0, &window, &renderer)) {
45 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
46 return SDL_APP_FAILURE;
47 }
48
49 for (i = 0; i < SDL_arraysize(colors); i++) {
50 colors[i].r = SDL_rand(255);
51 colors[i].g = SDL_rand(255);
52 colors[i].b = SDL_rand(255);
53 colors[i].a = 255;
54 }
55
56 return SDL_APP_CONTINUE; /* carry on with the program! */
57}
58
59/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
60SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
61{
62 if (event->type == SDL_EVENT_QUIT) {
63 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
64 } else if (event->type == SDL_EVENT_JOYSTICK_ADDED) {
65 /* this event is sent for each hotplugged stick, but also each already-connected joystick during SDL_Init(). */
66 if (joystick == NULL) { /* we don't have a stick yet and one was added, open it! */
67 joystick = SDL_OpenJoystick(event->jdevice.which);
68 if (!joystick) {
69 SDL_Log("Failed to open joystick ID %u: %s", (unsigned int) event->jdevice.which, SDL_GetError());
70 }
71 }
72 } else if (event->type == SDL_EVENT_JOYSTICK_REMOVED) {
73 if (joystick && (SDL_GetJoystickID(joystick) == event->jdevice.which)) {
74 SDL_CloseJoystick(joystick); /* our joystick was unplugged. */
75 joystick = NULL;
76 }
77 }
78 return SDL_APP_CONTINUE; /* carry on with the program! */
79}
80
81/* This function runs once per frame, and is the heart of the program. */
82SDL_AppResult SDL_AppIterate(void *appstate)
83{
84 int winw = 640, winh = 480;
85 const char *text = "Plug in a joystick, please.";
86 float x, y;
87 int i;
88
89 if (joystick) { /* we have a stick opened? */
90 text = SDL_GetJoystickName(joystick);
91 }
92
93 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
94 SDL_RenderClear(renderer);
95 SDL_GetWindowSize(window, &winw, &winh);
96
97 /* note that you can get input as events, instead of polling, which is
98 better since it won't miss button presses if the system is lagging,
99 but often times checking the current state per-frame is good enough,
100 and maybe better if you'd rather _drop_ inputs due to lag. */
101
102 if (joystick) { /* we have a stick opened? */
103 const float size = 30.0f;
104 int total;
105
106 /* 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. */
107 total = SDL_GetNumJoystickAxes(joystick);
108 y = (winh - (total * size)) / 2;
109 x = ((float) winw) / 2.0f;
110 for (i = 0; i < total; i++) {
111 const SDL_Color *color = &colors[i % SDL_arraysize(colors)];
112 const float val = (((float) SDL_GetJoystickAxis(joystick, i)) / 32767.0f); /* make it -1.0f to 1.0f */
113 const float dx = x + (val * x);
114 const SDL_FRect dst = { dx, y, x - SDL_fabsf(dx), size };
115 SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a);
116 SDL_RenderFillRect(renderer, &dst);
117 y += size;
118 }
119
120 /* draw buttons as blocks across top of window. We only know the button numbers, but not where they are on the device. */
121 total = SDL_GetNumJoystickButtons(joystick);
122 x = (winw - (total * size)) / 2;
123 for (i = 0; i < total; i++) {
124 const SDL_Color *color = &colors[i % SDL_arraysize(colors)];
125 const SDL_FRect dst = { x, 0.0f, size, size };
126 if (SDL_GetJoystickButton(joystick, i)) {
127 SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a);
128 } else {
129 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
130 }
131 SDL_RenderFillRect(renderer, &dst);
132 SDL_SetRenderDrawColor(renderer, 255, 255, 255, color->a);
133 SDL_RenderRect(renderer, &dst); /* outline it */
134 x += size;
135 }
136
137 /* draw hats across the bottom of the screen. */
138 total = SDL_GetNumJoystickHats(joystick);
139 x = ((winw - (total * (size * 2.0f))) / 2.0f) + (size / 2.0f);
140 y = ((float) winh) - size;
141 for (i = 0; i < total; i++) {
142 const SDL_Color *color = &colors[i % SDL_arraysize(colors)];
143 const float thirdsize = size / 3.0f;
144 const SDL_FRect cross[] = { { x, y + thirdsize, size, thirdsize }, { x + thirdsize, y, thirdsize, size } };
145 const Uint8 hat = SDL_GetJoystickHat(joystick, i);
146
147 SDL_SetRenderDrawColor(renderer, 90, 90, 90, 255);
148 SDL_RenderFillRects(renderer, cross, SDL_arraysize(cross));
149
150 SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a);
151
152 if (hat & SDL_HAT_UP) {
153 const SDL_FRect dst = { x + thirdsize, y, thirdsize, thirdsize };
154 SDL_RenderFillRect(renderer, &dst);
155 }
156
157 if (hat & SDL_HAT_RIGHT) {
158 const SDL_FRect dst = { x + (thirdsize * 2), y + thirdsize, thirdsize, thirdsize };
159 SDL_RenderFillRect(renderer, &dst);
160 }
161
162 if (hat & SDL_HAT_DOWN) {
163 const SDL_FRect dst = { x + thirdsize, y + (thirdsize * 2), thirdsize, thirdsize };
164 SDL_RenderFillRect(renderer, &dst);
165 }
166
167 if (hat & SDL_HAT_LEFT) {
168 const SDL_FRect dst = { x, y + thirdsize, thirdsize, thirdsize };
169 SDL_RenderFillRect(renderer, &dst);
170 }
171
172 x += size * 2;
173 }
174 }
175
176 x = (((float) winw) - (SDL_strlen(text) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f;
177 y = (((float) winh) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2.0f;
178 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
179 SDL_RenderDebugText(renderer, x, y, text);
180 SDL_RenderPresent(renderer);
181
182 return SDL_APP_CONTINUE; /* carry on with the program! */
183}
184
185/* This function runs once at shutdown. */
186void SDL_AppQuit(void *appstate, SDL_AppResult result)
187{
188 if (joystick) {
189 SDL_CloseJoystick(joystick);
190 }
191
192 /* SDL will clean up the window/renderer for us. */
193}
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/input/01-joystick-polling/thumbnail.png
Binary files 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 @@
1This example code looks for joystick input in the event handler, and
2reports 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 @@
1/*
2 * This example code looks for joystick input in the event handler, and
3 * reports any changes as a flood of info.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8/* Joysticks are low-level interfaces: there's something with a bunch of
9 buttons, axes and hats, in no understood order or position. This is
10 a flexible interface, but you'll need to build some sort of configuration
11 UI to let people tell you what button, etc, does what. On top of this
12 interface, SDL offers the "gamepad" API, which works with lots of devices,
13 and knows how to map arbitrary buttons and such to look like an
14 Xbox/PlayStation/etc gamepad. This is easier, and better, for many games,
15 but isn't necessarily a good fit for complex apps and hardware. A flight
16 simulator, a realistic racing game, etc, might want this interface instead
17 of gamepads. */
18
19#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
20#include <SDL3/SDL.h>
21#include <SDL3/SDL_main.h>
22
23/* We will use this renderer to draw into this window every frame. */
24static SDL_Window *window = NULL;
25static SDL_Renderer *renderer = NULL;
26static SDL_Color colors[64];
27
28#define MOTION_EVENT_COOLDOWN 40
29
30typedef struct EventMessage
31{
32 char *str;
33 SDL_Color color;
34 Uint64 start_ticks;
35 struct EventMessage *next;
36} EventMessage;
37
38static EventMessage messages;
39static EventMessage *messages_tail = &messages;
40
41static const char *hat_state_string(Uint8 state)
42{
43 switch (state) {
44 case SDL_HAT_CENTERED: return "CENTERED";
45 case SDL_HAT_UP: return "UP";
46 case SDL_HAT_RIGHT: return "RIGHT";
47 case SDL_HAT_DOWN: return "DOWN";
48 case SDL_HAT_LEFT: return "LEFT";
49 case SDL_HAT_RIGHTUP: return "RIGHT+UP";
50 case SDL_HAT_RIGHTDOWN: return "RIGHT+DOWN";
51 case SDL_HAT_LEFTUP: return "LEFT+UP";
52 case SDL_HAT_LEFTDOWN: return "LEFT+DOWN";
53 default: break;
54 }
55 return "UNKNOWN";
56}
57
58static const char *battery_state_string(SDL_PowerState state)
59{
60 switch (state) {
61 case SDL_POWERSTATE_ERROR: return "ERROR";
62 case SDL_POWERSTATE_UNKNOWN: return "UNKNOWN";
63 case SDL_POWERSTATE_ON_BATTERY: return "ON BATTERY";
64 case SDL_POWERSTATE_NO_BATTERY: return "NO BATTERY";
65 case SDL_POWERSTATE_CHARGING: return "CHARGING";
66 case SDL_POWERSTATE_CHARGED: return "CHARGED";
67 default: break;
68 }
69 return "UNKNOWN";
70}
71
72static void add_message(SDL_JoystickID jid, const char *fmt, ...)
73{
74 const SDL_Color *color = &colors[((size_t) jid) % SDL_arraysize(colors)];
75 EventMessage *msg = NULL;
76 char *str = NULL;
77 va_list ap;
78
79 msg = (EventMessage *) SDL_calloc(1, sizeof (*msg));
80 if (!msg) {
81 return; // oh well.
82 }
83
84 va_start(ap, fmt);
85 SDL_vasprintf(&str, fmt, ap);
86 va_end(ap);
87 if (!str) {
88 SDL_free(msg);
89 return; // oh well.
90 }
91
92 msg->str = str;
93 SDL_copyp(&msg->color, color);
94 msg->start_ticks = SDL_GetTicks();
95 msg->next = NULL;
96
97 messages_tail->next = msg;
98 messages_tail = msg;
99}
100
101
102/* This function runs once at startup. */
103SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
104{
105 int i;
106
107 SDL_SetAppMetadata("Example Input Joystick Events", "1.0", "com.example.input-joystick-events");
108
109 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)) {
110 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
111 return SDL_APP_FAILURE;
112 }
113
114 if (!SDL_CreateWindowAndRenderer("examples/input/joystick-events", 640, 480, 0, &window, &renderer)) {
115 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
116 return SDL_APP_FAILURE;
117 }
118
119 colors[0].r = colors[0].g = colors[0].b = colors[0].a = 255;
120 for (i = 1; i < SDL_arraysize(colors); i++) {
121 colors[i].r = SDL_rand(255);
122 colors[i].g = SDL_rand(255);
123 colors[i].b = SDL_rand(255);
124 colors[i].a = 255;
125 }
126
127 add_message(0, "Please plug in a joystick.");
128
129 return SDL_APP_CONTINUE; /* carry on with the program! */
130}
131
132/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
133SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
134{
135 if (event->type == SDL_EVENT_QUIT) {
136 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
137 } else if (event->type == SDL_EVENT_JOYSTICK_ADDED) {
138 /* this event is sent for each hotplugged stick, but also each already-connected joystick during SDL_Init(). */
139 const SDL_JoystickID which = event->jdevice.which;
140 SDL_Joystick *joystick = SDL_OpenJoystick(which);
141 if (!joystick) {
142 add_message(which, "Joystick #%u add, but not opened: %s", (unsigned int) which, SDL_GetError());
143 } else {
144 add_message(which, "Joystick #%u ('%s') added", (unsigned int) which, SDL_GetJoystickName(joystick));
145 }
146 } else if (event->type == SDL_EVENT_JOYSTICK_REMOVED) {
147 const SDL_JoystickID which = event->jdevice.which;
148 SDL_Joystick *joystick = SDL_GetJoystickFromID(which);
149 if (joystick) {
150 SDL_CloseJoystick(joystick); /* the joystick was unplugged. */
151 }
152 add_message(which, "Joystick #%u removed", (unsigned int) which);
153 } else if (event->type == SDL_EVENT_JOYSTICK_AXIS_MOTION) {
154 static Uint64 axis_motion_cooldown_time = 0; /* these are spammy, only show every X milliseconds. */
155 const Uint64 now = SDL_GetTicks();
156 if (now >= axis_motion_cooldown_time) {
157 const SDL_JoystickID which = event->jaxis.which;
158 axis_motion_cooldown_time = now + MOTION_EVENT_COOLDOWN;
159 add_message(which, "Joystick #%u axis %d -> %d", (unsigned int) which, (int) event->jaxis.axis, (int) event->jaxis.value);
160 }
161 } else if (event->type == SDL_EVENT_JOYSTICK_BALL_MOTION) {
162 static Uint64 ball_motion_cooldown_time = 0; /* these are spammy, only show every X milliseconds. */
163 const Uint64 now = SDL_GetTicks();
164 if (now >= ball_motion_cooldown_time) {
165 const SDL_JoystickID which = event->jball.which;
166 ball_motion_cooldown_time = now + MOTION_EVENT_COOLDOWN;
167 add_message(which, "Joystick #%u ball %d -> %d, %d", (unsigned int) which, (int) event->jball.ball, (int) event->jball.xrel, (int) event->jball.yrel);
168 }
169 } else if (event->type == SDL_EVENT_JOYSTICK_HAT_MOTION) {
170 const SDL_JoystickID which = event->jhat.which;
171 add_message(which, "Joystick #%u hat %d -> %s", (unsigned int) which, (int) event->jhat.hat, hat_state_string(event->jhat.value));
172 } else if ((event->type == SDL_EVENT_JOYSTICK_BUTTON_UP) || (event->type == SDL_EVENT_JOYSTICK_BUTTON_DOWN)) {
173 const SDL_JoystickID which = event->jbutton.which;
174 add_message(which, "Joystick #%u button %d -> %s", (unsigned int) which, (int) event->jbutton.button, event->jbutton.down ? "PRESSED" : "RELEASED");
175 } else if (event->type == SDL_EVENT_JOYSTICK_BATTERY_UPDATED) {
176 const SDL_JoystickID which = event->jbattery.which;
177 add_message(which, "Joystick #%u battery -> %s - %d%%", (unsigned int) which, battery_state_string(event->jbattery.state), event->jbattery.percent);
178 }
179
180 return SDL_APP_CONTINUE; /* carry on with the program! */
181}
182
183/* This function runs once per frame, and is the heart of the program. */
184SDL_AppResult SDL_AppIterate(void *appstate)
185{
186 const Uint64 now = SDL_GetTicks();
187 const float msg_lifetime = 3500.0f; /* milliseconds a message lives for. */
188 EventMessage *msg = messages.next;
189 float prev_y = 0.0f;
190 int winw = 640, winh = 480;
191
192 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
193 SDL_RenderClear(renderer);
194 SDL_GetWindowSize(window, &winw, &winh);
195
196 while (msg) {
197 float x, y;
198 const float life_percent = ((float) (now - msg->start_ticks)) / msg_lifetime;
199 if (life_percent >= 1.0f) { /* msg is done. */
200 messages.next = msg->next;
201 if (messages_tail == msg) {
202 messages_tail = &messages;
203 }
204 SDL_free(msg->str);
205 SDL_free(msg);
206 msg = messages.next;
207 continue;
208 }
209 x = (((float) winw) - (SDL_strlen(msg->str) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f;
210 y = ((float) winh) * life_percent;
211 if ((prev_y != 0.0f) && ((prev_y - y) < ((float) SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE))) {
212 msg->start_ticks = now;
213 break; // wait for the previous message to tick up a little.
214 }
215
216 SDL_SetRenderDrawColor(renderer, msg->color.r, msg->color.g, msg->color.b, (Uint8) (((float) msg->color.a) * (1.0f - life_percent)));
217 SDL_RenderDebugText(renderer, x, y, msg->str);
218
219 prev_y = y;
220 msg = msg->next;
221 }
222
223 SDL_RenderPresent(renderer);
224
225 return SDL_APP_CONTINUE; /* carry on with the program! */
226}
227
228/* This function runs once at shutdown. */
229void SDL_AppQuit(void *appstate, SDL_AppResult result)
230{
231 /* SDL will clean up the window/renderer for us. We let the joysticks leak. */
232}
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/input/02-joystick-events/thumbnail.png
Binary files 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 @@
1You need something with a pen/stylus for this to work.
2
3This 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 @@
1/*
2 * This example code reads pen/stylus input and draws lines. Darker lines
3 * for harder pressure.
4 *
5 * SDL can track multiple pens, but for simplicity here, this assumes any
6 * pen input we see was from one device.
7 *
8 * This code is public domain. Feel free to use it for any purpose!
9 */
10
11#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
12#include <SDL3/SDL.h>
13#include <SDL3/SDL_main.h>
14
15/* We will use this renderer to draw into this window every frame. */
16static SDL_Window *window = NULL;
17static SDL_Renderer *renderer = NULL;
18static SDL_Texture *render_target = NULL;
19static float pressure = 0.0f;
20static float previous_touch_x = -1.0f;
21static float previous_touch_y = -1.0f;
22static float tilt_x = 0.0f;
23static float tilt_y = 0.0f;
24
25/* This function runs once at startup. */
26SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
27{
28 int w, h;
29
30 SDL_SetAppMetadata("Example Pen Drawing Lines", "1.0", "com.example.pen-drawing-lines");
31
32 if (!SDL_Init(SDL_INIT_VIDEO)) {
33 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
34 return SDL_APP_FAILURE;
35 }
36
37 if (!SDL_CreateWindowAndRenderer("examples/pen/drawing-lines", 640, 480, 0, &window, &renderer)) {
38 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
39 return SDL_APP_FAILURE;
40 }
41
42 /* we make a render target so we can draw lines to it and not have to record and redraw every pen stroke each frame.
43 Instead rendering a frame for us is a single texture draw. */
44
45 /* make sure the render target matches output size (for hidpi displays, etc) so drawing matches the pen's position on a tablet display. */
46 SDL_GetRenderOutputSize(renderer, &w, &h);
47 render_target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
48 if (!render_target) {
49 SDL_Log("Couldn't create render target: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 /* just blank the render target to gray to start. */
54 SDL_SetRenderTarget(renderer, render_target);
55 SDL_SetRenderDrawColor(renderer, 100, 100, 100, SDL_ALPHA_OPAQUE);
56 SDL_RenderClear(renderer);
57 SDL_SetRenderTarget(renderer, NULL);
58 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
59
60 return SDL_APP_CONTINUE; /* carry on with the program! */
61}
62
63/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
64SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
65{
66 if (event->type == SDL_EVENT_QUIT) {
67 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
68 }
69
70 /* There are several events that track the specific stages of pen activity,
71 but we're only going to look for motion and pressure, for simplicity. */
72 if (event->type == SDL_EVENT_PEN_MOTION) {
73 /* you can check for when the pen is touching, but if pressure > 0.0f, it's definitely touching! */
74 if (pressure > 0.0f) {
75 if (previous_touch_x >= 0.0f) { /* only draw if we're moving while touching */
76 /* draw with the alpha set to the pressure, so you effectively get a fainter line for lighter presses. */
77 SDL_SetRenderTarget(renderer, render_target);
78 SDL_SetRenderDrawColorFloat(renderer, 0, 0, 0, pressure);
79 SDL_RenderLine(renderer, previous_touch_x, previous_touch_y, event->pmotion.x, event->pmotion.y);
80 }
81 previous_touch_x = event->pmotion.x;
82 previous_touch_y = event->pmotion.y;
83 } else {
84 previous_touch_x = previous_touch_y = -1.0f;
85 }
86 } else if (event->type == SDL_EVENT_PEN_AXIS) {
87 if (event->paxis.axis == SDL_PEN_AXIS_PRESSURE) {
88 pressure = event->paxis.value; /* remember new pressure for later draws. */
89 } else if(event->paxis.axis == SDL_PEN_AXIS_XTILT) {
90 tilt_x = event->paxis.value;
91 } else if(event->paxis.axis == SDL_PEN_AXIS_YTILT) {
92 tilt_y = event->paxis.value;
93 }
94 }
95
96 return SDL_APP_CONTINUE; /* carry on with the program! */
97}
98
99/* This function runs once per frame, and is the heart of the program. */
100SDL_AppResult SDL_AppIterate(void *appstate)
101{
102 char debug_text[1024];
103
104 /* make sure we're drawing to the window and not the render target */
105 SDL_SetRenderTarget(renderer, NULL);
106 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
107 SDL_RenderClear(renderer); /* just in case. */
108 SDL_RenderTexture(renderer, render_target, NULL, NULL);
109 SDL_snprintf(debug_text, sizeof(debug_text), "Tilt: %f %f", tilt_x, tilt_y);
110 SDL_RenderDebugText(renderer, 0, 8, debug_text);
111 SDL_RenderPresent(renderer);
112 return SDL_APP_CONTINUE; /* carry on with the program! */
113}
114
115/* This function runs once at shutdown. */
116void SDL_AppQuit(void *appstate, SDL_AppResult result)
117{
118 SDL_DestroyTexture(render_target);
119 /* SDL will clean up the window/renderer for us. */
120}
121
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/pen/01-drawing-lines/thumbnail.png
Binary files 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 @@
1This example code creates an SDL window and renderer, and then clears the
2window to a different color every frame, so you'll effectively get a window
3that'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 @@
1/*
2 * This example code creates an SDL window and renderer, and then clears the
3 * window to a different color every frame, so you'll effectively get a window
4 * that's smoothly fading between colors.
5 *
6 * This code is public domain. Feel free to use it for any purpose!
7 */
8
9#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
10#include <SDL3/SDL.h>
11#include <SDL3/SDL_main.h>
12
13/* We will use this renderer to draw into this window every frame. */
14static SDL_Window *window = NULL;
15static SDL_Renderer *renderer = NULL;
16
17/* This function runs once at startup. */
18SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
19{
20 SDL_SetAppMetadata("Example Renderer Clear", "1.0", "com.example.renderer-clear");
21
22 if (!SDL_Init(SDL_INIT_VIDEO)) {
23 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
24 return SDL_APP_FAILURE;
25 }
26
27 if (!SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, 0, &window, &renderer)) {
28 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
29 return SDL_APP_FAILURE;
30 }
31
32 return SDL_APP_CONTINUE; /* carry on with the program! */
33}
34
35/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
36SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
37{
38 if (event->type == SDL_EVENT_QUIT) {
39 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
40 }
41 return SDL_APP_CONTINUE; /* carry on with the program! */
42}
43
44/* This function runs once per frame, and is the heart of the program. */
45SDL_AppResult SDL_AppIterate(void *appstate)
46{
47 const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */
48 /* choose the color for the frame we will draw. The sine wave trick makes it fade between colors smoothly. */
49 const float red = (float) (0.5 + 0.5 * SDL_sin(now));
50 const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3));
51 const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3));
52 SDL_SetRenderDrawColorFloat(renderer, red, green, blue, SDL_ALPHA_OPAQUE_FLOAT); /* new color, full alpha. */
53
54 /* clear the window to the draw color. */
55 SDL_RenderClear(renderer);
56
57 /* put the newly-cleared rendering on the screen. */
58 SDL_RenderPresent(renderer);
59
60 return SDL_APP_CONTINUE; /* carry on with the program! */
61}
62
63/* This function runs once at shutdown. */
64void SDL_AppQuit(void *appstate, SDL_AppResult result)
65{
66 /* SDL will clean up the window/renderer for us. */
67}
68
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/01-clear/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, and then draws some lines,
2rectangles and points to it every frame.
3
4This is just a quick overview of simple drawing primitives; futher examples
5will explore them in more detail.
6
7
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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some lines,
3 * rectangles and points to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_FPoint points[500];
16
17/* This function runs once at startup. */
18SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
19{
20 int i;
21
22 SDL_SetAppMetadata("Example Renderer Primitives", "1.0", "com.example.renderer-primitives");
23
24 if (!SDL_Init(SDL_INIT_VIDEO)) {
25 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
26 return SDL_APP_FAILURE;
27 }
28
29 if (!SDL_CreateWindowAndRenderer("examples/renderer/primitives", 640, 480, 0, &window, &renderer)) {
30 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
31 return SDL_APP_FAILURE;
32 }
33
34 /* set up some random points */
35 for (i = 0; i < SDL_arraysize(points); i++) {
36 points[i].x = (SDL_randf() * 440.0f) + 100.0f;
37 points[i].y = (SDL_randf() * 280.0f) + 100.0f;
38 }
39
40 return SDL_APP_CONTINUE; /* carry on with the program! */
41}
42
43/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
44SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
45{
46 if (event->type == SDL_EVENT_QUIT) {
47 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
48 }
49 return SDL_APP_CONTINUE; /* carry on with the program! */
50}
51
52/* This function runs once per frame, and is the heart of the program. */
53SDL_AppResult SDL_AppIterate(void *appstate)
54{
55 SDL_FRect rect;
56
57 /* as you can see from this, rendering draws over whatever was drawn before it. */
58 SDL_SetRenderDrawColor(renderer, 33, 33, 33, SDL_ALPHA_OPAQUE); /* dark gray, full alpha */
59 SDL_RenderClear(renderer); /* start with a blank canvas. */
60
61 /* draw a filled rectangle in the middle of the canvas. */
62 SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */
63 rect.x = rect.y = 100;
64 rect.w = 440;
65 rect.h = 280;
66 SDL_RenderFillRect(renderer, &rect);
67
68 /* draw some points across the canvas. */
69 SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */
70 SDL_RenderPoints(renderer, points, SDL_arraysize(points));
71
72 /* draw a unfilled rectangle in-set a little bit. */
73 SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */
74 rect.x += 30;
75 rect.y += 30;
76 rect.w -= 60;
77 rect.h -= 60;
78 SDL_RenderRect(renderer, &rect);
79
80 /* draw two lines in an X across the whole canvas. */
81 SDL_SetRenderDrawColor(renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /* yellow, full alpha */
82 SDL_RenderLine(renderer, 0, 0, 640, 480);
83 SDL_RenderLine(renderer, 0, 480, 640, 0);
84
85 SDL_RenderPresent(renderer); /* put it all on the screen! */
86
87 return SDL_APP_CONTINUE; /* carry on with the program! */
88}
89
90/* This function runs once at shutdown. */
91void SDL_AppQuit(void *appstate, SDL_AppResult result)
92{
93 /* SDL will clean up the window/renderer for us. */
94}
95
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/02-primitives/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, and then draws a something
2roughly like a Christmas tree with nothing but lines, every frame.
3
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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some lines
3 * to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15
16/* This function runs once at startup. */
17SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
18{
19 SDL_SetAppMetadata("Example Renderer Lines", "1.0", "com.example.renderer-lines");
20
21 if (!SDL_Init(SDL_INIT_VIDEO)) {
22 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
23 return SDL_APP_FAILURE;
24 }
25
26 if (!SDL_CreateWindowAndRenderer("examples/renderer/lines", 640, 480, 0, &window, &renderer)) {
27 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
28 return SDL_APP_FAILURE;
29 }
30
31 return SDL_APP_CONTINUE; /* carry on with the program! */
32}
33
34/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
35SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
36{
37 if (event->type == SDL_EVENT_QUIT) {
38 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
39 }
40 return SDL_APP_CONTINUE; /* carry on with the program! */
41}
42
43/* This function runs once per frame, and is the heart of the program. */
44SDL_AppResult SDL_AppIterate(void *appstate)
45{
46 int i;
47
48 /* Lines (line segments, really) are drawn in terms of points: a set of
49 X and Y coordinates, one set for each end of the line.
50 (0, 0) is the top left of the window, and larger numbers go down
51 and to the right. This isn't how geometry works, but this is pretty
52 standard in 2D graphics. */
53 static const SDL_FPoint line_points[] = {
54 { 100, 354 }, { 220, 230 }, { 140, 230 }, { 320, 100 }, { 500, 230 },
55 { 420, 230 }, { 540, 354 }, { 400, 354 }, { 100, 354 }
56 };
57
58 /* as you can see from this, rendering draws over whatever was drawn before it. */
59 SDL_SetRenderDrawColor(renderer, 100, 100, 100, SDL_ALPHA_OPAQUE); /* grey, full alpha */
60 SDL_RenderClear(renderer); /* start with a blank canvas. */
61
62 /* You can draw lines, one at a time, like these brown ones... */
63 SDL_SetRenderDrawColor(renderer, 127, 49, 32, SDL_ALPHA_OPAQUE);
64 SDL_RenderLine(renderer, 240, 450, 400, 450);
65 SDL_RenderLine(renderer, 240, 356, 400, 356);
66 SDL_RenderLine(renderer, 240, 356, 240, 450);
67 SDL_RenderLine(renderer, 400, 356, 400, 450);
68
69 /* You can also draw a series of connected lines in a single batch... */
70 SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
71 SDL_RenderLines(renderer, line_points, SDL_arraysize(line_points));
72
73 /* here's a bunch of lines drawn out from a center point in a circle. */
74 /* we randomize the color of each line, so it functions as animation. */
75 for (i = 0; i < 360; i++) {
76 const float size = 30.0f;
77 const float x = 320.0f;
78 const float y = 95.0f - (size / 2.0f);
79 SDL_SetRenderDrawColor(renderer, SDL_rand(256), SDL_rand(256), SDL_rand(256), SDL_ALPHA_OPAQUE);
80 SDL_RenderLine(renderer, x, y, x + SDL_sinf((float) i) * size, y + SDL_cosf((float) i) * size);
81 }
82
83 SDL_RenderPresent(renderer); /* put it all on the screen! */
84
85 return SDL_APP_CONTINUE; /* carry on with the program! */
86}
87
88/* This function runs once at shutdown. */
89void SDL_AppQuit(void *appstate, SDL_AppResult result)
90{
91 /* SDL will clean up the window/renderer for us. */
92}
93
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/03-lines/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, and then draws a bunch of
2single points, moving across the screen.
3
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/04-points/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some points
3 * to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static Uint64 last_time = 0;
16
17#define WINDOW_WIDTH 640
18#define WINDOW_HEIGHT 480
19
20#define NUM_POINTS 500
21#define MIN_PIXELS_PER_SECOND 30 /* move at least this many pixels per second. */
22#define MAX_PIXELS_PER_SECOND 60 /* move this many pixels per second at most. */
23
24/* (track everything as parallel arrays instead of a array of structs,
25 so we can pass the coordinates to the renderer in a single function call.) */
26
27/* Points are plotted as a set of X and Y coordinates.
28 (0, 0) is the top left of the window, and larger numbers go down
29 and to the right. This isn't how geometry works, but this is pretty
30 standard in 2D graphics. */
31static SDL_FPoint points[NUM_POINTS];
32static float point_speeds[NUM_POINTS];
33
34/* This function runs once at startup. */
35SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
36{
37 int i;
38
39 SDL_SetAppMetadata("Example Renderer Points", "1.0", "com.example.renderer-points");
40
41 if (!SDL_Init(SDL_INIT_VIDEO)) {
42 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
43 return SDL_APP_FAILURE;
44 }
45
46 if (!SDL_CreateWindowAndRenderer("examples/renderer/points", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
47 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
48 return SDL_APP_FAILURE;
49 }
50
51 /* set up the data for a bunch of points. */
52 for (i = 0; i < SDL_arraysize(points); i++) {
53 points[i].x = SDL_randf() * ((float) WINDOW_WIDTH);
54 points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT);
55 point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND));
56 }
57
58 last_time = SDL_GetTicks();
59
60 return SDL_APP_CONTINUE; /* carry on with the program! */
61}
62
63/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
64SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
65{
66 if (event->type == SDL_EVENT_QUIT) {
67 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
68 }
69 return SDL_APP_CONTINUE; /* carry on with the program! */
70}
71
72/* This function runs once per frame, and is the heart of the program. */
73SDL_AppResult SDL_AppIterate(void *appstate)
74{
75 const Uint64 now = SDL_GetTicks();
76 const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */
77 int i;
78
79 /* let's move all our points a little for a new frame. */
80 for (i = 0; i < SDL_arraysize(points); i++) {
81 const float distance = elapsed * point_speeds[i];
82 points[i].x += distance;
83 points[i].y += distance;
84 if ((points[i].x >= WINDOW_WIDTH) || (points[i].y >= WINDOW_HEIGHT)) {
85 /* off the screen; restart it elsewhere! */
86 if (SDL_rand(2)) {
87 points[i].x = SDL_randf() * ((float) WINDOW_WIDTH);
88 points[i].y = 0.0f;
89 } else {
90 points[i].x = 0.0f;
91 points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT);
92 }
93 point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND));
94 }
95 }
96
97 last_time = now;
98
99 /* as you can see from this, rendering draws over whatever was drawn before it. */
100 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
101 SDL_RenderClear(renderer); /* start with a blank canvas. */
102 SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
103 SDL_RenderPoints(renderer, points, SDL_arraysize(points)); /* draw all the points! */
104
105 /* You can also draw single points with SDL_RenderPoint(), but it's
106 cheaper (sometimes significantly so) to do them all at once. */
107
108 SDL_RenderPresent(renderer); /* put it all on the screen! */
109
110 return SDL_APP_CONTINUE; /* carry on with the program! */
111}
112
113/* This function runs once at shutdown. */
114void SDL_AppQuit(void *appstate, SDL_AppResult result)
115{
116 /* SDL will clean up the window/renderer for us. */
117}
118
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/04-points/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, and then draws a few
2rectangles that change size each frame.
3
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * rectangles to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15
16#define WINDOW_WIDTH 640
17#define WINDOW_HEIGHT 480
18
19/* This function runs once at startup. */
20SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
21{
22 SDL_SetAppMetadata("Example Renderer Rectangles", "1.0", "com.example.renderer-rectangles");
23
24 if (!SDL_Init(SDL_INIT_VIDEO)) {
25 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
26 return SDL_APP_FAILURE;
27 }
28
29 if (!SDL_CreateWindowAndRenderer("examples/renderer/rectangles", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
30 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
31 return SDL_APP_FAILURE;
32 }
33
34 return SDL_APP_CONTINUE; /* carry on with the program! */
35}
36
37/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
38SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
39{
40 if (event->type == SDL_EVENT_QUIT) {
41 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
42 }
43 return SDL_APP_CONTINUE; /* carry on with the program! */
44}
45
46/* This function runs once per frame, and is the heart of the program. */
47SDL_AppResult SDL_AppIterate(void *appstate)
48{
49 SDL_FRect rects[16];
50 const Uint64 now = SDL_GetTicks();
51 int i;
52
53 /* we'll have the rectangles grow and shrink over a few seconds. */
54 const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
55 const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
56
57 /* as you can see from this, rendering draws over whatever was drawn before it. */
58 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
59 SDL_RenderClear(renderer); /* start with a blank canvas. */
60
61 /* Rectangles are comprised of set of X and Y coordinates, plus width and
62 height. (0, 0) is the top left of the window, and larger numbers go
63 down and to the right. This isn't how geometry works, but this is
64 pretty standard in 2D graphics. */
65
66 /* Let's draw a single rectangle (square, really). */
67 rects[0].x = rects[0].y = 100;
68 rects[0].w = rects[0].h = 100 + (100 * scale);
69 SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */
70 SDL_RenderRect(renderer, &rects[0]);
71
72 /* Now let's draw several rectangles with one function call. */
73 for (i = 0; i < 3; i++) {
74 const float size = (i+1) * 50.0f;
75 rects[i].w = rects[i].h = size + (size * scale);
76 rects[i].x = (WINDOW_WIDTH - rects[i].w) / 2; /* center it. */
77 rects[i].y = (WINDOW_HEIGHT - rects[i].h) / 2; /* center it. */
78 }
79 SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */
80 SDL_RenderRects(renderer, rects, 3); /* draw three rectangles at once */
81
82 /* those were rectangle _outlines_, really. You can also draw _filled_ rectangles! */
83 rects[0].x = 400;
84 rects[0].y = 50;
85 rects[0].w = 100 + (100 * scale);
86 rects[0].h = 50 + (50 * scale);
87 SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */
88 SDL_RenderFillRect(renderer, &rects[0]);
89
90 /* ...and also fill a bunch of rectangles at once... */
91 for (i = 0; i < SDL_arraysize(rects); i++) {
92 const float w = (float) (WINDOW_WIDTH / SDL_arraysize(rects));
93 const float h = i * 8.0f;
94 rects[i].x = i * w;
95 rects[i].y = WINDOW_HEIGHT - h;
96 rects[i].w = w;
97 rects[i].h = h;
98 }
99 SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
100 SDL_RenderFillRects(renderer, rects, SDL_arraysize(rects));
101
102 SDL_RenderPresent(renderer); /* put it all on the screen! */
103
104 return SDL_APP_CONTINUE; /* carry on with the program! */
105}
106
107/* This function runs once at shutdown. */
108void SDL_AppQuit(void *appstate, SDL_AppResult result)
109{
110 /* SDL will clean up the window/renderer for us. */
111}
112
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/05-rectangles/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, loads a texture from a
2.bmp file, and then draws it a few times each frame.
3
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * textures to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16static int texture_width = 0;
17static int texture_height = 0;
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_Surface *surface = NULL;
26 char *bmp_path = NULL;
27
28 SDL_SetAppMetadata("Example Renderer Textures", "1.0", "com.example.renderer-textures");
29
30 if (!SDL_Init(SDL_INIT_VIDEO)) {
31 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
32 return SDL_APP_FAILURE;
33 }
34
35 if (!SDL_CreateWindowAndRenderer("examples/renderer/textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
36 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
37 return SDL_APP_FAILURE;
38 }
39
40 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
41 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
42 times) with data from a bitmap file. */
43
44 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
45 Load a .bmp into a surface, move it to a texture from there. */
46 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
47 surface = SDL_LoadBMP(bmp_path);
48 if (!surface) {
49 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 SDL_free(bmp_path); /* done with this, the file is loaded. */
54
55 texture_width = surface->w;
56 texture_height = surface->h;
57
58 texture = SDL_CreateTextureFromSurface(renderer, surface);
59 if (!texture) {
60 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 SDL_FRect dst_rect;
82 const Uint64 now = SDL_GetTicks();
83
84 /* we'll have some textures move around over a few seconds. */
85 const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
86 const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
87
88 /* as you can see from this, rendering draws over whatever was drawn before it. */
89 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
90 SDL_RenderClear(renderer); /* start with a blank canvas. */
91
92 /* Just draw the static texture a few times. You can think of it like a
93 stamp, there isn't a limit to the number of times you can draw with it. */
94
95 /* top left */
96 dst_rect.x = (100.0f * scale);
97 dst_rect.y = 0.0f;
98 dst_rect.w = (float) texture_width;
99 dst_rect.h = (float) texture_height;
100 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
101
102 /* center this one. */
103 dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
104 dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
105 dst_rect.w = (float) texture_width;
106 dst_rect.h = (float) texture_height;
107 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
108
109 /* bottom right. */
110 dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) - (100.0f * scale);
111 dst_rect.y = (float) (WINDOW_HEIGHT - texture_height);
112 dst_rect.w = (float) texture_width;
113 dst_rect.h = (float) texture_height;
114 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
115
116 SDL_RenderPresent(renderer); /* put it all on the screen! */
117
118 return SDL_APP_CONTINUE; /* carry on with the program! */
119}
120
121/* This function runs once at shutdown. */
122void SDL_AppQuit(void *appstate, SDL_AppResult result)
123{
124 SDL_DestroyTexture(texture);
125 /* SDL will clean up the window/renderer for us. */
126}
127
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/06-textures/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, then a streaming texture that
2it will update every frame before drawing it to the screen.
3
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws a streaming
3 * texture to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16
17#define TEXTURE_SIZE 150
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_SetAppMetadata("Example Renderer Streaming Textures", "1.0", "com.example.renderer-streaming-textures");
26
27 if (!SDL_Init(SDL_INIT_VIDEO)) {
28 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
29 return SDL_APP_FAILURE;
30 }
31
32 if (!SDL_CreateWindowAndRenderer("examples/renderer/streaming-textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
33 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
34 return SDL_APP_FAILURE;
35 }
36
37 texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE);
38 if (!texture) {
39 SDL_Log("Couldn't create streaming texture: %s", SDL_GetError());
40 return SDL_APP_FAILURE;
41 }
42
43 return SDL_APP_CONTINUE; /* carry on with the program! */
44}
45
46/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
47SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
48{
49 if (event->type == SDL_EVENT_QUIT) {
50 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
51 }
52 return SDL_APP_CONTINUE; /* carry on with the program! */
53}
54
55/* This function runs once per frame, and is the heart of the program. */
56SDL_AppResult SDL_AppIterate(void *appstate)
57{
58 SDL_FRect dst_rect;
59 const Uint64 now = SDL_GetTicks();
60 SDL_Surface *surface = NULL;
61
62 /* we'll have some color move around over a few seconds. */
63 const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
64 const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
65
66 /* To update a streaming texture, you need to lock it first. This gets you access to the pixels.
67 Note that this is considered a _write-only_ operation: the buffer you get from locking
68 might not acutally have the existing contents of the texture, and you have to write to every
69 locked pixel! */
70
71 /* You can use SDL_LockTexture() to get an array of raw pixels, but we're going to use
72 SDL_LockTextureToSurface() here, because it wraps that array in a temporary SDL_Surface,
73 letting us use the surface drawing functions instead of lighting up individual pixels. */
74 if (SDL_LockTextureToSurface(texture, NULL, &surface)) {
75 SDL_Rect r;
76 SDL_FillSurfaceRect(surface, NULL, SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, 0, 0, 0)); /* make the whole surface black */
77 r.w = TEXTURE_SIZE;
78 r.h = TEXTURE_SIZE / 10;
79 r.x = 0;
80 r.y = (int) (((float) (TEXTURE_SIZE - r.h)) * ((scale + 1.0f) / 2.0f));
81 SDL_FillSurfaceRect(surface, &r, SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, 0, 255, 0)); /* make a strip of the surface green */
82 SDL_UnlockTexture(texture); /* upload the changes (and frees the temporary surface)! */
83 }
84
85 /* as you can see from this, rendering draws over whatever was drawn before it. */
86 SDL_SetRenderDrawColor(renderer, 66, 66, 66, SDL_ALPHA_OPAQUE); /* grey, full alpha */
87 SDL_RenderClear(renderer); /* start with a blank canvas. */
88
89 /* Just draw the static texture a few times. You can think of it like a
90 stamp, there isn't a limit to the number of times you can draw with it. */
91
92 /* Center this one. It'll draw the latest version of the texture we drew while it was locked. */
93 dst_rect.x = ((float) (WINDOW_WIDTH - TEXTURE_SIZE)) / 2.0f;
94 dst_rect.y = ((float) (WINDOW_HEIGHT - TEXTURE_SIZE)) / 2.0f;
95 dst_rect.w = dst_rect.h = (float) TEXTURE_SIZE;
96 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
97
98 SDL_RenderPresent(renderer); /* put it all on the screen! */
99
100 return SDL_APP_CONTINUE; /* carry on with the program! */
101}
102
103/* This function runs once at shutdown. */
104void SDL_AppQuit(void *appstate, SDL_AppResult result)
105{
106 SDL_DestroyTexture(texture);
107 /* SDL will clean up the window/renderer for us. */
108}
109
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/07-streaming-textures/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, loads a texture from a .bmp
2file, and then draws it, rotating around the center of the screen.
3
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * rotated textures to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16static int texture_width = 0;
17static int texture_height = 0;
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_Surface *surface = NULL;
26 char *bmp_path = NULL;
27
28 SDL_SetAppMetadata("Example Renderer Rotating Textures", "1.0", "com.example.renderer-rotating-textures");
29
30 if (!SDL_Init(SDL_INIT_VIDEO)) {
31 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
32 return SDL_APP_FAILURE;
33 }
34
35 if (!SDL_CreateWindowAndRenderer("examples/renderer/rotating-textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
36 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
37 return SDL_APP_FAILURE;
38 }
39
40 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
41 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
42 times) with data from a bitmap file. */
43
44 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
45 Load a .bmp into a surface, move it to a texture from there. */
46 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
47 surface = SDL_LoadBMP(bmp_path);
48 if (!surface) {
49 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 SDL_free(bmp_path); /* done with this, the file is loaded. */
54
55 texture_width = surface->w;
56 texture_height = surface->h;
57
58 texture = SDL_CreateTextureFromSurface(renderer, surface);
59 if (!texture) {
60 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 SDL_FPoint center;
82 SDL_FRect dst_rect;
83 const Uint64 now = SDL_GetTicks();
84
85 /* we'll have a texture rotate around over 2 seconds (2000 milliseconds). 360 degrees in a circle! */
86 const float rotation = (((float) ((int) (now % 2000))) / 2000.0f) * 360.0f;
87
88 /* as you can see from this, rendering draws over whatever was drawn before it. */
89 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
90 SDL_RenderClear(renderer); /* start with a blank canvas. */
91
92 /* Center this one, and draw it with some rotation so it spins! */
93 dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
94 dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
95 dst_rect.w = (float) texture_width;
96 dst_rect.h = (float) texture_height;
97 /* rotate it around the center of the texture; you can rotate it from a different point, too! */
98 center.x = texture_width / 2.0f;
99 center.y = texture_height / 2.0f;
100 SDL_RenderTextureRotated(renderer, texture, NULL, &dst_rect, rotation, &center, SDL_FLIP_NONE);
101
102 SDL_RenderPresent(renderer); /* put it all on the screen! */
103
104 return SDL_APP_CONTINUE; /* carry on with the program! */
105}
106
107/* This function runs once at shutdown. */
108void SDL_AppQuit(void *appstate, SDL_AppResult result)
109{
110 SDL_DestroyTexture(texture);
111 /* SDL will clean up the window/renderer for us. */
112}
113
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/08-rotating-textures/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, loads a texture from a .bmp
2file, and then draws it, scaling it up and down.
3
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * textures to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16static int texture_width = 0;
17static int texture_height = 0;
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_Surface *surface = NULL;
26 char *bmp_path = NULL;
27
28 SDL_SetAppMetadata("Example Renderer Scaling Textures", "1.0", "com.example.renderer-scaling-textures");
29
30 if (!SDL_Init(SDL_INIT_VIDEO)) {
31 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
32 return SDL_APP_FAILURE;
33 }
34
35 if (!SDL_CreateWindowAndRenderer("examples/renderer/scaling-textures", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
36 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
37 return SDL_APP_FAILURE;
38 }
39
40 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
41 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
42 times) with data from a bitmap file. */
43
44 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
45 Load a .bmp into a surface, move it to a texture from there. */
46 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
47 surface = SDL_LoadBMP(bmp_path);
48 if (!surface) {
49 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 SDL_free(bmp_path); /* done with this, the file is loaded. */
54
55 texture_width = surface->w;
56 texture_height = surface->h;
57
58 texture = SDL_CreateTextureFromSurface(renderer, surface);
59 if (!texture) {
60 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 SDL_FRect dst_rect;
82 const Uint64 now = SDL_GetTicks();
83
84 /* we'll have the texture grow and shrink over a few seconds. */
85 const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
86 const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
87
88 /* as you can see from this, rendering draws over whatever was drawn before it. */
89 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
90 SDL_RenderClear(renderer); /* start with a blank canvas. */
91
92 /* center this one and make it grow and shrink. */
93 dst_rect.w = (float) texture_width + (texture_width * scale);
94 dst_rect.h = (float) texture_height + (texture_height * scale);
95 dst_rect.x = (WINDOW_WIDTH - dst_rect.w) / 2.0f;
96 dst_rect.y = (WINDOW_HEIGHT - dst_rect.h) / 2.0f;
97 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
98
99 SDL_RenderPresent(renderer); /* put it all on the screen! */
100
101 return SDL_APP_CONTINUE; /* carry on with the program! */
102}
103
104/* This function runs once at shutdown. */
105void SDL_AppQuit(void *appstate, SDL_AppResult result)
106{
107 SDL_DestroyTexture(texture);
108 /* SDL will clean up the window/renderer for us. */
109}
110
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/09-scaling-textures/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, loads a texture from a .bmp
2file, and then draws geometry (arbitrary polygons) using it.
3
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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * geometry (arbitrary polygons) to it every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16static int texture_width = 0;
17static int texture_height = 0;
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_Surface *surface = NULL;
26 char *bmp_path = NULL;
27
28 SDL_SetAppMetadata("Example Renderer Geometry", "1.0", "com.example.renderer-geometry");
29
30 if (!SDL_Init(SDL_INIT_VIDEO)) {
31 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
32 return SDL_APP_FAILURE;
33 }
34
35 if (!SDL_CreateWindowAndRenderer("examples/renderer/geometry", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
36 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
37 return SDL_APP_FAILURE;
38 }
39
40 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
41 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
42 times) with data from a bitmap file. */
43
44 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
45 Load a .bmp into a surface, move it to a texture from there. */
46 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
47 surface = SDL_LoadBMP(bmp_path);
48 if (!surface) {
49 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 SDL_free(bmp_path); /* done with this, the file is loaded. */
54
55 texture_width = surface->w;
56 texture_height = surface->h;
57
58 texture = SDL_CreateTextureFromSurface(renderer, surface);
59 if (!texture) {
60 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 const Uint64 now = SDL_GetTicks();
82
83 /* we'll have the triangle grow and shrink over a few seconds. */
84 const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
85 const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
86 const float size = 200.0f + (200.0f * scale);
87
88 SDL_Vertex vertices[4];
89 int i;
90
91 /* as you can see from this, rendering draws over whatever was drawn before it. */
92 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
93 SDL_RenderClear(renderer); /* start with a blank canvas. */
94
95 /* Draw a single triangle with a different color at each vertex. Center this one and make it grow and shrink. */
96 /* You always draw triangles with this, but you can string triangles together to form polygons. */
97 SDL_zeroa(vertices);
98 vertices[0].position.x = ((float) WINDOW_WIDTH) / 2.0f;
99 vertices[0].position.y = (((float) WINDOW_HEIGHT) - size) / 2.0f;
100 vertices[0].color.r = 1.0f;
101 vertices[0].color.a = 1.0f;
102 vertices[1].position.x = (((float) WINDOW_WIDTH) + size) / 2.0f;
103 vertices[1].position.y = (((float) WINDOW_HEIGHT) + size) / 2.0f;
104 vertices[1].color.g = 1.0f;
105 vertices[1].color.a = 1.0f;
106 vertices[2].position.x = (((float) WINDOW_WIDTH) - size) / 2.0f;
107 vertices[2].position.y = (((float) WINDOW_HEIGHT) + size) / 2.0f;
108 vertices[2].color.b = 1.0f;
109 vertices[2].color.a = 1.0f;
110
111 SDL_RenderGeometry(renderer, NULL, vertices, 3, NULL, 0);
112
113 /* you can also map a texture to the geometry! Texture coordinates go from 0.0f to 1.0f. That will be the location
114 in the texture bound to this vertex. */
115 SDL_zeroa(vertices);
116 vertices[0].position.x = 10.0f;
117 vertices[0].position.y = 10.0f;
118 vertices[0].color.r = vertices[0].color.g = vertices[0].color.b = vertices[0].color.a = 1.0f;
119 vertices[0].tex_coord.x = 0.0f;
120 vertices[0].tex_coord.y = 0.0f;
121 vertices[1].position.x = 150.0f;
122 vertices[1].position.y = 10.0f;
123 vertices[1].color.r = vertices[1].color.g = vertices[1].color.b = vertices[1].color.a = 1.0f;
124 vertices[1].tex_coord.x = 1.0f;
125 vertices[1].tex_coord.y = 0.0f;
126 vertices[2].position.x = 10.0f;
127 vertices[2].position.y = 150.0f;
128 vertices[2].color.r = vertices[2].color.g = vertices[2].color.b = vertices[2].color.a = 1.0f;
129 vertices[2].tex_coord.x = 0.0f;
130 vertices[2].tex_coord.y = 1.0f;
131 SDL_RenderGeometry(renderer, texture, vertices, 3, NULL, 0);
132
133 /* Did that only draw half of the texture? You can do multiple triangles sharing some vertices,
134 using indices, to get the whole thing on the screen: */
135
136 /* Let's just move this over so it doesn't overlap... */
137 for (i = 0; i < 3; i++) {
138 vertices[i].position.x += 450;
139 }
140
141 /* we need one more vertex, since the two triangles can share two of them. */
142 vertices[3].position.x = 600.0f;
143 vertices[3].position.y = 150.0f;
144 vertices[3].color.r = vertices[3].color.g = vertices[3].color.b = vertices[3].color.a = 1.0f;
145 vertices[3].tex_coord.x = 1.0f;
146 vertices[3].tex_coord.y = 1.0f;
147
148 /* And an index to tell it to reuse some of the vertices between triangles... */
149 {
150 /* 4 vertices, but 6 actual places they used. Indices need less bandwidth to transfer and can reorder vertices easily! */
151 const int indices[] = { 0, 1, 2, 1, 2, 3 };
152 SDL_RenderGeometry(renderer, texture, vertices, 4, indices, SDL_arraysize(indices));
153 }
154
155 SDL_RenderPresent(renderer); /* put it all on the screen! */
156
157 return SDL_APP_CONTINUE; /* carry on with the program! */
158}
159
160/* This function runs once at shutdown. */
161void SDL_AppQuit(void *appstate, SDL_AppResult result)
162{
163 SDL_DestroyTexture(texture);
164 /* SDL will clean up the window/renderer for us. */
165}
166
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/10-geometry/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, loads a texture from a
2.bmp file, and then draws it a few times each frame, adjusting the colors.
3
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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * textures to it every frame, adjusting their color.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16static int texture_width = 0;
17static int texture_height = 0;
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_Surface *surface = NULL;
26 char *bmp_path = NULL;
27
28 SDL_SetAppMetadata("Example Renderer Color Mods", "1.0", "com.example.renderer-color-mods");
29
30 if (!SDL_Init(SDL_INIT_VIDEO)) {
31 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
32 return SDL_APP_FAILURE;
33 }
34
35 if (!SDL_CreateWindowAndRenderer("examples/renderer/color-mods", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
36 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
37 return SDL_APP_FAILURE;
38 }
39
40 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
41 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
42 times) with data from a bitmap file. */
43
44 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
45 Load a .bmp into a surface, move it to a texture from there. */
46 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
47 surface = SDL_LoadBMP(bmp_path);
48 if (!surface) {
49 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 SDL_free(bmp_path); /* done with this, the file is loaded. */
54
55 texture_width = surface->w;
56 texture_height = surface->h;
57
58 texture = SDL_CreateTextureFromSurface(renderer, surface);
59 if (!texture) {
60 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 SDL_FRect dst_rect;
82 const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */
83 /* choose the modulation values for the center texture. The sine wave trick makes it fade between colors smoothly. */
84 const float red = (float) (0.5 + 0.5 * SDL_sin(now));
85 const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3));
86 const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3));
87
88 /* as you can see from this, rendering draws over whatever was drawn before it. */
89 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
90 SDL_RenderClear(renderer); /* start with a blank canvas. */
91
92 /* Just draw the static texture a few times. You can think of it like a
93 stamp, there isn't a limit to the number of times you can draw with it. */
94
95 /* Color modulation multiplies each pixel's red, green, and blue intensities by the mod values,
96 so multiplying by 1.0f will leave a color intensity alone, 0.0f will shut off that color
97 completely, etc. */
98
99 /* top left; let's make this one blue! */
100 dst_rect.x = 0.0f;
101 dst_rect.y = 0.0f;
102 dst_rect.w = (float) texture_width;
103 dst_rect.h = (float) texture_height;
104 SDL_SetTextureColorModFloat(texture, 0.0f, 0.0f, 1.0f); /* kill all red and green. */
105 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
106
107 /* center this one, and have it cycle through red/green/blue modulations. */
108 dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
109 dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
110 dst_rect.w = (float) texture_width;
111 dst_rect.h = (float) texture_height;
112 SDL_SetTextureColorModFloat(texture, red, green, blue);
113 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
114
115 /* bottom right; let's make this one red! */
116 dst_rect.x = (float) (WINDOW_WIDTH - texture_width);
117 dst_rect.y = (float) (WINDOW_HEIGHT - texture_height);
118 dst_rect.w = (float) texture_width;
119 dst_rect.h = (float) texture_height;
120 SDL_SetTextureColorModFloat(texture, 1.0f, 0.0f, 0.0f); /* kill all green and blue. */
121 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
122
123 SDL_RenderPresent(renderer); /* put it all on the screen! */
124
125 return SDL_APP_CONTINUE; /* carry on with the program! */
126}
127
128/* This function runs once at shutdown. */
129void SDL_AppQuit(void *appstate, SDL_AppResult result)
130{
131 SDL_DestroyTexture(texture);
132 /* SDL will clean up the window/renderer for us. */
133}
134
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/11-color-mods/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, loads a texture
2from a .bmp file, and then draws it a few times each frame, adjusting
3the viewport before each draw.
4
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/14-viewport/thumbnail.png
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some
3 * textures to it every frame, adjusting the viewport.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15static SDL_Texture *texture = NULL;
16static int texture_width = 0;
17static int texture_height = 0;
18
19#define WINDOW_WIDTH 640
20#define WINDOW_HEIGHT 480
21
22/* This function runs once at startup. */
23SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
24{
25 SDL_Surface *surface = NULL;
26 char *bmp_path = NULL;
27
28 SDL_SetAppMetadata("Example Renderer Viewport", "1.0", "com.example.renderer-viewport");
29
30 if (!SDL_Init(SDL_INIT_VIDEO)) {
31 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
32 return SDL_APP_FAILURE;
33 }
34
35 if (!SDL_CreateWindowAndRenderer("examples/renderer/viewport", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
36 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
37 return SDL_APP_FAILURE;
38 }
39
40 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
41 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
42 times) with data from a bitmap file. */
43
44 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
45 Load a .bmp into a surface, move it to a texture from there. */
46 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
47 surface = SDL_LoadBMP(bmp_path);
48 if (!surface) {
49 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
50 return SDL_APP_FAILURE;
51 }
52
53 SDL_free(bmp_path); /* done with this, the file is loaded. */
54
55 texture_width = surface->w;
56 texture_height = surface->h;
57
58 texture = SDL_CreateTextureFromSurface(renderer, surface);
59 if (!texture) {
60 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
65
66 return SDL_APP_CONTINUE; /* carry on with the program! */
67}
68
69/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
70SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
71{
72 if (event->type == SDL_EVENT_QUIT) {
73 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
74 }
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs once per frame, and is the heart of the program. */
79SDL_AppResult SDL_AppIterate(void *appstate)
80{
81 SDL_FRect dst_rect = { 0, 0, (float) texture_width, (float) texture_height };
82 SDL_Rect viewport;
83
84 /* Setting a viewport has the effect of limiting the area that rendering
85 can happen, and making coordinate (0, 0) live somewhere else in the
86 window. It does _not_ scale rendering to fit the viewport. */
87
88 /* as you can see from this, rendering draws over whatever was drawn before it. */
89 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
90 SDL_RenderClear(renderer); /* start with a blank canvas. */
91
92 /* Draw once with the whole window as the viewport. */
93 viewport.x = 0;
94 viewport.y = 0;
95 viewport.w = WINDOW_WIDTH / 2;
96 viewport.h = WINDOW_HEIGHT / 2;
97 SDL_SetRenderViewport(renderer, NULL); /* NULL means "use the whole window" */
98 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
99
100 /* top right quarter of the window. */
101 viewport.x = WINDOW_WIDTH / 2;
102 viewport.y = WINDOW_HEIGHT / 2;
103 viewport.w = WINDOW_WIDTH / 2;
104 viewport.h = WINDOW_HEIGHT / 2;
105 SDL_SetRenderViewport(renderer, &viewport);
106 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
107
108 /* bottom 20% of the window. Note it clips the width! */
109 viewport.x = 0;
110 viewport.y = WINDOW_HEIGHT - (WINDOW_HEIGHT / 5);
111 viewport.w = WINDOW_WIDTH / 5;
112 viewport.h = WINDOW_HEIGHT / 5;
113 SDL_SetRenderViewport(renderer, &viewport);
114 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
115
116 /* what happens if you try to draw above the viewport? It should clip! */
117 viewport.x = 100;
118 viewport.y = 200;
119 viewport.w = WINDOW_WIDTH;
120 viewport.h = WINDOW_HEIGHT;
121 SDL_SetRenderViewport(renderer, &viewport);
122 dst_rect.y = -50;
123 SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
124
125 SDL_RenderPresent(renderer); /* put it all on the screen! */
126
127 return SDL_APP_CONTINUE; /* carry on with the program! */
128}
129
130/* This function runs once at shutdown. */
131void SDL_AppQuit(void *appstate, SDL_AppResult result)
132{
133 SDL_DestroyTexture(texture);
134 /* SDL will clean up the window/renderer for us. */
135}
136
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 @@
1This example creates an SDL window and renderer, loads a texture
2from a .bmp file, and stretches it across the window. Each frame, we move
3the clipping rectangle around, so only a small square of the texture is
4actually drawn.
5
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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws a scene
3 * to it every frame, while sliding around a clipping rectangle.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12#define WINDOW_WIDTH 640
13#define WINDOW_HEIGHT 480
14#define CLIPRECT_SIZE 250
15#define CLIPRECT_SPEED 200 /* pixels per second */
16
17/* We will use this renderer to draw into this window every frame. */
18static SDL_Window *window = NULL;
19static SDL_Renderer *renderer = NULL;
20static SDL_Texture *texture = NULL;
21static SDL_FPoint cliprect_position;
22static SDL_FPoint cliprect_direction;
23static Uint64 last_time = 0;
24
25/* A lot of this program is examples/renderer/02-primitives, so we have a good
26 visual that we can slide a clip rect around. The actual new magic in here
27 is the SDL_SetRenderClipRect() function. */
28
29/* This function runs once at startup. */
30SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
31{
32 SDL_Surface *surface = NULL;
33 char *bmp_path = NULL;
34
35 SDL_SetAppMetadata("Example Renderer Clipping Rectangle", "1.0", "com.example.renderer-cliprect");
36
37 if (!SDL_Init(SDL_INIT_VIDEO)) {
38 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
39 return SDL_APP_FAILURE;
40 }
41
42 if (!SDL_CreateWindowAndRenderer("examples/renderer/cliprect", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
43 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
44 return SDL_APP_FAILURE;
45 }
46
47 cliprect_direction.x = cliprect_direction.y = 1.0f;
48
49 last_time = SDL_GetTicks();
50
51 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
52 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
53 times) with data from a bitmap file. */
54
55 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
56 Load a .bmp into a surface, move it to a texture from there. */
57 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
58 surface = SDL_LoadBMP(bmp_path);
59 if (!surface) {
60 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
61 return SDL_APP_FAILURE;
62 }
63
64 SDL_free(bmp_path); /* done with this, the file is loaded. */
65
66 texture = SDL_CreateTextureFromSurface(renderer, surface);
67 if (!texture) {
68 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
69 return SDL_APP_FAILURE;
70 }
71
72 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
73
74 return SDL_APP_CONTINUE; /* carry on with the program! */
75}
76
77/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
78SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
79{
80 if (event->type == SDL_EVENT_QUIT) {
81 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
82 }
83 return SDL_APP_CONTINUE; /* carry on with the program! */
84}
85
86/* This function runs once per frame, and is the heart of the program. */
87SDL_AppResult SDL_AppIterate(void *appstate)
88{
89 const SDL_Rect cliprect = { (int) SDL_roundf(cliprect_position.x), (int) SDL_roundf(cliprect_position.y), CLIPRECT_SIZE, CLIPRECT_SIZE };
90 const Uint64 now = SDL_GetTicks();
91 const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */
92 const float distance = elapsed * CLIPRECT_SPEED;
93
94 /* Set a new clipping rectangle position */
95 cliprect_position.x += distance * cliprect_direction.x;
96 if (cliprect_position.x < 0.0f) {
97 cliprect_position.x = 0.0f;
98 cliprect_direction.x = 1.0f;
99 } else if (cliprect_position.x >= (WINDOW_WIDTH - CLIPRECT_SIZE)) {
100 cliprect_position.x = (WINDOW_WIDTH - CLIPRECT_SIZE) - 1;
101 cliprect_direction.x = -1.0f;
102 }
103
104 cliprect_position.y += distance * cliprect_direction.y;
105 if (cliprect_position.y < 0.0f) {
106 cliprect_position.y = 0.0f;
107 cliprect_direction.y = 1.0f;
108 } else if (cliprect_position.y >= (WINDOW_HEIGHT - CLIPRECT_SIZE)) {
109 cliprect_position.y = (WINDOW_HEIGHT - CLIPRECT_SIZE) - 1;
110 cliprect_direction.y = -1.0f;
111 }
112 SDL_SetRenderClipRect(renderer, &cliprect);
113
114 last_time = now;
115
116 /* okay, now draw! */
117
118 /* Note that SDL_RenderClear is _not_ affected by the clipping rectangle! */
119 SDL_SetRenderDrawColor(renderer, 33, 33, 33, SDL_ALPHA_OPAQUE); /* grey, full alpha */
120 SDL_RenderClear(renderer); /* start with a blank canvas. */
121
122 /* stretch the texture across the entire window. Only the piece in the
123 clipping rectangle will actually render, though! */
124 SDL_RenderTexture(renderer, texture, NULL, NULL);
125
126 SDL_RenderPresent(renderer); /* put it all on the screen! */
127
128 return SDL_APP_CONTINUE; /* carry on with the program! */
129}
130
131/* This function runs once at shutdown. */
132void SDL_AppQuit(void *appstate, SDL_AppResult result)
133{
134 SDL_DestroyTexture(texture);
135 /* SDL will clean up the window/renderer for us. */
136}
137
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/onmouseover.webp
Binary files 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/15-cliprect/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, and draws a
2rotating texture to it, reads back the rendered pixels, converts them to
3black and white, and then draws the converted image to a corner of the
4screen.
5
6This isn't necessarily an efficient thing to do--in real life one might
7want to do this sort of thing with a render target--but it's just a visual
8example of how to use SDL_RenderReadPixels().
9
10A better, but less visual, use of SDL_RenderReadPixels() is to make
11screenshots: you grab the current contents of the screen, and save the pixels
12as 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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/onmouseover.webp
Binary files 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 @@
1/*
2 * This example creates an SDL window and renderer, and draws a
3 * rotating texture to it, reads back the rendered pixels, converts them to
4 * black and white, and then draws the converted image to a corner of the
5 * screen.
6 *
7 * This isn't necessarily an efficient thing to do--in real life one might
8 * want to do this sort of thing with a render target--but it's just a visual
9 * example of how to use SDL_RenderReadPixels().
10 *
11 * This code is public domain. Feel free to use it for any purpose!
12 */
13
14#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
15#include <SDL3/SDL.h>
16#include <SDL3/SDL_main.h>
17
18/* We will use this renderer to draw into this window every frame. */
19static SDL_Window *window = NULL;
20static SDL_Renderer *renderer = NULL;
21static SDL_Texture *texture = NULL;
22static int texture_width = 0;
23static int texture_height = 0;
24static SDL_Texture *converted_texture = NULL;
25static int converted_texture_width = 0;
26static int converted_texture_height = 0;
27
28#define WINDOW_WIDTH 640
29#define WINDOW_HEIGHT 480
30
31/* This function runs once at startup. */
32SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
33{
34 SDL_Surface *surface = NULL;
35 char *bmp_path = NULL;
36
37 SDL_SetAppMetadata("Example Renderer Read Pixels", "1.0", "com.example.renderer-read-pixels");
38
39 if (!SDL_Init(SDL_INIT_VIDEO)) {
40 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
41 return SDL_APP_FAILURE;
42 }
43
44 if (!SDL_CreateWindowAndRenderer("examples/renderer/read-pixels", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
45 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
46 return SDL_APP_FAILURE;
47 }
48
49 /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
50 engines refer to these as "sprites." We'll do a static texture (upload once, draw many
51 times) with data from a bitmap file. */
52
53 /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
54 Load a .bmp into a surface, move it to a texture from there. */
55 SDL_asprintf(&bmp_path, "%ssample.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
56 surface = SDL_LoadBMP(bmp_path);
57 if (!surface) {
58 SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
59 return SDL_APP_FAILURE;
60 }
61
62 SDL_free(bmp_path); /* done with this, the file is loaded. */
63
64 texture_width = surface->w;
65 texture_height = surface->h;
66
67 texture = SDL_CreateTextureFromSurface(renderer, surface);
68 if (!texture) {
69 SDL_Log("Couldn't create static texture: %s", SDL_GetError());
70 return SDL_APP_FAILURE;
71 }
72
73 SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
74
75 return SDL_APP_CONTINUE; /* carry on with the program! */
76}
77
78/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
79SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
80{
81 if (event->type == SDL_EVENT_QUIT) {
82 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
83 }
84 return SDL_APP_CONTINUE; /* carry on with the program! */
85}
86
87/* This function runs once per frame, and is the heart of the program. */
88SDL_AppResult SDL_AppIterate(void *appstate)
89{
90 const Uint64 now = SDL_GetTicks();
91 SDL_Surface *surface;
92 SDL_FPoint center;
93 SDL_FRect dst_rect;
94
95 /* we'll have a texture rotate around over 2 seconds (2000 milliseconds). 360 degrees in a circle! */
96 const float rotation = (((float) ((int) (now % 2000))) / 2000.0f) * 360.0f;
97
98 /* as you can see from this, rendering draws over whatever was drawn before it. */
99 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
100 SDL_RenderClear(renderer); /* start with a blank canvas. */
101
102 /* Center this one, and draw it with some rotation so it spins! */
103 dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
104 dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
105 dst_rect.w = (float) texture_width;
106 dst_rect.h = (float) texture_height;
107 /* rotate it around the center of the texture; you can rotate it from a different point, too! */
108 center.x = texture_width / 2.0f;
109 center.y = texture_height / 2.0f;
110 SDL_RenderTextureRotated(renderer, texture, NULL, &dst_rect, rotation, &center, SDL_FLIP_NONE);
111
112 /* this next whole thing is _super_ expensive. Seriously, don't do this in real life. */
113
114 /* Download the pixels of what has just been rendered. This has to wait for the GPU to finish rendering it and everything before it,
115 and then make an expensive copy from the GPU to system RAM! */
116 surface = SDL_RenderReadPixels(renderer, NULL);
117
118 /* This is also expensive, but easier: convert the pixels to a format we want. */
119 if (surface && (surface->format != SDL_PIXELFORMAT_RGBA8888) && (surface->format != SDL_PIXELFORMAT_BGRA8888)) {
120 SDL_Surface *converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA8888);
121 SDL_DestroySurface(surface);
122 surface = converted;
123 }
124
125 if (surface) {
126 /* Rebuild converted_texture if the dimensions have changed (window resized, etc). */
127 if ((surface->w != converted_texture_width) || (surface->h != converted_texture_height)) {
128 SDL_DestroyTexture(converted_texture);
129 converted_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, surface->w, surface->h);
130 if (!converted_texture) {
131 SDL_Log("Couldn't (re)create conversion texture: %s", SDL_GetError());
132 return SDL_APP_FAILURE;
133 }
134 converted_texture_width = surface->w;
135 converted_texture_height = surface->h;
136 }
137
138 /* Turn each pixel into either black or white. This is a lousy technique but it works here.
139 In real life, something like Floyd-Steinberg dithering might work
140 better: https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering*/
141 int x, y;
142 for (y = 0; y < surface->h; y++) {
143 Uint32 *pixels = (Uint32 *) (((Uint8 *) surface->pixels) + (y * surface->pitch));
144 for (x = 0; x < surface->w; x++) {
145 Uint8 *p = (Uint8 *) (&pixels[x]);
146 const Uint32 average = (((Uint32) p[1]) + ((Uint32) p[2]) + ((Uint32) p[3])) / 3;
147 if (average == 0) {
148 p[0] = p[3] = 0xFF; p[1] = p[2] = 0; /* make pure black pixels red. */
149 } else {
150 p[1] = p[2] = p[3] = (average > 50) ? 0xFF : 0x00; /* make everything else either black or white. */
151 }
152 }
153 }
154
155 /* upload the processed pixels back into a texture. */
156 SDL_UpdateTexture(converted_texture, NULL, surface->pixels, surface->pitch);
157 SDL_DestroySurface(surface);
158
159 /* draw the texture to the top-left of the screen. */
160 dst_rect.x = dst_rect.y = 0.0f;
161 dst_rect.w = ((float) WINDOW_WIDTH) / 4.0f;
162 dst_rect.h = ((float) WINDOW_HEIGHT) / 4.0f;
163 SDL_RenderTexture(renderer, converted_texture, NULL, &dst_rect);
164 }
165
166 SDL_RenderPresent(renderer); /* put it all on the screen! */
167
168 return SDL_APP_CONTINUE; /* carry on with the program! */
169}
170
171/* This function runs once at shutdown. */
172void SDL_AppQuit(void *appstate, SDL_AppResult result)
173{
174 SDL_DestroyTexture(converted_texture);
175 SDL_DestroyTexture(texture);
176 /* SDL will clean up the window/renderer for us. */
177}
178
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/17-read-pixels/thumbnail.png
Binary files 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 @@
1This example creates an SDL window and renderer, and draws some text
2using SDL_RenderDebugText(). This is not quality text rendering, but it can
3be helpful for simple apps, debugging, or showing something in a pinch.
4
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 @@
1/*
2 * This example creates an SDL window and renderer, and then draws some text
3 * using SDL_RenderDebugText() every frame.
4 *
5 * This code is public domain. Feel free to use it for any purpose!
6 */
7
8#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
9#include <SDL3/SDL.h>
10#include <SDL3/SDL_main.h>
11
12/* We will use this renderer to draw into this window every frame. */
13static SDL_Window *window = NULL;
14static SDL_Renderer *renderer = NULL;
15
16#define WINDOW_WIDTH 640
17#define WINDOW_HEIGHT 480
18
19/* This function runs once at startup. */
20SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
21{
22 SDL_SetAppMetadata("Example Renderer Debug Texture", "1.0", "com.example.renderer-debug-text");
23
24 if (!SDL_Init(SDL_INIT_VIDEO)) {
25 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
26 return SDL_APP_FAILURE;
27 }
28
29 if (!SDL_CreateWindowAndRenderer("examples/renderer/debug-text", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
30 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
31 return SDL_APP_FAILURE;
32 }
33
34 return SDL_APP_CONTINUE; /* carry on with the program! */
35}
36
37/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
38SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
39{
40 if (event->type == SDL_EVENT_QUIT) {
41 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
42 }
43 return SDL_APP_CONTINUE; /* carry on with the program! */
44}
45
46/* This function runs once per frame, and is the heart of the program. */
47SDL_AppResult SDL_AppIterate(void *appstate)
48{
49 const int charsize = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
50
51 /* as you can see from this, rendering draws over whatever was drawn before it. */
52 SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
53 SDL_RenderClear(renderer); /* start with a blank canvas. */
54
55 SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
56 SDL_RenderDebugText(renderer, 272, 100, "Hello world!");
57 SDL_RenderDebugText(renderer, 224, 150, "This is some debug text.");
58
59 SDL_SetRenderDrawColor(renderer, 51, 102, 255, SDL_ALPHA_OPAQUE); /* light blue, full alpha */
60 SDL_RenderDebugText(renderer, 184, 200, "You can do it in different colors.");
61 SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
62
63 SDL_SetRenderScale(renderer, 4.0f, 4.0f);
64 SDL_RenderDebugText(renderer, 14, 65, "It can be scaled.");
65 SDL_SetRenderScale(renderer, 1.0f, 1.0f);
66 SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣");
67
68 SDL_RenderDebugTextFormat(renderer, (float) ((WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000);
69
70 SDL_RenderPresent(renderer); /* put it all on the screen! */
71
72 return SDL_APP_CONTINUE; /* carry on with the program! */
73}
74
75/* This function runs once at shutdown. */
76void SDL_AppQuit(void *appstate, SDL_AppResult result)
77{
78 /* SDL will clean up the window/renderer for us. */
79}
80
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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/renderer/18-debug-text/thumbnail.png
Binary files 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 @@
1<!DOCTYPE html>
2<html lang="en-us">
3 <head>
4 <meta charset="utf-8" />
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1" />
7 <title>@project_name@ Examples: @category_description@</title>
8 <link rel="icon" href="/@project_name@/thumbnail.png" type="image/png" />
9 <link
10 rel="stylesheet"
11 type="text/css"
12 href="/@project_name@/examples.css"
13 />
14 <style>
15 main > h1 {
16 margin-top: 0;
17 }
18 </style>
19
20 <meta property="og:type" content="website">
21 <meta property="og:title" content="@project_name@ Examples: @category_description@">
22 <meta property="og:description" content="@project_name@ Examples: @category_description@">
23 <meta property="og:image" content="@preview_image@" />
24
25 </head>
26 <body>
27 <header>
28 <a href="/">@project_name@ Examples</a>
29 </header>
30 <main>
31 <nav class="breadcrumb">
32 <ul>
33 <li><a href="/@project_name@/">@project_name@</a></li>
34 <li><a href="/@project_name@/@category_name@">@category_name@</a></li>
35 </ul>
36 </nav>
37 <h1>@project_name@ examples: @category_description@</h1>
38 <div class="list">@examples_list_html@</div>
39 </main>
40 </body>
41</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 @@
1<!DOCTYPE html>
2<html lang="en-us">
3 <head>
4 <meta charset="utf-8" />
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <meta name="viewport" content="width=device-width, initial-scale=1" />
7 <title>@project_name@ Examples</title>
8 <link rel="icon" href="/@project_name@/thumbnail.png" type="image/png" />
9 <link
10 rel="stylesheet"
11 type="text/css"
12 href="/@project_name@/examples.css"
13 />
14 <style>
15 main > h1 {
16 margin-top: 0;
17 }
18 </style>
19
20 <meta property="og:type" content="website">
21 <meta property="og:title" content="@project_name@ Examples">
22 <meta property="og:description" content="@project_name@ Examples">
23 <meta property="og:image" content="@preview_image@" />
24
25 </head>
26 <body>
27 <header>
28 <a href="/">SDL Examples</a>
29 </header>
30 <main>
31 <nav class="breadcrumb">
32 <ul>
33 <li><a href="/@project_name@">@project_name@</a></li>
34 </ul>
35 </nav>
36 <h1>@project_name@ examples</h1>
37
38 @homepage_list_html@
39 </main>
40 </body>
41</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
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/examples/template-placeholder.png
Binary files 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 @@
1/*
2 * This example code $WHAT_IT_DOES.
3 *
4 * This code is public domain. Feel free to use it for any purpose!
5 */
6
7#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
8#include <SDL3/SDL.h>
9#include <SDL3/SDL_main.h>
10
11/* We will use this renderer to draw into this window every frame. */
12static SDL_Window *window = NULL;
13static SDL_Renderer *renderer = NULL;
14
15
16/* This function runs once at startup. */
17SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
18{
19 SDL_SetAppMetadata("Example HUMAN READABLE NAME", "1.0", "com.example.CATEGORY-NAME");
20
21 if (!SDL_Init(SDL_INIT_VIDEO)) {
22 SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
23 return SDL_APP_FAILURE;
24 }
25
26 if (!SDL_CreateWindowAndRenderer("examples/CATEGORY/NAME", 640, 480, 0, &window, &renderer)) {
27 SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
28 return SDL_APP_FAILURE;
29 }
30 return SDL_APP_CONTINUE; /* carry on with the program! */
31}
32
33/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
34SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
35{
36 if (event->type == SDL_EVENT_QUIT) {
37 return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
38 }
39 return SDL_APP_CONTINUE; /* carry on with the program! */
40}
41
42/* This function runs once per frame, and is the heart of the program. */
43SDL_AppResult SDL_AppIterate(void *appstate)
44{
45 return SDL_APP_CONTINUE; /* carry on with the program! */
46}
47
48/* This function runs once at shutdown. */
49void SDL_AppQuit(void *appstate, SDL_AppResult result)
50{
51 /* SDL will clean up the window/renderer for us. */
52}
53
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 @@
1/** from ghwikipp.css */
2:root {
3 color-scheme: dark light; /* both supported */
4}
5
6body {
7 background-color: white;
8 padding: 2vw;
9 color: #333;
10 max-width: 1200px;
11 margin: 0 auto;
12 font-size: 16px;
13 line-height: 1.5;
14 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
15 Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
16 overflow-wrap: break-word;
17}
18
19a {
20 color: #0969da;
21 /* text-decoration: none; */
22}
23
24a:visited {
25 color: #064998;
26}
27
28h1 {
29 border-bottom: 2px solid #efefef;
30}
31
32h2 {
33 border-bottom: 1px solid #efefef;
34}
35
36p {
37 max-width: 85ch;
38}
39
40li {
41 max-width: 85ch;
42}
43
44div.sourceCode {
45 background-color: #f6f8fa;
46 max-width: 100%;
47 padding: 16px;
48}
49
50code {
51 background-color: #f6f8fa;
52 padding: 0px;
53 font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
54 "Liberation Mono", monospace;
55}
56
57table {
58 border: 1px solid #808080;
59 border-collapse: collapse;
60}
61
62td {
63 border: 1px solid #808080;
64 padding: 5px;
65}
66
67tr:nth-child(even) {
68 background-color: #f6f8fa;
69}
70
71.wikitopbanner {
72 background-color: #efefef;
73 padding: 10px;
74 margin-bottom: 10px;
75 width: auto;
76}
77
78.wikibottombanner {
79 background-color: #efefef;
80 padding: 10px;
81 margin-top: 10px;
82 width: auto;
83}
84
85.alertBox {
86 background-color: #f8d7da;
87 border: 1px solid #f5c6cb;
88 max-width: 60%;
89 padding: 10;
90 margin: auto;
91}
92
93.anchorImage {
94 visibility: hidden;
95 padding-left: 0.2em;
96 color: #fff;
97}
98
99.anchorText:hover .anchorImage {
100 visibility: visible;
101}
102
103hr {
104 display: block;
105 height: 1px;
106 border: 0;
107 border-top: 1px solid #efefef;
108 margin: 1em 0;
109 padding: 0;
110}
111
112/* Text and background color for dark mode */
113@media (prefers-color-scheme: dark) {
114 body {
115 color: #e6edf3;
116 background-color: #0d1117;
117 }
118
119 h1 {
120 border-color: rgba(48, 54, 61, 0.7);
121 }
122
123 h2 {
124 border-color: rgba(48, 54, 61, 0.7);
125 }
126
127 hr {
128 border-color: rgba(48, 54, 61, 0.7);
129 }
130
131 div.sourceCode {
132 background-color: #161b22;
133 }
134
135 code {
136 background-color: #161b22;
137 }
138
139 a {
140 color: #4493f8;
141 }
142
143 a:visited {
144 color: #2f66ad;
145 }
146
147 table {
148 border-color: rgba(48, 54, 61, 0.7);
149 }
150
151 td {
152 border-color: rgba(48, 54, 61, 0.7);
153 }
154
155 tr:nth-child(even) {
156 background-color: #161b22;
157 }
158
159 .wikitopbanner {
160 background-color: #263040;
161 }
162
163 .wikibottombanner {
164 background-color: #263040;
165 }
166
167 .anchorText:hover .anchorImage {
168 filter: invert(100%);
169 }
170}
171
172@media print {
173 body {
174 font-size: 12px;
175 }
176
177 table {
178 font-size: inherit;
179 }
180
181 a:visited {
182 color: #0969da;
183 }
184
185 .wikitopbanner,
186 .anchorText,
187 .wikibottombanner {
188 display: none;
189 }
190}
191
192/** additional (& overrides) for examples */
193header {
194 background-color: #efefef;
195 padding: 10px;
196 font-size: 2rem;
197}
198
199header > a,
200header > a:hover,
201header > a:visited {
202 color: inherit;
203 text-decoration: none;
204}
205
206.breadcrumb {
207 padding: 0.75rem 0.75rem;
208}
209
210.breadcrumb ul {
211 display: flex;
212 flex-wrap: wrap;
213 list-style: none;
214 margin: 0;
215 padding: 0;
216}
217
218.breadcrumb li:not(:last-child)::after {
219 display: inline-block;
220 margin: 0 0.25rem;
221 content: "»";
222}
223
224.list {
225 display: flex;
226 flex-flow: row wrap;
227 gap: 24px;
228}
229
230.list > a > div {
231 width: 200px;
232 border: 5px solid #efefef;
233 border-radius: 5px;
234 background: #efefef;
235
236 display: flex;
237 flex-flow: column nowrap;
238
239 transition: border 0.25s;
240}
241
242.list > a > div:hover {
243 border-color: #064998;
244}
245
246.list > a > div > img {
247 width: 100%;
248 border-radius: 5px;
249}
250
251.list > a > div > div {
252 text-align: center;
253}
254
255.list > a,
256.list > a:visited {
257 display: block;
258 color: inherit;
259 text-decoration: none;
260}
261.list > a:hover {
262 color: #0969da;
263}
264
265@media (prefers-color-scheme: dark) {
266 header {
267 background-color: #263040;
268 }
269
270 .breadcrumb li:not(:last-child)::after {
271 color: #efefef;
272 }
273
274 .list > a > div {
275 border-color: #333;
276 background: #333;
277 }
278}
279
280@media only screen and (max-width: 992px) {
281 .list > a > div {
282 width: 150px;
283 }
284}
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 @@
1<!doctype html>
2<html lang="en-us">
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1" />
7 <title>@project_name@ Example: @category_name@/@example_name@</title>
8 <link rel="icon" href="/@project_name@/thumbnail.png" type="image/png" />
9
10 <meta property="og:type" content="website">
11 <meta property="og:title" content="@project_name@ Example: @category_name@/@example_name@">
12 <meta property="og:description" content="@description@">
13 <meta property="og:image" content="@preview_image@" />
14
15 <link rel="stylesheet" type="text/css" href="/@project_name@/examples.css" />
16 <style>
17 main {
18 display: flex;
19 }
20
21 main > #sidebar {
22 flex: 0 1 25%;
23 border-left: 2px solid #efefef;
24 padding: 1rem 1rem;
25 }
26
27 main > #content {
28 flex: 1 1 auto;
29 margin-bottom: 16px;
30 }
31
32 main > #content > h1 {
33 margin-top: 0;
34 }
35
36 main > #sidebar ul {
37 list-style-type: none;
38 padding: 0;
39 margin: 0;
40 }
41
42 main > #sidebar li {
43 padding: 2px 0;
44 }
45
46 #example-description {
47 max-width: 85ch;
48 margin-bottom: 16px;
49 }
50
51 .canvas-container {
52 display: flex;
53 align-items: center;
54 justify-content: center;
55 }
56
57 #canvas {
58 max-width: 100%;
59 box-shadow: 0 0 0.5rem #7787;
60 }
61
62 #output-container {
63 position: fixed;
64 top: 100%;
65 left: 0;
66 right: 0;
67 bottom: 0;
68
69 background-color: black;
70 border: none;
71 border-top: 1px solid #778;
72 margin: 0;
73 padding: 1rem;
74
75 transition: top 0.25s;
76 }
77
78 #output-container::before {
79 position: absolute;
80 bottom: 100%;
81 right: 1rem;
82
83 content: 'Console';
84 font-size: 1.5rem;
85 color: white;
86 background: black;
87 border: 1px solid #778;
88 border-bottom: none;
89 padding: 0.75rem 1.5rem;
90 border-radius: 0.5rem 0.5rem 0 0;
91 }
92
93 #output-container:hover,
94 #output-container:focus-within {
95 top: 50%;
96 }
97
98 #output-container:focus-within {
99 border-top: 2px solid orange;
100 }
101
102 #output-container:focus-within::before {
103 border: 2px solid orange;
104 border-bottom: none;
105 }
106
107 #output {
108 width: 100%;
109 height: 100%;
110 padding: 0;
111 margin: 0;
112
113 border: none;
114 background: black;
115 color: white;
116 outline: none;
117 resize: none;
118
119 font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
120 "Liberation Mono", monospace;
121 }
122
123 #source-code {
124 position: fixed;
125 top: 100%;
126 left: 0;
127 right: 0;
128 bottom: 0;
129
130 background: #e0eaee;
131 padding: 1rem;
132
133 transition: top 0.25s;
134 }
135
136 #source-code::before {
137 position: absolute;
138 bottom: 100%;
139 left: 1rem;
140
141 content: 'Source code';
142 font-size: 1.5rem;
143 background: linear-gradient(to bottom, #789, #e0eaee);
144 padding: 0.75rem 1.5rem;
145 border-radius: 0.5rem 0.5rem 0 0;
146
147 /* Used for a hack to avoid tab labels showing on top of tabs; see
148 comment below for details. */
149 transition: bottom 0.25s;
150 }
151
152 #source-code:hover,
153 #source-code:focus-within {
154 top: 50%;
155 }
156
157 #source-code:focus-within {
158 border-top: 2px solid orange;
159 }
160
161 #source-code:focus-within::before {
162 border: 2px solid orange;
163 border-bottom: none;
164 }
165
166 #source-code-contents {
167 height: 100%;
168 overflow: scroll;
169 }
170
171 /* Hack: Sinze z-index only goes one way, and both tab labels should be
172 behind each other's tab, put the former on top (higher z-index) and
173 make the latter one disappear when the former is hovered. */
174 #output-container:hover ~ #source-code::before,
175 #output-container:focus-within ~ #source-code::before {
176 bottom: -100%;
177 }
178
179 @media (prefers-color-scheme: dark) {
180 main > #sidebar {
181 border-color: rgba(48, 54, 61, 0.7);
182 }
183 }
184
185 @media only screen and (max-width: 992px) {
186 main {
187 flex-direction: column;
188 }
189
190 main > #sidebar {
191 border: none;
192 }
193 }
194 </style>
195 <link rel="stylesheet" type="text/css" href="highlight.css">
196 </head>
197 <body>
198 <header>
199 <a href="/">SDL Examples</a>
200 </header>
201 <main>
202 <div id="content">
203 <nav class="breadcrumb">
204 <ul>
205 <li><a href="/@project_name@">@project_name@</a></li>
206 <li><a href="/@project_name@/@category_name@">@category_name@</a></li>
207 <li><a href="/@project_name@/@category_name@/@example_name@">@example_name@</a></li>
208 </ul>
209 </nav>
210 <hr/>
211 <div id="example-description">@description@</div>
212 <div class="canvas-container">
213 <canvas
214 id="canvas"
215 oncontextmenu="event.preventDefault()"
216 tabindex="-1"
217 ></canvas>
218 </div>
219 </div>
220 <div id="sidebar">
221 <h3>Other examples:</h3>
222 @other_examples_html@
223 </div>
224 </main>
225
226 <div id="output-container">
227 <textarea id="output" rows="8" spellcheck="false" readonly></textarea>
228 </div>
229
230 <div id="source-code" tabindex="1">
231 <div id="source-code-contents">@htmlified_source_code@</div>
232 </div>
233
234 <script type='text/javascript'>
235 var Module = {
236 preRun: [],
237 postRun: [],
238 print: (function() {
239 var element = document.getElementById('output');
240 if (element) element.value = ''; // clear browser cache
241 return function(text) {
242 var elem = document.getElementById('output-container');
243 if (elem.style['top'] == '') {
244 elem.style['top'] = '50%';
245 setTimeout(function() { elem.style['top'] = ''; }, 3000);
246 }
247
248 if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
249 // These replacements are necessary if you render to raw HTML
250 //text = text.replace(/&/g, "&amp;");
251 //text = text.replace(/</g, "&lt;");
252 //text = text.replace(/>/g, "&gt;");
253 //text = text.replace('\n', '<br>', 'g');
254 console.log(text);
255 if (element) {
256 element.value += text + "\n";
257 element.scrollTop = element.scrollHeight; // focus on bottom
258 }
259 };
260 })(),
261 printErr: function(text) { Module.print(text) },
262 canvas: (() => {
263 var canvas = document.getElementById('canvas');
264
265 // As a default initial behavior, pop up an alert when webgl context is lost. To make your
266 // application robust, you may want to override this behavior before shipping!
267 // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
268 canvas.addEventListener("webglcontextlost", (e) => { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
269
270 return canvas;
271 })(),
272 setStatus: (text) => {},
273 totalDependencies: 0,
274 monitorRunDependencies: (left) => {
275 this.totalDependencies = Math.max(this.totalDependencies, left);
276 Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
277 }
278 };
279 Module.setStatus('Downloading...');
280 window.onerror = (event) => {
281 // TODO: do not warn on ok events like simulating an infinite loop or exitStatus
282 Module.setStatus('Exception thrown, see JavaScript console');
283 Module.setStatus = (text) => {
284 if (text) console.error('[post-exception status] ' + text);
285 };
286 };
287 </script>
288 <script async type="text/javascript" src="@javascript_file@"></script>
289 </body>
290</html>
291
292