Initial build scripts
This commit is contained in:
parent
7e3772891a
commit
76e2800c3c
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
minetest/
|
||||
build/
|
||||
sources/
|
||||
install/
|
||||
www/
|
30
README.md
Normal file
30
README.md
Normal file
@ -0,0 +1,30 @@
|
||||
Minetest-wasm
|
||||
=============
|
||||
|
||||
This is an experimental port of Minetest to the web using emscripten/WebAssembly.
|
||||
|
||||
|
||||
System Requirements
|
||||
-------------------
|
||||
This has only been tested on Ubuntu 20.04.
|
||||
|
||||
* Ubuntu: apt-get install -y build-essential cmake tclsh
|
||||
|
||||
Pre-requisites
|
||||
--------------
|
||||
The Emscripten SDK (emsdk) must be installed, activated, and in the PATH.
|
||||
It is assumed to be installed in $HOME/emsdk (edit `common.sh` to change this).
|
||||
|
||||
Building
|
||||
---------
|
||||
|
||||
cd minetest-wasm
|
||||
./build_all.sh
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
If the build completes successfully, the www/ directory will contain the entire application. This
|
||||
includes an `.htaccess` file which sets headers that are required (by browsers) to load the app.
|
||||
If your webserver does not recognize `.htaccess` files, you may need to set the headers in
|
||||
another way.
|
23
build_all.sh
Executable file
23
build_all.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
rm -rf build install www
|
||||
|
||||
# Emscripten comes with ports for most of these, but they don't compile
|
||||
# with pthread support. Wipe the cache and build them ourselves.
|
||||
emcc --clear-cache --clear-ports
|
||||
|
||||
# Dependencies
|
||||
./build_zlib.sh
|
||||
./build_libjpeg.sh
|
||||
./build_libpng.sh # uses zlib
|
||||
./build_libogg.sh
|
||||
./build_libvorbis.sh # uses ogg
|
||||
./build_freetype.sh # uses zlib, libpng
|
||||
./build_zstd.sh
|
||||
./build_sqlite3.sh
|
||||
./build_webshims.sh
|
||||
|
||||
# Minetest
|
||||
./pull_minetest.sh
|
||||
./build_fsroot.sh
|
||||
./build_minetest.sh
|
27
build_freetype.sh
Executable file
27
build_freetype.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -d src/freetype ]; then
|
||||
pushd sources
|
||||
git clone https://gitlab.freedesktop.org/freetype/freetype.git freetype
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf freetype
|
||||
mkdir freetype
|
||||
|
||||
pushd freetype
|
||||
|
||||
emcmake cmake \
|
||||
-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
|
||||
-DZLIB_LIBRARY="$INSTALL_DIR/lib/libz.a" \
|
||||
-DZLIB_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DPNG_LIBRARY="$INSTALL_DIR/lib/libpng.a" \
|
||||
-DPNG_PNG_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
"$SRC_DIR/freetype"
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "freetype OK"
|
54
build_fsroot.sh
Executable file
54
build_fsroot.sh
Executable file
@ -0,0 +1,54 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
# Build virtual file system
|
||||
#
|
||||
# All the files minetest needs to function correctly.
|
||||
#
|
||||
# Shaders, fonts, games, etc
|
||||
#
|
||||
# The only source for this seems to be the official distribution.
|
||||
# There must be a script to build it somewhere, but I haven't found it.
|
||||
|
||||
source common.sh
|
||||
|
||||
UPSTREAM="https://github.com/minetest/minetest/releases/download/5.5.0/minetest-5.5.0-win64.zip"
|
||||
ZIPFILE="minetest-5.5.0-win64.zip"
|
||||
ZIPDIR="minetest-5.5.0-win64"
|
||||
|
||||
if [ ! -d "$MINETEST_REPO" ] || [ ! -d "$IRRLICHT_REPO" ; then
|
||||
echo "Minetest source not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f sources/"$ZIPFILE" ]; then
|
||||
pushd sources
|
||||
wget "$UPSTREAM"
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf "$ZIPDIR"
|
||||
unzip "$SRC_DIR"/"$ZIPFILE"
|
||||
|
||||
rm -rf fsroot
|
||||
mkdir fsroot
|
||||
mv "$ZIPDIR" fsroot/minetest
|
||||
|
||||
pushd fsroot/minetest
|
||||
|
||||
# Don't need the Windows exe/dlls
|
||||
rm -rf bin
|
||||
|
||||
# Emscripten strips empty directories. But bin/ needs to be present so that
|
||||
# realpath() works on relative paths starting with bin/../
|
||||
mkdir bin
|
||||
echo "This is here to ensure bin exists" > bin/readme.txt
|
||||
|
||||
# Replace these directories with the ones from the source directory
|
||||
for I in client builtin clientmods games/devtest textures; do
|
||||
rm -rf "$I"
|
||||
cp -r "$MINETEST_REPO/$I" "$I"
|
||||
done
|
||||
|
||||
# Copy the irrlicht shaders
|
||||
cp -r "$IRRLICHT_REPO/media/Shaders" client/shaders/Irrlicht
|
24
build_libjpeg.sh
Executable file
24
build_libjpeg.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -d sources/libjpeg ]; then
|
||||
pushd sources
|
||||
git clone "https://github.com/libjpeg-turbo/libjpeg-turbo.git" libjpeg
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf libjpeg
|
||||
mkdir -p libjpeg
|
||||
|
||||
pushd libjpeg
|
||||
emcmake cmake \
|
||||
-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
|
||||
-DWITH_SIMD=0 \
|
||||
"$SRC_DIR/libjpeg"
|
||||
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "libjpeg OK"
|
30
build_libogg.sh
Executable file
30
build_libogg.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
TARNAME="libogg-1.3.5"
|
||||
TARBALL="libogg-1.3.5.tar.gz"
|
||||
|
||||
if [ ! -f sources/"$TARBALL" ]; then
|
||||
pushd sources
|
||||
wget "https://downloads.xiph.org/releases/ogg/$TARBALL"
|
||||
popd
|
||||
fi
|
||||
|
||||
if ! sha256sum sources/"$TARBALL" | grep -q 0eb4b4b9420a0f51db142ba3f9c64b333f826532dc0f48c6410ae51f4799b664; then
|
||||
echo "Wrong checksum for $TARNAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd build
|
||||
|
||||
rm -rf "$TARNAME"
|
||||
tar -zxvf "$SRC_DIR/$TARBALL"
|
||||
|
||||
pushd "$TARNAME"
|
||||
|
||||
emconfigure ./configure --disable-shared --prefix="$INSTALL_DIR"
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "libogg OK"
|
21
build_libpng.sh
Executable file
21
build_libpng.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -d sources/libpng ]; then
|
||||
pushd sources
|
||||
git clone https://git.code.sf.net/p/libpng/code libpng
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf libpng
|
||||
cp -a "$SRC_DIR/libpng" libpng
|
||||
|
||||
pushd libpng
|
||||
# For zlib
|
||||
export CPPFLAGS="-I${INSTALL_DIR}/include"
|
||||
export LDFLAGS="-L${INSTALL_DIR}/lib"
|
||||
emconfigure ./configure --disable-shared --prefix="${INSTALL_DIR}"
|
||||
emmake make
|
||||
emmake make install
|
29
build_libvorbis.sh
Executable file
29
build_libvorbis.sh
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
TARNAME="libvorbis-1.3.7"
|
||||
TARBALL="libvorbis-1.3.7.tar.gz"
|
||||
|
||||
if [ ! -f "sources/$TARBALL" ]; then
|
||||
pushd sources
|
||||
wget "https://downloads.xiph.org/releases/vorbis/$TARBALL"
|
||||
popd
|
||||
fi
|
||||
|
||||
if ! sha256sum "sources/$TARBALL" | grep -q 0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab; then
|
||||
echo "Wrong checksum"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf "$TARNAME"
|
||||
tar -zxvf "$SRC_DIR/$TARBALL"
|
||||
|
||||
pushd "$TARNAME"
|
||||
|
||||
emconfigure ./configure --disable-shared --prefix="$INSTALL_DIR" --with-ogg="$INSTALL_DIR"
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "libvorbis OK"
|
83
build_minetest.sh
Executable file
83
build_minetest.sh
Executable file
@ -0,0 +1,83 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
INCREMENTAL=${INCREMENTAL:-false}
|
||||
|
||||
pushd build
|
||||
if ! $INCREMENTAL; then
|
||||
rm -rf minetest
|
||||
fi
|
||||
mkdir -p minetest
|
||||
pushd minetest
|
||||
|
||||
export EMSDK_EXTRA="-sUSE_SDL=2"
|
||||
export CFLAGS="$CFLAGS $EMSDK_EXTRA"
|
||||
export CXXFLAGS="$CXXFLAGS $EMSDK_EXTRA"
|
||||
export LDFLAGS="$LDFLAGS $EMSDK_EXTRA -sALLOW_MEMORY_GROWTH=1 -sPTHREAD_POOL_SIZE=20 -s EXPORTED_RUNTIME_METHODS=ccall,cwrap -L$INSTALL_DIR/lib -lemsocket"
|
||||
|
||||
# Used by CMakeFiles.txt in the webport
|
||||
export FSROOT_DIR="$BUILD_DIR/fsroot"
|
||||
|
||||
# Create a dummy .o file to use as a substitute for the OpenGLES2 / EGL libraries,
|
||||
# since Emscripten doesn't actually provide those. (the symbols are resolved through
|
||||
# javascript stubs).
|
||||
echo > dummy.c
|
||||
emcc -c dummy.c -o dummy.o
|
||||
DUMMY_OBJECT="$(pwd)/dummy.o"
|
||||
|
||||
if ! $INCREMENTAL; then
|
||||
emcmake cmake \
|
||||
-DENABLE_SYSTEM_GMP=OFF \
|
||||
-DRUN_IN_PLACE=TRUE \
|
||||
-DENABLE_GLES=TRUE \
|
||||
-DCMAKE_BUILD_TYPE="$BUILD_KIND" \
|
||||
-DZLIB_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DZLIB_LIBRARY="$INSTALL_DIR/lib/libz.a" \
|
||||
-DJPEG_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DJPEG_LIBRARY="$INSTALL_DIR/lib/libjpeg.a" \
|
||||
-DPNG_PNG_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DPNG_LIBRARY="$INSTALL_DIR/lib/libpng.a" \
|
||||
-DOGG_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DVORBIS_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DOGG_LIBRARY="$INSTALL_DIR/lib/libogg.a" \
|
||||
-DVORBIS_LIBRARY="$INSTALL_DIR/lib/libvorbis.a" \
|
||||
-DVORBISFILE_LIBRARY="$INSTALL_DIR/lib/libvorbisfile.a" \
|
||||
-DFREETYPE_LIBRARY="$INSTALL_DIR/lib/libfreetype.a" \
|
||||
-DFREETYPE_INCLUDE_DIRS="$INSTALL_DIR/include/freetype2" \
|
||||
-DOPENGLES2_INCLUDE_DIR="$EMSDK_SYSINCLUDE" \
|
||||
-DOPENGLES2_LIBRARY="$DUMMY_OBJECT" \
|
||||
-DSQLITE3_LIBRARY="$INSTALL_DIR/lib/libsqlite3.a" \
|
||||
-DSQLITE3_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DZSTD_LIBRARY="$INSTALL_DIR/lib/libzstd.a" \
|
||||
-DZSTD_INCLUDE_DIR="$INSTALL_DIR/include" \
|
||||
-DEGL_LIBRARY="$DUMMY_OBJECT" \
|
||||
-DEGL_INCLUDE_DIR="$EMSDK_SYSINCLUDE" \
|
||||
-G "Unix Makefiles" \
|
||||
"$BASE_DIR/minetest"
|
||||
fi
|
||||
|
||||
if $INCREMENTAL; then
|
||||
emmake make -j1
|
||||
else
|
||||
emmake make -j4
|
||||
fi
|
||||
|
||||
echo "Installing into www/"
|
||||
rm -rf "$WWW_DIR"
|
||||
mkdir "$WWW_DIR"
|
||||
|
||||
FILES="minetest.data minetest.js minetest.wasm minetest.worker.js"
|
||||
|
||||
for I in $FILES; do
|
||||
cp src/"$I" "$WWW_DIR"
|
||||
done
|
||||
|
||||
if [ -f src/minetest.wasm.map ]; then
|
||||
cp src/minetest.wasm.map "$WWW_DIR"
|
||||
fi
|
||||
|
||||
cp "$BASE_DIR/static/index.html" "$WWW_DIR"
|
||||
cp "$BASE_DIR/static/.htaccess" "$WWW_DIR"
|
||||
|
||||
echo "DONE"
|
21
build_sqlite3.sh
Executable file
21
build_sqlite3.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -f sources/sqlite.tar.gz ]; then
|
||||
pushd sources
|
||||
wget "https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release" -O sqlite.tar.gz
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf sqlite
|
||||
tar -zxvf "$SRC_DIR/sqlite.tar.gz"
|
||||
|
||||
pushd sqlite
|
||||
export BUILD_CC="gcc"
|
||||
emconfigure ./configure --disable-shared --prefix="$INSTALL_DIR" cross_compiling=yes
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "sqlite3 OK"
|
20
build_webshims.sh
Executable file
20
build_webshims.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -d sources/webshims ]; then
|
||||
pushd sources
|
||||
git clone "https://github.com/paradust7/webshims.git" webshims
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf webshims
|
||||
mkdir webshims
|
||||
pushd webshims
|
||||
|
||||
emcmake cmake -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" "$SRC_DIR/webshims"
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "webshims OK"
|
20
build_zlib.sh
Executable file
20
build_zlib.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -d sources/zlib ]; then
|
||||
pushd sources
|
||||
git clone "https://github.com/madler/zlib.git" zlib
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf zlib
|
||||
cp -a "$SRC_DIR/zlib" zlib
|
||||
|
||||
pushd zlib
|
||||
emconfigure ./configure --static --prefix="$INSTALL_DIR"
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "ZLIB OK"
|
30
build_zstd.sh
Executable file
30
build_zstd.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
if [ ! -d sources/zstd ]; then
|
||||
pushd sources
|
||||
git clone https://github.com/facebook/zstd.git zstd
|
||||
|
||||
pushd zstd
|
||||
git checkout v1.5.2
|
||||
popd
|
||||
|
||||
popd
|
||||
fi
|
||||
|
||||
pushd build
|
||||
rm -rf zstd
|
||||
mkdir zstd
|
||||
|
||||
pushd zstd
|
||||
export CFLAGS="-D_POSIX_SOURCE=1"
|
||||
export CXXFLAGS="-D_POSIX_SOURCE=1"
|
||||
emcmake cmake \
|
||||
-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
|
||||
"$SRC_DIR/zstd/build/cmake"
|
||||
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
echo "zstd OK"
|
34
common.sh
Normal file
34
common.sh
Normal file
@ -0,0 +1,34 @@
|
||||
BASE_DIR="$(dirname -- "$(readlink -f -- "$0")")"
|
||||
|
||||
cd "$BASE_DIR"
|
||||
mkdir -p sources build install
|
||||
SRC_DIR="$BASE_DIR/sources"
|
||||
BUILD_DIR="$BASE_DIR/build"
|
||||
INSTALL_DIR="$BASE_DIR/install"
|
||||
WWW_DIR="$BASE_DIR/www"
|
||||
|
||||
test -d "$SRC_DIR"
|
||||
test -d "$BUILD_DIR"
|
||||
test -d "$INSTALL_DIR"
|
||||
|
||||
# Debug / Release
|
||||
export BUILD_KIND=Release
|
||||
|
||||
if [ $BUILD_KIND == Debug ]; then
|
||||
export BUILD_CFLAGS="-g -gsource-map -O0 --source-map-base=/dev/"
|
||||
export BUILD_LDFLAGS="-sSAFE_HEAP=1 -sASSERTIONS=2 -sDEMANGLE_SUPPORT=1"
|
||||
else
|
||||
export BUILD_CFLAGS="-O2"
|
||||
export BUILD_LDFLAGS=""
|
||||
fi
|
||||
|
||||
export CFLAGS="$BUILD_CFLAGS -pthread -sUSE_PTHREADS=1 -fexceptions"
|
||||
export CXXFLAGS="$BUILD_CFLAGS -pthread -sUSE_PTHREADS=1 -fexceptions"
|
||||
export LDFLAGS="$BUILD_LDFLAGS -pthread -sUSE_PTHREADS=1 -fexceptions -sEXIT_RUNTIME"
|
||||
|
||||
export EMSDK_ROOT="$HOME/emsdk"
|
||||
export EMSDK_SYSLIB="${EMSDK_ROOT}/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten"
|
||||
export EMSDK_SYSINCLUDE="${EMSDK_ROOT}/upstream/emscripten/cache/sysroot/include"
|
||||
|
||||
export MINETEST_REPO="$BASE_DIR/minetest"
|
||||
export IRRLICHT_REPO="$BASE_DIR/minetest/lib/irrlichtmt"
|
4
incremental.sh
Executable file
4
incremental.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
export INCREMENTAL=true
|
||||
./build_minetest.sh
|
15
pull_minetest.sh
Executable file
15
pull_minetest.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash -eux
|
||||
|
||||
source common.sh
|
||||
|
||||
|
||||
# If there's an existing source directory, leave it alone
|
||||
if [ -d minetest ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
git clone -b webport "https://github.com/paradust7/minetest.git"
|
||||
|
||||
pushd minetest/lib/
|
||||
|
||||
git clone -b webport "https://github.com/paradust7/irrlicht.git" irrlichtmt
|
2
static/.htaccess
Normal file
2
static/.htaccess
Normal file
@ -0,0 +1,2 @@
|
||||
Header set Cross-Origin-Embedder-Policy "require-corp"
|
||||
Header set Cross-Origin-Opener-Policy "same-origin"
|
357
static/index.html
Normal file
357
static/index.html
Normal file
@ -0,0 +1,357 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Minetest 5.6.0</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: arial;
|
||||
margin: 0;
|
||||
padding: none;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.emscripten {
|
||||
padding-right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.emscripten {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||
canvas.emscripten {
|
||||
border: 0px none;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
#progress {
|
||||
height: 20px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
#controls {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
#output {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin: 0 auto;
|
||||
margin-top: 0px;
|
||||
border-left: 0px;
|
||||
border-right: 0px;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-family: 'Lucida Console', Monaco, monospace;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.playbutton {
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
height: 120px;
|
||||
z-index: 10;
|
||||
font-size: 20pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="header">
|
||||
|
||||
<div class="emscripten">
|
||||
<span id='controls'>
|
||||
<span>
|
||||
<select id="resolution" onchange="fixGeometry()">
|
||||
<option value="high">High</option>
|
||||
<option value="medium">Medium</option>
|
||||
<option value="low">Low</option>
|
||||
</select>
|
||||
</span>
|
||||
<span>
|
||||
<select id="aspectRatio" onchange="fixGeometry()">
|
||||
<option value="any">Fit Screen</option>
|
||||
<option value="4:3">4:3</option>
|
||||
<option value="16:9">16:9</option>
|
||||
<option value="5:4">5:4</option>
|
||||
<option value="21:9">21:9</option>
|
||||
<option value="32:9">32:9</option>
|
||||
<option value="1:1">1:1</option>
|
||||
</select>
|
||||
</span>
|
||||
<span><input type="button" value="Toggle Fullscreen" onclick="fullscreen_button()"></span>
|
||||
<span><input type="button" value="Toggle Console" onclick="toggle_console()"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="emscripten">
|
||||
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="emscripten">
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" onclick="doPlay()" tabindex=-1 width="1024" height="600">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<textarea id="output" rows="8" style="display: none;"></textarea>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type='text/javascript'>
|
||||
var progressElement = document.getElementById('progress');
|
||||
|
||||
function toggle_console() {
|
||||
var element = document.getElementById('output');
|
||||
element.style.display = (element.style.display == 'block') ? 'none' : 'block';
|
||||
fixGeometry();
|
||||
}
|
||||
|
||||
var consoleElement = document.getElementById('output');
|
||||
var enableTracing = false;
|
||||
var consoleText = [];
|
||||
var consoleLengthMax = 1000;
|
||||
var consoleTextLast = 0;
|
||||
var consoleDirty = false;
|
||||
var playOK = false;
|
||||
var didPlay = false;
|
||||
|
||||
// Called by the MainLoop when it is ready
|
||||
function mainloop_ready_to_play() {
|
||||
drawPlayButton();
|
||||
playOK = true;
|
||||
}
|
||||
|
||||
var thePlayButton;
|
||||
function drawPlayButton() {
|
||||
if (thePlayButton) return;
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
var canvasRect = canvas.getBoundingClientRect();
|
||||
var midX = Math.floor((canvasRect.top + canvasRect.bottom) / 2);
|
||||
var midY = Math.floor((canvasRect.left + canvasRect.right) / 2);
|
||||
thePlayButton = document.createElement('button');
|
||||
thePlayButton.className = 'playbutton';
|
||||
thePlayButton.innerText = 'Click to Launch';
|
||||
thePlayButton.style.left = (midY - 300/2) + 'px';
|
||||
thePlayButton.style.top = (midX - 120/2) + 'px';
|
||||
thePlayButton.addEventListener('click', doPlay);
|
||||
document.body.appendChild(thePlayButton);
|
||||
}
|
||||
|
||||
function doPlay() {
|
||||
if (thePlayButton) {
|
||||
thePlayButton.remove();
|
||||
thePlayButton = null;
|
||||
}
|
||||
|
||||
if (playOK && !didPlay) {
|
||||
setupWrappers();
|
||||
didPlay = true;
|
||||
mainloop_play_wrapped();
|
||||
// irrlicht initialization resets the width/height
|
||||
fixGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
function consoleUpdate() {
|
||||
if (consoleDirty) {
|
||||
if (consoleText.length > consoleLengthMax) {
|
||||
consoleText = consoleText.slice(-consoleLengthMax);
|
||||
}
|
||||
consoleElement.value = consoleText.join('');
|
||||
consoleElement.scrollTop = consoleElement.scrollHeight; // focus on bottom
|
||||
consoleDirty = false;
|
||||
}
|
||||
window.requestAnimationFrame(consoleUpdate);
|
||||
}
|
||||
consoleUpdate();
|
||||
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {
|
||||
return function(text) {
|
||||
if (enableTracing) {
|
||||
console.trace(text);
|
||||
}
|
||||
consoleText.push(text + "\n");
|
||||
consoleDirty = true;
|
||||
};
|
||||
})(),
|
||||
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.last.text) return;
|
||||
if (text) Module.print('[status] ' + text);
|
||||
|
||||
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||
var now = Date.now();
|
||||
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
|
||||
Module.setStatus.last.time = now;
|
||||
Module.setStatus.last.text = text;
|
||||
if (m) {
|
||||
text = m[1];
|
||||
progressElement.value = parseInt(m[2])*100;
|
||||
progressElement.max = parseInt(m[4])*100;
|
||||
progressElement.hidden = false;
|
||||
} else {
|
||||
progressElement.value = null;
|
||||
progressElement.max = null;
|
||||
progressElement.hidden = true;
|
||||
}
|
||||
},
|
||||
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['printErr'] = Module['print'];
|
||||
Module['onFullScreen'] = () => { fixGeometry(); };
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function(event) {
|
||||
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
|
||||
Module.print('Exception thrown, see JavaScript console');
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.print('[status] ' + text);
|
||||
};
|
||||
};
|
||||
var pointerlock_pending = false;
|
||||
var mainloop_play_wrapped;
|
||||
var irrlicht_want_pointerlock;
|
||||
var irrlicht_resize;
|
||||
|
||||
function setupWrappers() {
|
||||
if (!mainloop_play_wrapped || !irrlicht_want_pointerlock || !irrlicht_resize) {
|
||||
mainloop_play_wrapped = cwrap("mainloop_play");
|
||||
irrlicht_want_pointerlock = cwrap("irrlicht_want_pointerlock", "number");
|
||||
irrlicht_resize = cwrap("irrlicht_resize", null, ['number', 'number']);
|
||||
}
|
||||
}
|
||||
|
||||
function fullscreen_button() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
if (playOK) {
|
||||
setupWrappers();
|
||||
var alsoLockPointer = irrlicht_want_pointerlock();
|
||||
// This calls Module['onFullScreen'] when finished, which calls fixGeometry.
|
||||
Module.requestFullscreen(alsoLockPointer, false);
|
||||
}
|
||||
}
|
||||
|
||||
function resizeCanvas(width, height) {
|
||||
var canvas = document.getElementById('canvas');
|
||||
if (canvas.width != width || canvas.height != height) {
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.widthNative = width;
|
||||
canvas.heightNative = height;
|
||||
}
|
||||
// Trigger SDL window resize.
|
||||
// This should happen automatically, it's disappointing that it doesn't.
|
||||
if (playOK) {
|
||||
setupWrappers();
|
||||
irrlicht_resize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
var resolutionSelect = document.getElementById('resolution');
|
||||
var aspectRatioSelect = document.getElementById('aspectRatio');
|
||||
|
||||
function fixGeometry() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var resolution = resolutionSelect.value;
|
||||
var aspectRatio = aspectRatioSelect.value;
|
||||
var screenX;
|
||||
var screenY;
|
||||
|
||||
var isFullScreen = document.fullscreenElement ? true : false;
|
||||
if (isFullScreen) {
|
||||
screenX = screen.width;
|
||||
screenY = screen.height;
|
||||
} else {
|
||||
var headerHeight = document.getElementById('header').offsetHeight;
|
||||
var footerHeight = document.getElementById('footer').offsetHeight;
|
||||
screenX = document.documentElement.clientWidth;
|
||||
screenY = document.documentElement.clientHeight - headerHeight - footerHeight;
|
||||
}
|
||||
|
||||
// Size of the viewport (after scaling)
|
||||
var realX;
|
||||
var realY;
|
||||
if (aspectRatio == 'any') {
|
||||
realX = screenX;
|
||||
realY = screenY;
|
||||
} else {
|
||||
var ar = aspectRatio.split(':');
|
||||
var innerRatio = parseInt(ar[0]) / parseInt(ar[1]);
|
||||
var outerRatio = screenX / screenY;
|
||||
if (innerRatio <= outerRatio) {
|
||||
realX = Math.floor(innerRatio * screenY);
|
||||
realY = screenY;
|
||||
} else {
|
||||
realX = screenX;
|
||||
realY = Math.floor(screenX / innerRatio);
|
||||
}
|
||||
}
|
||||
|
||||
// Native canvas resolution
|
||||
var resX;
|
||||
var resY;
|
||||
var scale = false;
|
||||
if (resolution == 'high') {
|
||||
resX = realX;
|
||||
resY = realY;
|
||||
} else if (resolution == 'medium') {
|
||||
resX = Math.floor(realX / 1.5);
|
||||
resY = Math.floor(realY / 1.5);
|
||||
scale = true;
|
||||
} else {
|
||||
resX = Math.floor(realX / 2.0);
|
||||
resY = Math.floor(realY / 2.0);
|
||||
scale = true;
|
||||
}
|
||||
resizeCanvas(resX, resY);
|
||||
|
||||
if (scale) {
|
||||
var styleWidth = realX + "px";
|
||||
var styleHeight = realY + "px";
|
||||
canvas.style.setProperty("width", styleWidth, "important");
|
||||
canvas.style.setProperty("height", styleHeight, "important");
|
||||
} else {
|
||||
canvas.style.removeProperty("width");
|
||||
canvas.style.removeProperty("height");
|
||||
}
|
||||
}
|
||||
window.addEventListener('resize', fixGeometry);
|
||||
fixGeometry();
|
||||
</script>
|
||||
<script async type="text/javascript" src="minetest.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user