summaryrefslogtreecommitdiff
path: root/md
diff options
context:
space:
mode:
Diffstat (limited to 'md')
-rw-r--r--md/writeup.md2
-rw-r--r--md/writeup/web_assembly_sdl_example.md208
2 files changed, 209 insertions, 1 deletions
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
<!--[Write hello world with stm32](writeup/hello_world_stm32.md) -->
[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 <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