SDL2 / Desktop Bridge / Emscripten Questions

Hi,

We’ve been away from SDL for some time.
We may now update our SDL2 video game called “LettersFall 5”.
(game uses: SDL2, SDL2_Image, SDL2_Mixer, & SDL2_TTF and is 100% cross-platform)

We have some technical questions:
(1) Does SDL2 work with Microsoft’s new “Desktop Bridge”?
https://developer.microsoft.com/en-us/windows/bridges/desktop
(Desktop Bridge converts a Windows desktop application to a Windows 10 Store application)

(2) Does SDL2 work with current Emscripten?
https://github.com/kripken/emscripten
(Emscripten converts a desktop application to a web application)
*How do we tell SDL2 to use OpenGL so Emscripten will build web application with WebGL?

Thanks in advance!

JeZxLee
16BitSoft Inc.
Video Game Design Studio
www.16BitSoft.com

I’m developing a game that is using SDL2 and SDL2_image that works on emscripten. I haven’t used SDL2_mixer or SDL2_TTF so I can’t help with those.

You may need some modifications to your program to work on emscripten. At least:

  • Threads are not supported (at least not yet I think)
  • Networking. Can’t use normal sockets
  • Possible filesystem issues
  • Emscripten should be able to emulate OpenGL and Open GL ES functionality on WebGL, but could be that not everything is supported
  • You cannot just loop and draw frames in your program. Instead you need to give a callback to emscripten that will be called each frame. You can check my simple example for more details: https://github.com/suikki/simpleSDL

The simple example project is using cmake to build for emscripten too. It has .cmd file to build on windows but it should work manually on linux/mac by running something like this in the project dir (emsdk must be in path or just give full path to it):

mkdir build
cd build
emsdk activate latest
emcmake cmake -D CMAKE_BUILD_TYPE:STRING=Debug ..
emmake make

Another issue is that most browsers don’t allow doing some javascript stuff when opening a local .html file. To test the my app without uploading to an actual server I use this command on my chrome (on windows, but same options should work on other platforms too):

"c:\Program Files (x86)\Google\Chrome\Application\chrome.exe"  --allow-file-access-from-files --user-data-dir=c:\tmp\chrome_debug file:///the/html/file/to/open.html

It’s also using a separate data dir so you can delete it easily to clear all caching and it’s not messing around with you normal browsing

I can’t share my actual project, but here are some cmake snippets to help you out to get more complicated stuff working:

if(EMSCRIPTEN)
  # Make emscripten output a html page instead of just the javascript (for easier testing).
  set(CMAKE_EXECUTABLE_SUFFIX ".html")

  # This should make it easier to debug runtime problems on the browser.
  if(CMAKE_BUILD_TYPE MATCHES Debug)
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ASSERTIONS=2 -s DEMANGLE_SUPPORT=1")
  endif()

  # Using c++11, SDL2 and SDL_image. Also using OPENGL_ES 2 emulation.
  # See https://kripken.github.io/emscripten-site/docs/porting/multimedia_and_graphics/OpenGL-support.html for more options
  # I haven't fiddled around with this for a while and I'm not sure if all of this is actually necessary
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_SDL=2 -s USE_SDL_IMAGE=2 -std=c++11")
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_SDL=2 -s USE_SDL_IMAGE=2")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s FULL_ES2=1")


  #
  # Embedding asset files etc. to the javascript output:
  #

  #  "For SDL2_image in order to be useful, you need to specify the image formats you are planning on using with -s SDL2_IMAGE_FORMATS='["png"]'. This will also ensure that IMG_Init works properly. Alternatively, you can specify 'emcc --use-preload-plugins' but then you calls to IMG_Init will fail."
  # See https://github.com/kripken/emscripten/pull/3831 fro more info
  #
  # Had some issues with this not sure if it works yet. see https://github.com/emscripten-ports/SDL2_image/issues/4
  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s SDL2_IMAGE_FORMATS='[\"png\",\"jpg\"]'")
  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --use-preload-plugins")

  # This maps a dir called data in my build hierarchy to a virtual dir called data embedded in the final javascript output.
  # Add more of these and modify the paths as necessary
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --preload-file ../../../dist/data@data")

  # Another option you can try if having trouble with loading images:
  # https://groups.google.com/forum/#!topic/emscripten-discuss/0qxtF7zyG0s
  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s STB_IMAGE=1")

  # Might need to play around with this if emscripten gives errors saying your program is too big.
  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_MEMORY=67108864")
endif()

Hi,

Thanks for the reply.
Emscripten looks much more complicated than we had realized, we will put it aside for now.
Anyone try new Microsoft “Desktop Bridge” to convert SDL2 Windows desktop app to Windows 10 Store app?
Windows 10 Store is the future of Windows application distribution which is why we have interest in it.
Thanks!

JeZxLee

I forgot to mention that the example github project I linked is compiling SDL from source. It’s probably better to just use the USE_SDL=2 option instead (like in the cmake snippet above). That way SDL should work pretty much out of the box.

Fwiw, Emscripten was easier than I expected to port to; the biggest stumbling block was that your main loop has to become a function that Emscripten calls once per frame and you can’t ever block and read the event queue because that function has to return before more events will fire or your rendering will get to the screen.

In practice, most games end up with a small ifdef to handle this and it’s not a big deal, but depending on your game it can be a huge redesign problem.

