mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-15 09:18:27 +00:00
examples: Add a way to add datafiles to an example, and add audio/load-wav
This commit is contained in:
parent
f562a6d9f7
commit
195c26a50a
4 changed files with 133 additions and 10 deletions
|
@ -80,14 +80,31 @@ sub handle_example_dir {
|
||||||
}
|
}
|
||||||
closedir($dh);
|
closedir($dh);
|
||||||
|
|
||||||
|
my $datafilestxtpath = "$examples_dir/$category/$example/datafiles.txt";
|
||||||
|
my $datafiles_str = '';
|
||||||
|
if ( -f $datafilestxtpath ) {
|
||||||
|
open (my $datafilesh, '<', $datafilestxtpath) or die("Couldn't opendir '$datafilestxtpath': $!\n");
|
||||||
|
$spc = '';
|
||||||
|
while (<$datafilesh>) {
|
||||||
|
chomp;
|
||||||
|
my $path = "$examples_dir/$category/$example/$_";
|
||||||
|
my $fname = $_;
|
||||||
|
$fname =~ s/\A.*\///;
|
||||||
|
$datafiles_str .= "$spc--embed-file=$path\@/$fname";
|
||||||
|
$spc = ' ';
|
||||||
|
}
|
||||||
|
close($datafilesh);
|
||||||
|
}
|
||||||
|
|
||||||
my $dst = "$output_dir/$category/$example";
|
my $dst = "$output_dir/$category/$example";
|
||||||
|
|
||||||
print("Building $category/$example ...\n");
|
print("Building $category/$example ...\n");
|
||||||
|
|
||||||
|
|
||||||
do_mkdir($dst);
|
do_mkdir($dst);
|
||||||
|
|
||||||
# !!! FIXME: hardcoded SDL3 references, need to fix this for satellite libraries and SDL2.
|
# !!! FIXME: hardcoded SDL3 references, need to fix this for satellite libraries and SDL2.
|
||||||
do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && emcc -s USE_SDL=0 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb -s ASSERTIONS=0 -o '$dst/index.js' '-I$examples_dir/../include' $files_str '$compile_dir/libSDL3.a'") == 0
|
do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && emcc -s USE_SDL=0 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=1gb -s ASSERTIONS=0 -o '$dst/index.js' '-I$examples_dir/../include' $files_str '$compile_dir/libSDL3.a' $datafiles_str") == 0
|
||||||
or die("Failed to build $category/$example!\n");
|
or die("Failed to build $category/$example!\n");
|
||||||
|
|
||||||
my $highlight_cmd = "highlight '--outdir=$dst' --style-outfile=highlight.css --fragment --enclose-pre --stdout --syntax=c '--plug-in=$examples_dir/highlight-plugin.lua'";
|
my $highlight_cmd = "highlight '--outdir=$dst' --style-outfile=highlight.css --fragment --enclose-pre --stdout --syntax=c '--plug-in=$examples_dir/highlight-plugin.lua'";
|
||||||
|
|
|
@ -70,7 +70,7 @@ if(WINDOWS_STORE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
macro(add_sdl_example_executable TARGET)
|
macro(add_sdl_example_executable TARGET)
|
||||||
cmake_parse_arguments(AST "BUILD_DEPENDENT;NEEDS_RESOURCES;" "" "SOURCES" ${ARGN})
|
cmake_parse_arguments(AST "BUILD_DEPENDENT" "" "SOURCES;DATAFILES" ${ARGN})
|
||||||
if(AST_UNPARSED_ARGUMENTS)
|
if(AST_UNPARSED_ARGUMENTS)
|
||||||
message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}")
|
message(FATAL_ERROR "Unknown argument(s): ${AST_UNPARSED_ARGUMENTS}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -100,8 +100,8 @@ macro(add_sdl_example_executable TARGET)
|
||||||
"../test/uwp/splash-620x300.png"
|
"../test/uwp/splash-620x300.png"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(AST_NEEDS_RESOURCES)
|
if(AST_DATAFILES)
|
||||||
list(APPEND EXTRA_SOURCES ${RESOURCE_FILES})
|
list(APPEND EXTRA_SOURCES ${DATAFILES})
|
||||||
endif()
|
endif()
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
add_library(${TARGET} SHARED ${AST_SOURCES} ${EXTRA_SOURCES})
|
add_library(${TARGET} SHARED ${AST_SOURCES} ${EXTRA_SOURCES})
|
||||||
|
@ -113,11 +113,11 @@ macro(add_sdl_example_executable TARGET)
|
||||||
target_link_libraries(${TARGET} PRIVATE SDL3::${sdl_name_component})
|
target_link_libraries(${TARGET} PRIVATE SDL3::${sdl_name_component})
|
||||||
|
|
||||||
list(APPEND SDL_EXAMPLE_EXECUTABLES ${TARGET})
|
list(APPEND SDL_EXAMPLE_EXECUTABLES ${TARGET})
|
||||||
if(AST_NEEDS_RESOURCES)
|
if(AST_DATAFILES)
|
||||||
if(PSP OR PS2)
|
if(PSP OR PS2)
|
||||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E make_directory $<TARGET_FILE_DIR:${TARGET}>/sdl-${TARGET}
|
COMMAND ${CMAKE_COMMAND} ARGS -E make_directory $<TARGET_FILE_DIR:${TARGET}>/sdl-${TARGET}
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILES} $<TARGET_FILE_DIR:${TARGET}>/sdl-${TARGET})
|
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${AST_DATAFILES} $<TARGET_FILE_DIR:${TARGET}>/sdl-${TARGET})
|
||||||
elseif(WINDOWS_STORE)
|
elseif(WINDOWS_STORE)
|
||||||
# MSVC does build the dependent targets (or POST_BUILD commands) when building an application
|
# MSVC does build the dependent targets (or POST_BUILD commands) when building an application
|
||||||
# after starting to debug. By copying the resources in a custom target, the files can be copied afterwards.
|
# after starting to debug. By copying the resources in a custom target, the files can be copied afterwards.
|
||||||
|
@ -125,7 +125,7 @@ macro(add_sdl_example_executable TARGET)
|
||||||
cmake_minimum_required(VERSION 3.19)
|
cmake_minimum_required(VERSION 3.19)
|
||||||
add_custom_target(zzz-resources-copy-${TARGET}
|
add_custom_target(zzz-resources-copy-${TARGET}
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${TARGET}>/AppX"
|
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${TARGET}>/AppX"
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RESOURCE_FILES} "$<TARGET_FILE_DIR:${TARGET}>/AppX"
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${AST_DATAFILES} "$<TARGET_FILE_DIR:${TARGET}>/AppX"
|
||||||
)
|
)
|
||||||
add_dependencies(${TARGET} zzz-resources-copy-${TARGET})
|
add_dependencies(${TARGET} zzz-resources-copy-${TARGET})
|
||||||
else()
|
else()
|
||||||
|
@ -133,15 +133,15 @@ macro(add_sdl_example_executable TARGET)
|
||||||
endif()
|
endif()
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# Make sure resource files get installed into macOS/iOS .app bundles.
|
# Make sure resource files get installed into macOS/iOS .app bundles.
|
||||||
set_target_properties(${TARGET} PROPERTIES RESOURCE "${RESOURCE_FILES}")
|
set_target_properties(${TARGET} PROPERTIES RESOURCE "${AST_DATAFILES}")
|
||||||
endif()
|
endif()
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
foreach(res IN LISTS RESOURCE_FILES)
|
foreach(res IN LISTS AST_DATAFILES)
|
||||||
get_filename_component(res_name "${res}" NAME)
|
get_filename_component(res_name "${res}" NAME)
|
||||||
target_link_options(${TARGET} PRIVATE "SHELL:--embed-file ${res}@${res_name}")
|
target_link_options(${TARGET} PRIVATE "SHELL:--embed-file ${res}@${res_name}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$<TARGET_FILE_DIR:${TARGET}>/$<JOIN:${RESOURCE_FILE_NAMES},$<SEMICOLON>$<TARGET_FILE_DIR:${TARGET}>/>")
|
set_property(TARGET ${TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$<TARGET_FILE_DIR:${TARGET}>/$<JOIN:${AST_DATAFILES},$<SEMICOLON>$<TARGET_FILE_DIR:${TARGET}>/>")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WINDOWS)
|
if(WINDOWS)
|
||||||
|
@ -180,6 +180,7 @@ add_sdl_example_executable(renderer-clear SOURCES renderer/01-clear/renderer-cle
|
||||||
add_sdl_example_executable(renderer-primitives SOURCES renderer/02-primitives/renderer-primitives.c)
|
add_sdl_example_executable(renderer-primitives SOURCES renderer/02-primitives/renderer-primitives.c)
|
||||||
add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c)
|
add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c)
|
||||||
add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c)
|
add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c)
|
||||||
|
add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ../test/sample.wav)
|
||||||
|
|
||||||
|
|
||||||
if(PSP)
|
if(PSP)
|
||||||
|
|
1
examples/audio/03-load-wav/datafiles.txt
Normal file
1
examples/audio/03-load-wav/datafiles.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
../../../test/sample.wav
|
104
examples/audio/03-load-wav/load-wav.c
Normal file
104
examples/audio/03-load-wav/load-wav.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* This example code creates an simple audio stream for playing sound, and
|
||||||
|
* loads a .wav file that is pushed through the stream in a loop.
|
||||||
|
*
|
||||||
|
* This code is public domain. Feel free to use it for any purpose!
|
||||||
|
*
|
||||||
|
* The .wav file is a sample from Will Provost's song, The Living Proof,
|
||||||
|
* used with permission.
|
||||||
|
*
|
||||||
|
* From the album The Living Proof
|
||||||
|
* Publisher: 5 Guys Named Will
|
||||||
|
* Copyright 1996 Will Provost
|
||||||
|
* https://itunes.apple.com/us/album/the-living-proof/id4153978
|
||||||
|
* http://www.amazon.com/The-Living-Proof-Will-Provost/dp/B00004R8RH
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
|
/* We will use this renderer to draw into this window every frame. */
|
||||||
|
static SDL_Window *window = NULL;
|
||||||
|
static SDL_Renderer *renderer = NULL;
|
||||||
|
static SDL_AudioStream *stream = NULL;
|
||||||
|
static Uint8 *wav_data = NULL;
|
||||||
|
static Uint32 wav_data_len = 0;
|
||||||
|
|
||||||
|
/* This function runs once at startup. */
|
||||||
|
int SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SDL_AudioSpec spec;
|
||||||
|
char *wav_path = NULL;
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we don't _need_ a window for audio-only things but it's good policy to have one. */
|
||||||
|
if (SDL_CreateWindowAndRenderer("examples/audio/load-wav", 640, 480, 0, &window, &renderer) == -1) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL);
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the .wav file from wherever the app is being run from. */
|
||||||
|
SDL_asprintf(&wav_path, "%ssample.wav", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||||
|
if (SDL_LoadWAV(wav_path, &spec, &wav_data, &wav_data_len) == -1) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load .wav file!", SDL_GetError(), NULL);
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(wav_path); /* done with this string. */
|
||||||
|
|
||||||
|
/* Create our audio stream in the same format as the .wav file. It'll convert to what the audio hardware wants. */
|
||||||
|
stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);
|
||||||
|
if (!stream) {
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create audio stream!", SDL_GetError(), window);
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */
|
||||||
|
SDL_ResumeAudioStreamDevice(stream);
|
||||||
|
|
||||||
|
/* (this is a web browser requirement, not an SDL thing.) */
|
||||||
|
SDL_Log("If you're running this in a web browser, you need to click the window before you'll hear anything.");
|
||||||
|
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||||
|
int SDL_AppEvent(void *appstate, const SDL_Event *event)
|
||||||
|
{
|
||||||
|
if (event->type == SDL_EVENT_QUIT) {
|
||||||
|
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||||
|
}
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs once per frame, and is the heart of the program. */
|
||||||
|
int SDL_AppIterate(void *appstate)
|
||||||
|
{
|
||||||
|
/* see if we need to feed the audio stream more data yet.
|
||||||
|
We're being lazy here, but if there's less than the entire wav file left to play,
|
||||||
|
just shove a whole copy of it into the queue, so we always have _tons_ of
|
||||||
|
data queued for playback. */
|
||||||
|
if (SDL_GetAudioStreamAvailable(stream) < wav_data_len) {
|
||||||
|
/* feed more data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */
|
||||||
|
SDL_PutAudioStreamData(stream, wav_data, wav_data_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we're not doing anything with the renderer, so just blank it out. */
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
|
||||||
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function runs once at shutdown. */
|
||||||
|
void SDL_AppQuit(void *appstate)
|
||||||
|
{
|
||||||
|
SDL_free(wav_data); /* strictly speaking, this isn't necessary because the process is ending, but it's good policy. */
|
||||||
|
/* SDL will clean up the window/renderer for us. */
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue