SFourmi on the web using Emscripten

The SFourmi project is now running directly in the web browser, being compiled from C++ into WebAssembly using Emscripten.

Try it here

but be patient, it is very slow to load (explanations below)

You can then use mouse and keys (F2, click and select, and so on)

Why ?

For my new job I wanted to explore the possibility of running C++ code in the browser. I decided to use SFourmi as a testing project, because it only uses libraries supported by emscripten (SDL), and the project can be shown to anyone with a web browser !

Build it

You need to have emscripten installed on your system, follow the instructions here

Don’t forget to run the scripts to get all emscripten tools in the path

source emscripten-install/emsdk_env.sh

Get the source code of SuperFourmi using git from https://github.com/manikbh/SFourmi/

cd SFourmi
mkdir build
cd build
emcmake cmake ../
emmake make
cd src
emrun SFourmi.html # To run it

How?

I found the documentation of Emscripten lacking, and the error reporting really bad, so for a long time it did not work and I had no idea why, even though I followed multiple tutorials that seems contradictory or just outdated as emscripten evolves.

I first added CMake support to SFourmi to reorganize the way the code is compiled, as old autotools are now quite deprecated. As I was learning CMake, the CMakeLists.txt are not very clean, especially as target dependencies do not seems to be carried over correctly when using emscripten: I had to repeat the SDL library dependency on multiple targets even though it should be inherited and works well when using normal g++-based compilation.

Then I noticed a number of badly programmed parts that had to be corrected. I removed the way to write logs to a file so that it would be displayed in the web console (that’s slow, and currently it is compiled in debug mode so the log is very verbose).

I added in CMakeLists.txt

if( ${CMAKE_SYSTEM_NAME} MATCHES “Emscripten”)

set(USE_FLAGS “-s USE_SDL=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 -s SDL2_IMAGE_FORMATS='[\”xpm\”]’ -sALLOW_MEMORY_GROWTH –embed-file ../images”)

set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${USE_FLAGS})

set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} ${USE_FLAGS})
set(CMAKE_EXECUTABLE_SUFFIX .html)

else()

find_package(SDL2 REQUIRED)

find_package(SDL2_image REQUIRED)

find_package(SDL2_ttf REQUIRED)

endif()

What is important there is that SFourmi uses SDL SDL-image and SDL-TTF. For SDL-image, there was no png format at the time to load the background and sprites, so everything was stored in XPM non-compressed format because this format can be just included in a C++ file, so you get a variable containing the image data and you don’t need to distribute the image file with the software as it is embedded in it.

Nowadays we should use PNG to reduce the size of the file and use SDL-image’s PNG support to use it.

However, I tried to have it work as it is, so I added -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s USE_SDL_TTF=2 flags, but I never saw anything.

Not being sure what was wrong, I followed different examples of using SDL2 with emscripten. Some of those example explain that you have to modify the main function of the program, some said it was not necessary. I finally modified main function with #ifdef for EMSCRIPTEN, but that did not solve the problem.

There were still two main issues: bad error condition handling in the code when not finding a font to load or failing to read the main image. I added error handling code, and saw that the image was not loaded. How could it be, it was embedded as XPM in the source code ! In fact you have to add another flag when using SDL-image to declare the file formats you are using, otherwise it will just fail to load images without any error message. -s SDL2_IMAGE_FORMATS='[\”xpm\”]’ was the flag to add !

Unfortunately, SFourmi also needs a font file to display text, and it is loaded from a directory. But that cannot work from the web browser, so you need to create a virtual filesystem containing all files that will be accessible from the software, in this case the images directory, and use relative paths. Fortunately there is just another flag to add: –embed-file ../images

Looking in the web console, I saw another error about lacking memory, with another flag to use to solve the problem: -sALLOW_MEMORY_GROWTH

And finally it worked !

Todo list

  • Cleanup CMake files and Emscripten flags
  • Use PNG images to compress the huge XPM file
    Unfortunately it seems that just adding png to the list of formats in the SDL2_IMAGE_FORMATS flag does not work, SFourmi just shows a black screen again. Maybe it needs to manually add libpng flags to the build ?
  • Cleanup which keys do what, allow parameters other than default map (used to load an ini file, should find a way to provide simulation parameters – e.g. terrain size, number of ants and families)
  • Display on the compiled SFourmi.html web page the usage instructions and remove Emscripten huge logo.
  • Add a CMake install target so all required files go into one clean directory.

 

 

This entry was posted in software project and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*