mirror of
https://github.com/minetest/irrlicht.git
synced 2025-06-28 14:26:06 +02:00
Merging r5975 through r6036 from trunk to ogl-es branch.
GLES drivers adapted, but only did make compile-tests. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
98
examples/01.HelloWorld_emscripten/Makefile
Normal file
98
examples/01.HelloWorld_emscripten/Makefile
Normal file
@ -0,0 +1,98 @@
|
||||
# Makefile for Irrlicht Examples
|
||||
# It's usually sufficient to change just the target name and source file list
|
||||
# and be sure that CXX is set to a valid compiler
|
||||
|
||||
# Name of the executable created (.exe will be added automatically if necessary)
|
||||
Target := 01.HelloEmscripten
|
||||
# List of source files, separated by spaces
|
||||
Sources := main.cpp
|
||||
# Path to Irrlicht directory, should contain include/ and lib/
|
||||
IrrlichtHome := ../..
|
||||
# Path for the executable. Note that Irrlicht.dll should usually also be there for win32 systems
|
||||
BinPath = ../../bin/$(SYSTEM)
|
||||
|
||||
all_emscripten: EMSCRIPTEN=1
|
||||
|
||||
# general compiler settings (might need to be set when compiling the lib, too)
|
||||
CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include
|
||||
ifndef NDEBUG
|
||||
ifdef EMSCRIPTEN
|
||||
LDFLAGS += -s DEMANGLE_SUPPORT=1
|
||||
endif
|
||||
CXXFLAGS += -g -Wall
|
||||
else
|
||||
ifdef EMSCRIPTEN
|
||||
LDFLAGS += -O3
|
||||
endif
|
||||
CXXFLAGS += -O3
|
||||
endif
|
||||
ifdef EMSCRIPTEN
|
||||
CXXFLAGS += -std=gnu++11 -U__STRICT_ANSI__
|
||||
endif
|
||||
|
||||
ifdef EMSCRIPTEN
|
||||
all: all_emscripten
|
||||
else
|
||||
all: all_linux
|
||||
endif
|
||||
|
||||
# target specific settings
|
||||
all_linux all_emscripten all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
|
||||
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lEGL
|
||||
ifndef EMSCRIPTEN
|
||||
LDFLAGS += -lGLESv1_CM -lGLESv2 -lXxf86vm -lXext -lX11 -lXcursor
|
||||
endif
|
||||
all_linux clean_linux: SYSTEM=Linux
|
||||
all_emscripten clean_emscripten: SYSTEM=emscripten
|
||||
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
|
||||
all_win32 clean_win32 static_win32: SUF=.exe
|
||||
all_emscripten clean_emscripten: SUF=.html
|
||||
all_emscripten: CXXFLAGS += -fno-exceptions -fno-rtti -fstrict-aliasing -std=gnu++11 -U__STRICT_ANSI__
|
||||
# Pass on a custom html file.
|
||||
#all_emscripten: CXXFLAGS += --shell-file shell_minimal.html
|
||||
all_emscripten: LDFLAGS += -lGL -lSDL --preload-file ../../media@/media -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1
|
||||
#If you know the maximum memory (in bytes) which your application need then set it. It can speed things up a lot.
|
||||
#all_emscripten: LDFLAGS += -s TOTAL_MEMORY=268435456
|
||||
# You need the FULL_ES2 when using EDT_OGLES2 driver
|
||||
#all_emscripten: LDFLAGS += -s FULL_ES2=1
|
||||
static_win32: CPPFLAGS += -D_IRR_STATIC_LIB_
|
||||
all_win32: LDFLAGS += -lopengl32 -lEGL -lGLESv1_CM -lGLESv2 -lm
|
||||
static_win32: LDFLAGS += -lgdi32 -lwinspool -lcomdlg32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lopengl32 -lEGL -lGLESv1_CM -lGLESv2
|
||||
# name of the binary - only valid for targets which set SYSTEM
|
||||
DESTPATH = $(BinPath)/$(Target)$(SUF)
|
||||
|
||||
# Enable compiling to WASM and not just asm.js (you have to set it in the engine Makefile as well)
|
||||
ifdef EMSCRIPTEN
|
||||
ifdef WASM
|
||||
CXXFLAGS += -s WASM=1
|
||||
endif
|
||||
endif
|
||||
|
||||
emscripten: all_emscripten
|
||||
|
||||
all_linux all_win32 all_emscripten static_win32:
|
||||
$(warning Building...)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS)
|
||||
|
||||
clean: clean_linux clean_win32 clean_emscripten
|
||||
$(warning Cleaning...)
|
||||
|
||||
clean_linux clean_win32:
|
||||
@$(RM) $(DESTPATH)
|
||||
|
||||
clean_emscripten:
|
||||
@$(RM) $(BinPath)/$(Target).data
|
||||
@$(RM) $(BinPath)/$(Target).html*
|
||||
@$(RM) $(BinPath)/$(Target).js
|
||||
|
||||
|
||||
.PHONY: all all_win32 all_emscripten static_win32 clean clean_linux clean_win32 clean_emscripten
|
||||
|
||||
#multilib handling
|
||||
ifeq ($(HOSTTYPE), x86_64)
|
||||
LIBSELECT=64
|
||||
endif
|
||||
#solaris real-time features
|
||||
ifeq ($(HOSTTYPE), sun4)
|
||||
LDFLAGS += -lrt
|
||||
endif
|
240
examples/01.HelloWorld_emscripten/main.cpp
Normal file
240
examples/01.HelloWorld_emscripten/main.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
/** Example 001 HelloWorld adapted to emscripten
|
||||
|
||||
This Tutorial shows how to run code with emscripten.
|
||||
Emscripten compiles c++ to asm.js to allow it running inside a webbrowser.
|
||||
You have to setup the emscripten environment on your system first to use this.
|
||||
*/
|
||||
#include <irrlicht.h>
|
||||
#include "exampleHelper.h"
|
||||
#include <emscripten.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
The code in here is mostly similar to the usual HelloWorld.
|
||||
You can find more information about it there. Here we mainly document the
|
||||
differences needed for emscripten.
|
||||
*/
|
||||
|
||||
using namespace irr;
|
||||
using namespace core;
|
||||
using namespace scene;
|
||||
using namespace video;
|
||||
using namespace io;
|
||||
using namespace gui;
|
||||
|
||||
/*
|
||||
This part not necessary for emscripten, only useful to keep it in
|
||||
in case you want to run the same code on Windows with VS as well.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "Irrlicht.lib")
|
||||
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Variables on the stack will stay intact between runs of one_iter()
|
||||
*/
|
||||
IrrlichtDevice *device = 0;
|
||||
IVideoDriver* driver = 0;
|
||||
ISceneManager* smgr = 0;
|
||||
IGUIEnvironment* guienv = 0;
|
||||
|
||||
ICameraSceneNode* camera = 0;
|
||||
dimension2d<u32> screenSize(640, 480);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
/*
|
||||
Handle changes in canvas size which are done with html/js.
|
||||
Note that it's only OK for windowed so far,
|
||||
the switch to fullscreen not yet working.
|
||||
Also the emscripten_get_canvas_size might cause a slow-down
|
||||
(but haven't found yet a way to avoid it with SDL1).
|
||||
*/
|
||||
void checkCanvasResize()
|
||||
{
|
||||
int w, h, fs;
|
||||
emscripten_get_canvas_size(&w, &h, &fs);
|
||||
const core::dimension2d<u32> canvasDim(w,h);
|
||||
if ( canvasDim != screenSize )
|
||||
{
|
||||
screenSize = canvasDim;
|
||||
driver->OnResize(canvasDim);
|
||||
driver->setViewPort(irr::core::rect<irr::s32>(0,0,w,h));
|
||||
|
||||
irr::f32 aspect = (irr::f32)w / (irr::f32)h;
|
||||
camera->setAspectRatio(aspect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
emscripten can't run things in an endless-loop or otherwise the browse will consider
|
||||
the script to hang.
|
||||
*/
|
||||
void one_iter()
|
||||
{
|
||||
if(!device->run())
|
||||
{
|
||||
// Could clean up here in theory, but not sure if it makes a difference
|
||||
|
||||
/*
|
||||
This tells emscripten to not run any further code.
|
||||
*/
|
||||
emscripten_cancel_main_loop();
|
||||
return;
|
||||
}
|
||||
|
||||
// In case you have a resizeable canvas (resized from html)
|
||||
//checkCanvasResize();
|
||||
|
||||
driver->beginScene(ECBF_COLOR | ECBF_DEPTH, SColor(255,100,101,140));
|
||||
|
||||
smgr->drawAll();
|
||||
guienv->drawAll();
|
||||
|
||||
driver->endScene();
|
||||
}
|
||||
#endif //__EMSCRIPTEN__
|
||||
|
||||
|
||||
/*
|
||||
The main method is also run on emscripten.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
/*
|
||||
Printing out the build date/time is very useful to find troubles with unexpected browser-caches.
|
||||
*/
|
||||
printf("Build-date: %s %s\n", __DATE__, __TIME__);
|
||||
|
||||
SIrrlichtCreationParameters parameters;
|
||||
/*
|
||||
Create device flags for emscripten are still experimental
|
||||
and might not all work.
|
||||
|
||||
- deviceType: You can to use EDT_OGLES2 or EDT_WEBGL1 on emscripten.
|
||||
EDT_WEBGL1 is better optimized but does not yet support all options.
|
||||
EDT_OGLES2 needs -s FULL_ES2=1 as linker flag in the Makefile.
|
||||
*/
|
||||
#ifndef __EMSCRIPTEN__
|
||||
parameters.DriverType = EDT_OGLES2;
|
||||
#else //__EMSCRIPTEN__
|
||||
parameters.DriverType = EDT_WEBGL1;
|
||||
#endif //__EMSCRIPTEN__
|
||||
|
||||
parameters.LoggingLevel = ELL_DEBUG;
|
||||
parameters.WindowSize = screenSize;
|
||||
parameters.Stencilbuffer = false;
|
||||
parameters.AntiAlias = 4;
|
||||
|
||||
device = createDeviceEx(parameters);
|
||||
|
||||
if (!device)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
Window caption will set the title-text in the browser.
|
||||
*/
|
||||
device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
|
||||
|
||||
/*
|
||||
Get a pointer to the VideoDriver, the SceneManager and the graphical
|
||||
user interface environment, so that we do not always have to write
|
||||
device->getVideoDriver(), device->getSceneManager(), or
|
||||
device->getGUIEnvironment().
|
||||
*/
|
||||
driver = device->getVideoDriver();
|
||||
smgr = device->getSceneManager();
|
||||
guienv = device->getGUIEnvironment();
|
||||
|
||||
/*
|
||||
We add a hello world label to the window, using the GUI environment.
|
||||
The text is placed at the position (10,10) as top left corner and
|
||||
(260,22) as lower right corner.
|
||||
*/
|
||||
guienv->addStaticText(L"Hello World! This is Irrlicht on emscripten!",
|
||||
rect<s32>(10,10,260,22), true);
|
||||
|
||||
/*
|
||||
Get a media path dedicated for your platform.
|
||||
We tell emscripten to copy the media folder in the Makefile with:
|
||||
"--preload-file ../../media@/media"
|
||||
That copies our ../../media folder in a .data
|
||||
file which is loaded by the browser. It can then be accessed there
|
||||
by "/media" name (that's the parameter after the '@').
|
||||
Note that usually you would try to copy only as many files
|
||||
as absolutely necessary to reduce start-up times.
|
||||
*/
|
||||
const io::path mediaPath = getExampleMediaPath();
|
||||
|
||||
/*
|
||||
Make a model called Sydney show up.
|
||||
*/
|
||||
IAnimatedMesh* mesh = smgr->getMesh(mediaPath + "sydney.md2");
|
||||
if (!mesh)
|
||||
{
|
||||
device->drop();
|
||||
return 1;
|
||||
}
|
||||
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
|
||||
|
||||
/*
|
||||
Disable lighting because we do not have a dynamic light in here, and
|
||||
the mesh would be totally black otherwise.
|
||||
Set the frame loop such that the predefined STAND animation is used.
|
||||
Add a texture to the model.
|
||||
*/
|
||||
if (node)
|
||||
{
|
||||
node->setMaterialFlag(EMF_LIGHTING, false);
|
||||
node->setMD2Animation(scene::EMAT_STAND);
|
||||
node->setMaterialTexture( 0, driver->getTexture(mediaPath + "sydney.bmp") );
|
||||
}
|
||||
|
||||
/*
|
||||
To look at the mesh, we place a camera into 3d space at the position
|
||||
(0, 30, -40). The camera looks from there to (0,5,0), which is
|
||||
approximately the place where our md2 model is.
|
||||
*/
|
||||
camera = smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
|
||||
|
||||
#ifndef __EMSCRIPTEN__ // this part only so you can run the same code on desktop
|
||||
/*
|
||||
On desktop we run and endless loop until the user closes the window or
|
||||
presses ALT+F4 (or whatever keycode closes a window).
|
||||
*/
|
||||
while(device->run())
|
||||
{
|
||||
driver->beginScene(ECBF_COLOR | ECBF_DEPTH, SColor(255,100,101,140));
|
||||
|
||||
smgr->drawAll();
|
||||
guienv->drawAll();
|
||||
|
||||
driver->endScene();
|
||||
}
|
||||
device->drop();
|
||||
|
||||
#else // __EMSCRIPTEN__
|
||||
|
||||
/*
|
||||
Setting fps to 0 or a negative value will use the browser’s
|
||||
requestAnimationFrame mechanism to call the main loop function.
|
||||
Emscripten documentation recommends to do that, but you can also set
|
||||
another fps value and the browser will try to call the main-loop
|
||||
fps times per second.
|
||||
The simulate_infinite_loop tells emscripten that this is an application
|
||||
which will simulate an infinite loop. There is also a flag in the
|
||||
Makefile about that: -s NO_EXIT_RUNTIME=1
|
||||
*/
|
||||
int fps = 0;
|
||||
int simulate_infinite_loop = 1;
|
||||
emscripten_set_main_loop(one_iter, fps, simulate_infinite_loop);
|
||||
#endif //__EMSCRIPTEN__
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
That's it. Compile and run.
|
||||
**/
|
24
examples/01.HelloWorld_emscripten/readme.txt
Normal file
24
examples/01.HelloWorld_emscripten/readme.txt
Normal file
@ -0,0 +1,24 @@
|
||||
Emscripten is a project to compile c/c++ code int the asm.js format which can be run in some browsers.
|
||||
See http://kripken.github.io/emscripten-site for more information.
|
||||
|
||||
emscripten support for Irrlicht is a work in process. Use at your own risk.
|
||||
Might take work and knowledge to get it running.
|
||||
|
||||
------------
|
||||
REQUIREMENTS
|
||||
------------
|
||||
You have to install the emscripten environment.
|
||||
|
||||
----------------------------
|
||||
BUILDING Irrlicht & your App
|
||||
----------------------------
|
||||
|
||||
Linux:
|
||||
Go into source/Irrlicht folder and call:
|
||||
emmake make emscripten
|
||||
|
||||
|
||||
Go into examples/01.HelloWord_emscripten folder and call:
|
||||
emmake make all_emscripten
|
||||
|
||||
Note: The shell_minimal.html is currently not used (as resizing isn't working yet correctly), but can be enabled in the Makefile.
|
180
examples/01.HelloWorld_emscripten/shell_minimal.html
Normal file
180
examples/01.HelloWorld_emscripten/shell_minimal.html
Normal file
@ -0,0 +1,180 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Emscripten-Generated Code</title>
|
||||
<style>
|
||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||
textarea.emscripten { font-family: monospace; width: 80%; }
|
||||
div.emscripten { text-align: center; }
|
||||
div.emscripten_border { border: 1px solid black; }
|
||||
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||
canvas.emscripten { width: 95vw; height: 75vh; display: block; border: 0px none; background-color: black; }
|
||||
|
||||
.spinner {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin: 0px auto;
|
||||
-webkit-animation: rotation .8s linear infinite;
|
||||
-moz-animation: rotation .8s linear infinite;
|
||||
-o-animation: rotation .8s linear infinite;
|
||||
animation: rotation 0.8s linear infinite;
|
||||
border-left: 10px solid rgb(0,150,240);
|
||||
border-right: 10px solid rgb(0,150,240);
|
||||
border-bottom: 10px solid rgb(0,150,240);
|
||||
border-top: 10px solid rgb(100,0,200);
|
||||
border-radius: 100%;
|
||||
background-color: rgb(200,100,250);
|
||||
}
|
||||
@-webkit-keyframes rotation {
|
||||
from {-webkit-transform: rotate(0deg);}
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
@-moz-keyframes rotation {
|
||||
from {-moz-transform: rotate(0deg);}
|
||||
to {-moz-transform: rotate(360deg);}
|
||||
}
|
||||
@-o-keyframes rotation {
|
||||
from {-o-transform: rotate(0deg);}
|
||||
to {-o-transform: rotate(360deg);}
|
||||
}
|
||||
@keyframes rotation {
|
||||
from {transform: rotate(0deg);}
|
||||
to {transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type='text/javascript'>
|
||||
function resize(canvas) {
|
||||
// Lookup the size the browser is displaying the canvas.
|
||||
var displayWidth = canvas.clientWidth;
|
||||
var displayHeight = canvas.clientHeight;
|
||||
|
||||
// Check if the canvas is not the same size.
|
||||
if (canvas.width != displayWidth ||
|
||||
canvas.height != displayHeight) {
|
||||
|
||||
// Make the canvas the same size
|
||||
canvas.width = displayWidth;
|
||||
canvas.height = displayHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function OnResize() {
|
||||
resize( document.getElementsByTagName('canvas')[0] );
|
||||
}
|
||||
function OnLoad() {
|
||||
resize( document.getElementsByTagName('canvas')[0] );
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<body onresize="OnResize()">
|
||||
<body onload="OnLoad()">
|
||||
|
||||
<hr/>
|
||||
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
|
||||
<div class="emscripten" id="status">Downloading...</div>
|
||||
<div class="emscripten">
|
||||
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||
</div>
|
||||
<div class="emscripten_border">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="emscripten">
|
||||
<input type="checkbox" id="resize">Resize canvas
|
||||
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||
|
||||
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
|
||||
document.getElementById('resize').checked)">
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<textarea class="emscripten" id="output" rows="8"></textarea>
|
||||
<hr>
|
||||
<script type='text/javascript'>
|
||||
var statusElement = document.getElementById('status');
|
||||
var progressElement = document.getElementById('progress');
|
||||
var spinnerElement = document.getElementById('spinner');
|
||||
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {
|
||||
var element = document.getElementById('output');
|
||||
if (element) element.value = ''; // clear browser cache
|
||||
return function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
// These replacements are necessary if you render to raw HTML
|
||||
//text = text.replace(/&/g, "&");
|
||||
//text = text.replace(/</g, "<");
|
||||
//text = text.replace(/>/g, ">");
|
||||
//text = text.replace('\n', '<br>', 'g');
|
||||
console.log(text);
|
||||
if (element) {
|
||||
element.value += text + "\n";
|
||||
element.scrollTop = element.scrollHeight; // focus on bottom
|
||||
}
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
if (0) { // XXX disabled for safety typeof dump == 'function') {
|
||||
dump(text + '\n'); // fast, straight to the real console
|
||||
} else {
|
||||
console.error(text);
|
||||
}
|
||||
},
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
// application robust, you may want to override this behavior before shipping!
|
||||
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||
|
||||
return canvas;
|
||||
})(),
|
||||
setStatus: function(text) {
|
||||
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
|
||||
if (text === Module.setStatus.text) return;
|
||||
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||
var now = Date.now();
|
||||
if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
|
||||
if (m) {
|
||||
text = m[1];
|
||||
progressElement.value = parseInt(m[2])*100;
|
||||
progressElement.max = parseInt(m[4])*100;
|
||||
progressElement.hidden = false;
|
||||
spinnerElement.hidden = false;
|
||||
} else {
|
||||
progressElement.value = null;
|
||||
progressElement.max = null;
|
||||
progressElement.hidden = true;
|
||||
if (!text) spinnerElement.hidden = true;
|
||||
}
|
||||
statusElement.innerHTML = text;
|
||||
},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||
}
|
||||
};
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function() {
|
||||
Module.setStatus('Exception thrown, see JavaScript console');
|
||||
spinnerElement.style.display = 'none';
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user