Simple example of SDL in Emscripten (generating graphics from C)

It’s pretty easy to get emscripten installed. And straight forward to compile existing SDL code a simple:

emcc mycode.c -o mycode.html

Will work. However there are a few things to watch out for when working with SDL. Firstly, Emscripten currently supports SDl1.2 I don’t believe there are any plans for SDL2 support. Secondly you may need to change your code slightly. I tried my previous SDL1.2 example and it compiled and sort of worked, but pretty much hung the browser. The issue is that Emscripten doesn’t like infinite loops. In fact the correct way to work in emscripten is register a callback for screen rendering with emscripten_set_main_loop. You can set the required number of frames per second or allow the browser to decide. To use this function you also need to include emscripten.h. Here’s a version of my previous code modified to use this callback:

#include <string.h>
#include <SDL/SDL.h>
#include <iostream>
#include <emscripten.h>

using namespace std;
 
SDL_Surface *screen;

void renderloop() {
  SDL_Flip(screen);
  SDL_LockSurface(screen);
  for(int n=0;n<1000;n++) {
    int x=rand()%800;
    int y=rand()%600;
    int pixel=rand()*100000;
    int bpp = screen->format->BytesPerPixel;
    Uint8 *p = (Uint8 *)screen->pixels + y * screen->pitch + x * bpp;
    if((x>screen->w)||(y>screen->h)||(x<0)||(y<0)) return;
    *(Uint32 *)p = pixel;
  }
 
  SDL_Event event;
  while(SDL_PollEvent(&event)) {
    if(event.key.keysym.sym == SDLK_c     ) { SDL_FillRect(screen,NULL,0); }
  }
 
  SDL_UnlockSurface(screen);
  //SDL_Quit();
}

int main(int argc, char *argv[]) {

 
  if(SDL_Init(SDL_INIT_VIDEO)<0) {
    cout << "Failed SDL_Init " << SDL_GetError() << endl;
    return 1;
  }
 
  screen=SDL_SetVideoMode(800,600,32,SDL_ANYFORMAT);
  if(screen==NULL) {
    cout << "Failed SDL_SetVideoMode: " << SDL_GetError() << endl;
    SDL_Quit();
    return 1;
  }
 
  emscripten_set_main_loop(renderloop,0,0);
 
  return 0;
}

You can compile it using the command above (assuming you save it as mycode.cpp). And you should see the following output in firefox:

emscripten_graphics

Comments are closed.