emscripten: Let SDL hints be set by URL parameters.

Any parameters (key/value pairs after the '?' in a URL) that have a keyname
that starts with `SDL_` will be put into Emscripten's environment variable
emulation table at startup, before SDL_main runs.

This lets users set hints the same way they might set them from a shell's
command line on a desktop platform:

For example:

`https://example.com/my_sdl3_application.html?SDL_RENDER_DRIVER=software`

Fixes #10154.
This commit is contained in:
Ryan C. Gordon 2024-07-03 20:05:43 -04:00
parent 9d47daef0a
commit f338fa20dd
3 changed files with 68 additions and 0 deletions

View File

@ -1480,6 +1480,8 @@ elseif(EMSCRIPTEN)
# project. Uncomment at will for verbose cross-compiling -I/../ path info.
sdl_compile_options(PRIVATE "-Wno-warn-absolute-paths")
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/emscripten/*.c")
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/emscripten/*.c")
set(HAVE_SDL_MAIN_CALLBACKS TRUE)

View File

@ -94,6 +94,16 @@
/* We need to export SDL_main so it can be launched from Java */
#define SDLMAIN_DECLSPEC SDL_DECLSPEC
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
/* On Emscripten, SDL provides a main function that converts URL
parameters that start with "SDL_" to environment variables, so
they can be used as SDL hints, etc.
This is 100% optional, so if you don't want this to happen, you may
define SDL_MAIN_HANDLED
*/
#define SDL_MAIN_AVAILABLE
#elif defined(SDL_PLATFORM_PSP)
/* On PSP SDL provides a main function that sets the module info,
activates the GPU and starts the thread required to be able to exit

View File

@ -0,0 +1,56 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_PLATFORM_EMSCRIPTEN
#include <emscripten/emscripten.h>
EM_JS_DEPS(sdlrunapp, "$dynCall,$stringToNewUTF8");
int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved)
{
(void)reserved;
// Move any URL params that start with "SDL_" over to environment
// variables, so the hint system can pick them up, etc, much like a user
// can set them from a shell prompt on a desktop machine. Ignore all
// other params, in case the app wants to use them for something.
MAIN_THREAD_EM_ASM({
var parms = new URLSearchParams(window.location.search);
for (const [key, value] of parms) {
if (key.startsWith("SDL_")) {
var ckey = stringToNewUTF8(key);
var cvalue = stringToNewUTF8(value);
if ((ckey != 0) && (cvalue != 0)) {
//console.log("Setting SDL env var '" + key + "' to '" + value + "' ...");
dynCall('iiii', $0, [ckey, cvalue, 1]);
}
_free(ckey); // these must use free(), not SDL_free()!
_free(cvalue);
}
}
}, SDL_setenv);
return mainFunction(argc, argv);
}
#endif