From 96a7301dc3bcb1c4e5b219ef4f9c728c2b094eae Mon Sep 17 00:00:00 2001
From: FreeArtMan <dos21h@gmail.com>
Date: Sat, 12 May 2018 22:48:23 +0100
Subject: Added example of SDL for webassembly

---
 md/writeup/web_assembly_sdl_example.md | 208 +++++++++++++++++++++++++++++++++
 1 file changed, 208 insertions(+)
 create mode 100644 md/writeup/web_assembly_sdl_example.md

(limited to 'md/writeup')

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
-- 
cgit v1.2.3