SDL and WebAssembly


#1

On the WebAssembly official site, it says:

WebAssembly applications can use high-level C/C++ APIs such as the C and C++ standard libraries, OpenGL, SDL, pthreads, and others, just as in normal C/C++ development. Under the covers, these libraries implement their functionality by using low-level facilities provided by WebAssembly implementations. On the Web, they utilize Web APIs (for example, OpenGL is executed on WebGL, libc date and time methods use the browser’s Date functionality, etc.). In other contexts, other low-level mechanisms may be used.

This is interesting, but I haven’t been able to find any documentation on the subject. How do I get at the SDL bindings in WebAssembly?


#2

I’ve never done it, but search online for emscripten


#3

Yeah, I know about the emscripten/asm.js version of SDL. That’s not the same thing as WASM.

Mason


#4

No, but it can output Web Assembly too: http://kripken.github.io/emscripten-site/docs/compiling/WebAssembly.html


#5

I’m gonna write all this out in case it’s helpful for everyone, but disregard whatever you already know here.

One could probably generate wasm without Emscripten, but it’s more or less an assumption at this moment that you’ll be using Emscripten.

Basically you build things the same way as you would for asm.js, but instead of generating Javascript at the end, it generates WebAssembly. This happens at link time; you can put the same compiled object files in the linker and specify -s WASM=1 and it’ll spit out WebAssembly binary instead of asm.js “script.”

Emscripten ships with an implementation of SDL 1.2’s API; even though you call it from C code, it’s written entirely in Javascript!

Since that’s from-scratch code and some things aren’t doable in a web browser, it’s a sort of Good Enough implementation of the API. If you have an older game, it might Just Work though, which is cool.

For SDL2, the actual SDL2 codebase is ported to Emscripten, so you can literally just compile it and link it to your project. In that scenario, it works when generating either asm.js or WebAssembly.

Here’s the Unreal Tournament '99 flyby using it. If your browser supports wasm, it’ll use that, if not it’ll use asm.js (which happens to work as generic Javascript if your browser supports neither wasm or asm.js). You probably won’t notice a difference at runtime, except maybe wasm starts up faster and might have some other optimizations.

For video, you can use OpenGL (which Emscripten will convert to WebGL calls). It’s…touchy though. Compatiblity with legacy OpenGL is really spotty, but if you’re looking more like GL3 Core Profile, it’s pretty sweet. That UT99 thing used libRegal with UT99’s GL1.2 code, which sort of stumbled its way to working in a pretty inefficient manner. We did better with Unrealty later, but you need a browser with WebGL2:

No one has tried to use SDL2 with node.js, and there’s a lot of code in our implementation that assumes you are running in a web browser, so it can have access to facilities for video/audio/input/etc. If something similar is available for node, I’d love to hear about it.

I’ve ported several things to Emscripten using SDL 1.2 and SDL 2.0 for Jump:

https://playonjump.com/

So if you have questions, I probably have answers.

–ryan.


#6

Cool, thanks for the explanation!


#7

You don’t actually need to compile SDL2 yourself if you don’t want to. By defining USE_SDL=2 on the emscripten commandline it will automatically download SDL2 and compile it instead of using the javascript implementation of SDL 1.2

https://kripken.github.io/emscripten-site/docs/compiling/Building-Projects.html?highlight=sdl2#emscripten-ports


#8

Wow, I had no idea! That’s wild. :slight_smile:

–ryan.