It’s worth noting that Emscripten has a built-in reimplementation of SDL 1.2 (written in pure JavaScript!), but SDL 2 (the same C library used everywhere else) can be compiled with Emscripten and has a backend for that platform. If you don’t link with this, Emscripten will think you wanted its 1.2 implementation, and things will fail.

Hi,

Thanks for the info.
SDL2 with Emscripten will take some time so we will put it aside for now.
Our SDL2 C++ main loop is the following:
//-MAIN-LOOP------------------------------------------------------------------------
printf(“Main loop started…\n”);
while (visuals->CoreFailure != true && input->EXIT_Game != true)
{
input->GetAllUserInput();
visuals->CalculateFramerate();
screens->ProcessScreenToDisplay();
visuals->ProcessFramerate();
}
printf("…Main loop exited\n");
//------------------------------------------------------------------------MAIN-LOOP-

We are REALLY interested in submitting SDL2 games to the Windows 10 Store.
(with the use of new Microsoft “Desktop Bridge” conversion software)
If we have any issues with the conversion then we will report them back here.
Thanks!

JeZxLee

Out of curiosity - if you are using SDL2 already, you could directly create
a UWP app for publishing in the store. Any reason why you want to use the
Desktop Bridge instead?

---------- Původní e-mail ----------
Od: Jesse Palser noreply@discourse.libsdl.org
Komu: hardcoredaniel@seznam.cz
Datum: 17. 6. 2017 5:19:12
Předmět: Re: [SDL] SDL2 / Desktop Bridge / Emscripten Questions
"

 JeZxLee(https://discourse.libsdl.org/u/jezxlee) 

June 17

Hi,

Thanks for the info.
SDL2 with Emscripten will take some time so we will put it aside for now.
Our SDL2 C++ main loop is the following:
//-MAIN-LOOP----------------------------------------------------------------

Hi,

Creating UWP application would require us to use icky MSVS 17 Community which we want to avoid.
We highly prefer using current free Code:Blocks C++ IDE on Windows.
(we’ve had problems getting MSVS compiled source code to compile on Linux so we dumped MSVS)
Seems like “Desktop Bridge” might be the preferred method to make Windows 10 Store SDL2 application.
We have submitted “Advanced Installer” made *.MSI install file to Microsoft for approval to use Desktop Bridge.
Thanks!

JeZxLee

Our SDL2 C++ main loop is the following:

(if you aren’t interested in Emscripten right now, this might be interesting to you later, or someone else might find it on Google, etc.)

So if I were to rework this for Emscripten, it would look something like this (untested!)…

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

// this function runs once per frame, returns true if game should keep running the mainloop.
static bool mainloopIteration(void)
{
    if (visuals->CoreFailure == true || input->EXIT_Game == true) {
        return false;  // stop now.
    }

    input->GetAllUserInput();
    visuals->CalculateFramerate();
    screens->ProcessScreenToDisplay();
    visuals->ProcessFramerate();

    return true;  // keep going.
}

#ifdef __EMSCRIPTEN__
// calls mainloop, terminates if appropriate.
static void emscriptenMainloop(void)
{
     // strictly speaking, maybe you don't have to cancel the main loop, as maybe
     // the Emscripten port doesn't have a "quit" option on the main menu or whatever,
     // and the user "quits" by closing the browser tab. But you can terminate like this
     // and it's more or less like calling exit().
     if (!mainloopIteration()) {
        printf("...Main loop exited\n");
        emscripten_cancel_main_loop();  // this should "kill" the app.
     }
}
#endif

//-MAIN-LOOP------------------------------------------------------------------------
printf("Main loop started...\n");
#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(emscriptenMainloop, 0, 1);
    // This will now continue on until main() or whatever returns, and then 
    //  call emscriptenMainloop 60 times a second. Do this right at the end of main(), and 
    //  DON'T call SDL_Quit(), etc, on your way out the door!
    return 0;  // just return now to prevent confusion.
#else
    while (mainloopIteration()) { /* spin */ }
    printf("...Main loop exited\n");
    // shutdown things here, call SDL_Quit(), etc.
#endif
//------------------------------------------------------------------------MAIN-LOOP-

…which is basically your mainloop’s body split out into a function, and some basic glue code for Emscripten/everything else.

Hi,

you can avoid using Visual Studio (I still use 2015 but maybe its not too
different from 2017) for development, and just use a command line to build
the final UWP app for upload to the store. This way you’ll never need to use
the IDE.

I can send you the command line that I use for building with Jenkins if you
want. It’s a rather long line with many options, but includes building for
32 and 64 bit intel + 32 bit arm plus signing plus debugging info plus
building the final .appxupload package for the store.

Regards,

Daniel

---------- Původní e-mail ----------
Od: Jesse Palser noreply@discourse.libsdl.org
Komu: hardcoredaniel@seznam.cz
Datum: 17. 6. 2017 15:36:43
Předmět: Re: [SDL] SDL2 / Desktop Bridge / Emscripten Questions
"

 JeZxLee(https://discourse.libsdl.org/u/jezxlee) 

June 17

Hi,

Creating UWP application would require us to use icky MSVS 17 Community
which we want to avoid.
We highly prefer using current free Code:Blocks C++ IDE on Windows.
(we’ve had problems getting MSVS compiled source code to compile on Linux so
we dumped MSVS)
Seems like “Desktop Bridge” might be the preferred method to make Windows 10
Store SDL2 application.
We have submitted “Advanced Installer” made *.MSI install file to Microsoft
for approval to use Desktop Bridge.
Thanks!

JeZxLee