diff options
author | FreeArtMan <dos21h@gmail.com> | 2018-05-12 22:48:23 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2018-05-12 22:48:23 +0100 |
commit | 96a7301dc3bcb1c4e5b219ef4f9c728c2b094eae (patch) | |
tree | a929ed40075e30db1e051b2b1bcaae3c7d773db3 /md/writeup | |
parent | be97234d48b77b022748a0e4ea36057be3e78fe3 (diff) | |
download | md-content-96a7301dc3bcb1c4e5b219ef4f9c728c2b094eae.tar.gz md-content-96a7301dc3bcb1c4e5b219ef4f9c728c2b094eae.zip |
Added example of SDL for webassembly
Diffstat (limited to 'md/writeup')
-rw-r--r-- | md/writeup/web_assembly_sdl_example.md | 208 |
1 files changed, 208 insertions, 0 deletions
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 <emscripten/emscripten.h> +``` + +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 <stdio.h> +#include <stdlib.h> + +#if __EMSCRIPTEN__ +#include <emscripten/emscripten.h> +#include <SDL2/SDL.h> +#include <SDL/SDL_ttf.h> +#else +#include <SDL2/SDL.h> +#include <SDL2/SDL_ttf.h> +#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 +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + </head> + <body> + <script type='text/javascript'> + var Module = {}; + fetch('index.wasm') + .then(response => + response.arrayBuffer() + ).then(buffer => { + Module.canvas = document.getElementById("canvas"); + Module.wasmBinary = buffer; + var script = document.createElement('script'); + script.src = "index.js"; + script.onload = function() { + console.log("Emscripten boilerplate loaded.") + } + document.body.appendChild(script); + }); + </script> + <canvas id="canvas" style="width:100%; height:100%"></canvas> + + </body> +</html> +``` + +```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 |