From 96a7301dc3bcb1c4e5b219ef4f9c728c2b094eae Mon Sep 17 00:00:00 2001 From: FreeArtMan Date: Sat, 12 May 2018 22:48:23 +0100 Subject: Added example of SDL for webassembly --- md/writeup.md | 2 +- md/writeup/web_assembly_sdl_example.md | 208 +++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 md/writeup/web_assembly_sdl_example.md diff --git a/md/writeup.md b/md/writeup.md index 73f5124..ff0ead0 100644 --- a/md/writeup.md +++ b/md/writeup.md @@ -21,7 +21,7 @@ title: Writeup page [C macro tricks](writeup/c_macro_tricks.md) [STM32F4 SDRAM configuration](writeup/stm32f4_sdram_configuration.md) - +[WebAssembly SDL example](writeup/web_assembly_sdl_example.md) ## Projects diff --git a/md/writeup/web_assembly_sdl_example.md b/md/writeup/web_assembly_sdl_example.md new file mode 100644 index 0000000..c6f475b --- /dev/null +++ b/md/writeup/web_assembly_sdl_example.md @@ -0,0 +1,208 @@ +title: WebAssembly SDL example +keywords:c,webassembly,js,SDL + +# WebAssembly SDL example + +## Intro + +There is many examples of how to compile SDL for webassembly, but many of them isnt +minimal as necessary, so here tried to make just bare minimum for application +that can be compiled for 2 targets webassembly and pc. + +## How things works + +Webassembly is virtual machine that you can run in your browser, it allows you to run compiled code. +Its not 100% like real pc virtual machine and more oriented on web. But its close enough to just +port and run you C/C++ or any other language that supports LLVM as backend. + +There need to be included emscripten header that gives callback for javascript to be runned. + +```c +#include +``` + +And as all this going to be compiled to webassembly byte code then you can _just_ load compiled file. +There is many ways how wasm bytecode going to be runned. We registed our code so its runes specified +number of frames per second. Check functions docs for better description. + +```c +void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop) +``` + +Porting requiring to define loop that will be registered for webassembly engine and thats all. +There need to be covered more things if there is need to use some fonts,images or files. But for +now its minimal example that will draw SDL window in your browser ;] + +## Source + + + +```c +#include +#include + +#if __EMSCRIPTEN__ +#include +#include +#include +#else +#include +#include +#endif + +#define SCREEN_WIDTH 200 +#define SCREEN_HEIGHT 200 + +SDL_Window *window = NULL; +SDL_Surface *screen = NULL; +SDL_Surface *blank = NULL; + +#define MAX(a,b) ((a) > (b) ? a : b) +#define MIN(a,b) ((a) < (b) ? a : b) + +void render() +{ + SDL_Rect r_scr; + r_scr.x = 10; + r_scr.y = 20; + r_scr.w = 10; + r_scr.h = 10; + SDL_Rect r_im; + r_im.x = 0; + r_im.y = 0; + r_im.w = 16; + r_im.h = 16; + SDL_BlitSurface(blank, NULL, screen, &r_scr); +} + +#if __EMSCRIPTEN__ +void main_tick() { +#else +int main_tick() { +#endif + + SDL_UpdateWindowSurface(window); + + + #if !__EMSCRIPTEN__ + return 1; + #endif +} + +void main_loop() +{ + + + +#if __EMSCRIPTEN__ + emscripten_set_main_loop(main_tick, -1, 1); +#else + int quit = 0; + SDL_Event event; + + + while (quit==0) + { + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + quit = 1; + break; + } + quit = main_tick(); + } + printf("Loop\n"); + } +#endif +} + +int main() +{ + SDL_Init(SDL_INIT_VIDEO); + + window = SDL_CreateWindow( + "WEBASM", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + SCREEN_WIDTH, SCREEN_HEIGHT, + SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); + screen = SDL_GetWindowSurface(window); + SDL_GL_SetSwapInterval(1); + + blank = SDL_CreateRGBSurface(0, 16, 16, 32, 0, 255, 255, 50); + Uint32 color = SDL_MapRGB(blank->format, 50, 0 , 0); + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + Uint32 *bufp; + bufp = (Uint32 *)blank->pixels + y*blank->pitch/4 + x; + *bufp = color; + } + } + + main_loop(); + + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} +``` + + +```js + + + + + + + + + + + +``` + +```makefile +CC=gcc +CFALGS= +LDFLAGS=-lSDL2 -lSDL2_ttf + +EM_ENV=LLVM=/usr/bin NODE_JS=node EMSCRIPTEN_ROOT=/usr/lib/emscripten +EM_CC=emcc +EM_CFLAGS=-s WASM=1 -O3 +EM_LDFALGS=-s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' -s USE_SDL_TTF=2 + +pc: + $(CC) $(CFLAGS) $(LDFLAGS) main.c -o main + +em: + $(EM_CC) main.c $(EM_CFLAGS) $(EM_LDFALGS) -o index.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' +``` + +## Links + +1. https://wiki.libsdl.org/CategoryAPI +2. https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm +3. https://github.com/kvark/wasm-triangle/blob/master/src/main.rs +4. https://github.com/belen-albeza/space-shooter-wasm/blob/master/src/main.c +5. https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html \ No newline at end of file -- cgit v1.2.3