-
Notifications
You must be signed in to change notification settings - Fork 89
Web support #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Web support #94
Conversation
|
I'll try to keep an eye on it over the weekend |
|
Hello! I just tested it on Windows and it seems to work fine. It doesn't seem to work with MSVC but it worked with MinGW (GCC).
Tell me when you finish. |
|
I'm done on my end! |
|
Could you please add an option to compile the examples with all their dependencies in one file per example/app. This way the user program does not need a server. I think is the flag -sSINGLE_FILE. |
|
Done. |
|
Wow, thank you! |
This commit adds web support to minifb through emscripten. See #93
CMake build changes
The CMake build has been modified in the following way:
SrcWebwas added. It contains the web backend (WebMiniFB.c)UNIX. Sections of the build targetingUNIXhad to be modified, e.g. to not add theUSE_OPENGL_APIoption when building for the web.CMakeLists.txtto their build.web_assetsis created, which copies all files fromtests/webto the output folder. The folder contains.htmlfiles which load the generated.js/.wasmfiles, setup a canvas for rendering, and execute the test app'smain()function. It also adds the target as a dependency to the test targets, and sets an additional linker option for each test target. The linker option specifies the module name with which the compiled minifb app can be instantiated in JavaScript.New backend features and limitations
A new backend was added in
src/web/WebMiniFB.c. It can run all tests of minifb, including the multi-window and input tests, both in dekstop and mobile browsers.The
mfb_open_ex()function expects that a HTMLcanvaselement with an id equal to the specifiedtitleexists. If no such canvas exists in the DOM,mfb_open_ex()will return an error code.Keyboard, mouse and touch input are supported. However, only a single touch will be processed, as the minifb API currently does not provide a way to deal with multi-touch. Touche events are thus interpreted as mouse events. The only supported button on the web is the left mouse button.
The web backend is using emscripten's Asyncify feature. It allows to run synchronous native code, like the minifb tests without modification. However, a minifb app on the web must still yield to the browser so DOM events can be processed. A minifb app on the web must thus periodically call
mfb_wait_sync(), which will hand control back to the browser for a short time. This "yielding" is implemented usingrequestAnimationFrame(), so it is vsynched and as high performance as it can be.The web backend also implements the timer api using
performance.now(). Note that this is not a high precision timer and fudges things by 2ms to due to a Spectre mitigation. It is usually good enough for real-time apps.The web backend blits the buffer passed to
mfb_update_ex()to the canvas associated with the window by converting the buffer to anImageDatainstance, then callingContext2D.putImageData()to draw the buffer to the canvas. The canvas' backing buffer always has the size of the buffer provided tomfb_update_ex(). If the CSS size of the canvas is different, the browser engine will automatically up or downscale the backing buffer. To keep scaled display as pixel accurate as possible,mfb_open_ex()will set the CSS propertyimage-renderingtopixelatedon the canvas.When blitting the user provided buffer to the canvas via
putImageData(), the alpha channel of each pixel will be interpreted and the data will actually be blended with the current canvas backing buffer data. It is thus necessary to always set the alpha channel of pixels in the buffer passed tomfb_update_ex()The web backend currently does not support
mfb_set_viewport().Test changes
The changes are using the new
MFB_ARGBmacro instead ofMFB_RGBso each pixel receives an alpha value as well.Building for and running in the browser
To build for the web, specify the emscripten toolchain location:
The
buildfolder will then contain.js,.wasm, and.htmlfiles for each test, as well as aindex.htmlfile that links to all the test.htmlfiles for faster navigation between tests.The tests can then be viewed in the browser by serving the contents of the
buildfile via a HTTP server. E.g. using Python:Open http://localhost:8000 in the browser to check out the test apps.
Example usage
Here's a simple project that illustrates how to setup the CMake build for a project using minifb:
https://github.com/badlogic/r96/blob/main/CMakeLists.txt
I've also uploaded the minifb tests for web here: Submitted a pull request to minifb for my web backend:
https://marioslab.io/dump/minifb/