summaryrefslogtreecommitdiff
path: root/platform/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'platform/javascript')
-rw-r--r--platform/javascript/SCsub40
-rw-r--r--platform/javascript/audio_driver_javascript.cpp31
-rw-r--r--platform/javascript/audio_driver_javascript.h8
-rw-r--r--platform/javascript/audio_server_javascript.cpp197
-rw-r--r--platform/javascript/audio_server_javascript.h4
-rw-r--r--platform/javascript/detect.py66
-rw-r--r--platform/javascript/export/export.cpp34
-rw-r--r--platform/javascript/godot_shell.html381
-rw-r--r--platform/javascript/javascript_eval.cpp9
-rw-r--r--platform/javascript/javascript_main.cpp51
-rw-r--r--platform/javascript/os_javascript.cpp112
-rw-r--r--platform/javascript/os_javascript.h14
12 files changed, 506 insertions, 441 deletions
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 5d5cd1590a..bd7b0c304d 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -2,6 +2,9 @@
Import('env')
+env.Tool('textfile')
+env.Tool('zip')
+
javascript_files = [
"os_javascript.cpp",
"audio_driver_javascript.cpp",
@@ -21,17 +24,26 @@ for x in javascript_files:
env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync']\""])
env.Append(LINKFLAGS=["--shell-file", '"platform/javascript/godot_shell.html"'])
-build = env.Program('#bin/godot', javascript_objects, PROGSUFFIX=env["PROGSUFFIX"] + ".html")
-
-def make_html_shell(target, source, env):
- html_path = target[0].rstr()
- assert html_path[:4] == 'bin/'
- assert html_path[-5:] == '.html'
- basename = html_path[4:-5]
- with open(html_path, 'r+') as html_file:
- fixed_html = html_file.read().replace('.html.mem', '.mem').replace(basename, '$GODOT_BASE')
- html_file.seek(0)
- html_file.truncate()
- html_file.write(fixed_html)
-
-env.AddPostAction(build, Action(make_html_shell, "Creating HTML shell file"))
+html_file = env.Program('#bin/godot', javascript_objects, PROGSUFFIX=env["PROGSUFFIX"] + ".html")[0]
+Depends(html_file, "godot_shell.html")
+basename = "godot" + env["PROGSUFFIX"] # output file name without file extension
+
+# Emscripten hardcodes file names, so replace common base name with
+# placeholder while leaving extension; also change `.html.mem` to just `.mem`
+fixup_html = env.Substfile(html_file, SUBST_DICT=[(basename, '$$GODOT_BASE'), ('.html.mem', '.mem')], SUBSTFILESUFFIX='.fixup.html')
+
+zip_dir = env.Dir('#bin/.javascript_zip')
+zip_files = []
+js_file = env.SideEffect(html_file.File(basename+'.js'), html_file)
+zip_files.append(env.InstallAs(
+ [zip_dir.File('godot.html'), zip_dir.File('godot.js'), zip_dir.File('godotfs.js')],
+ [fixup_html, js_file, '#misc/dist/html_fs/godotfs.js']))
+
+if env['wasm'] == 'yes':
+ wasm_file = env.SideEffect(html_file.File(basename+'.wasm'), html_file)
+ zip_files.append(env.InstallAs(zip_dir.File('godot.wasm'), wasm_file))
+else:
+ asmjs_files = env.SideEffect([html_file.File(basename+'.asm.js'), html_file.File(basename+'.html.mem')], html_file)
+ zip_files.append(env.InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files))
+
+Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX']+env['ZIPSUFFIX'], ZIPROOT=zip_dir)
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 579cbaed3c..bff01d7c37 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -27,20 +27,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "audio_driver_javascript.h"
-#include <string.h>
-
-
-
-
+#include <string.h>
#define MAX_NUMBER_INTERFACES 3
#define MAX_NUMBER_OUTPUT_DEVICES 6
/* Structure for passing information to callback function */
-
-
//AudioDriverJavaScript* AudioDriverJavaScript::s_ad=NULL;
const char* AudioDriverJavaScript::get_name() const {
@@ -53,36 +47,45 @@ Error AudioDriverJavaScript::init(){
return OK;
}
+
void AudioDriverJavaScript::start(){
}
+
int AudioDriverJavaScript::get_mix_rate() const {
return 44100;
}
-AudioDriverSW::OutputFormat AudioDriverJavaScript::get_output_format() const{
- return OUTPUT_STEREO;
+AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const{
+
+ return SPEAKER_MODE_STEREO;
}
+
void AudioDriverJavaScript::lock(){
- //if (active && mutex)
- // mutex->lock();
+ /*
+ if (active && mutex)
+ mutex->lock();
+ */
}
+
void AudioDriverJavaScript::unlock() {
- //if (active && mutex)
- // mutex->unlock();
+ /*
+ if (active && mutex)
+ mutex->unlock();
+ */
}
+
void AudioDriverJavaScript::finish(){
}
-
AudioDriverJavaScript::AudioDriverJavaScript()
{
}
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index 528b45569d..4c2064663a 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -29,21 +29,19 @@
#ifndef AUDIO_DRIVER_JAVASCRIPT_H
#define AUDIO_DRIVER_JAVASCRIPT_H
+#include "servers/audio_server.h"
-#include "servers/audio/audio_server_sw.h"
#include "os/mutex.h"
-class AudioDriverJavaScript : public AudioDriverSW {
+class AudioDriverJavaScript : public AudioDriver {
public:
- void set_singleton();
-
virtual const char* get_name() const;
virtual Error init();
virtual void start();
virtual int get_mix_rate() const ;
- virtual OutputFormat get_output_format() const;
+ virtual SpeakerMode get_speaker_mode() const;
virtual void lock();
virtual void unlock();
virtual void finish();
diff --git a/platform/javascript/audio_server_javascript.cpp b/platform/javascript/audio_server_javascript.cpp
index d1fba030a5..bb238ede0c 100644
--- a/platform/javascript/audio_server_javascript.cpp
+++ b/platform/javascript/audio_server_javascript.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "audio_server_javascript.h"
-
+#if 0
#include "emscripten.h"
AudioMixer *AudioServerJavascript::get_mixer() {
@@ -198,14 +198,15 @@ RID AudioServerJavascript::voice_create(){
voice->positional=false;
voice->active=false;
+ /* clang-format off */
EM_ASM_( {
- _as_voices[$0]=null;
- _as_voice_gain[$0]=_as_audioctx.createGain();
- _as_voice_pan[$0]=_as_audioctx.createStereoPanner();
- _as_voice_gain[$0].connect(_as_voice_pan[$0]);
- _as_voice_pan[$0].connect(_as_audioctx.destination);
-
- },voice_base);
+ _as_voices[$0] = null;
+ _as_voice_gain[$0] = _as_audioctx.createGain();
+ _as_voice_pan[$0] = _as_audioctx.createStereoPanner();
+ _as_voice_gain[$0].connect(_as_voice_pan[$0]);
+ _as_voice_pan[$0].connect(_as_audioctx.destination);
+ }, voice_base);
+ /* clang-format on */
voice_base++;
@@ -227,27 +228,29 @@ void AudioServerJavascript::voice_play(RID p_voice, RID p_sample){
//create sample if not created
ERR_FAIL_COND(sample->tmp_data.size()==0);
sample->index=sample_base;
- EM_ASM_( {
- _as_samples[$0]=_as_audioctx.createBuffer($1,$2,$3);
- },sample_base,sample->stereo?2:1,sample->length,sample->mix_rate);
+ /* clang-format off */
+ EM_ASM_({
+ _as_samples[$0] = _as_audioctx.createBuffer($1, $2, $3);
+ }, sample_base, sample->stereo ? 2 : 1, sample->length, sample->mix_rate);
+ /* clang-format on */
sample_base++;
int chans = sample->stereo?2:1;
for(int i=0;i<chans;i++) {
-
-
+ /* clang-format off */
EM_ASM_({
- _as_edited_buffer=_as_samples[$0].getChannelData($1);
- },sample->index,i);
-
+ _as_edited_buffer = _as_samples[$0].getChannelData($1);
+ }, sample->index, i);
+ /* clang-format on */
for(int j=0;j<sample->length;j++) {
-
+ /* clang-format off */
EM_ASM_({
- _as_edited_buffer[$0]=$1;
- },j,sample->tmp_data[j*chans+i]);
+ _as_edited_buffer[$0] = $1;
+ }, j, sample->tmp_data[j * chans + i]);
+ /* clang-format on */
}
}
@@ -263,26 +266,27 @@ void AudioServerJavascript::voice_play(RID p_voice, RID p_sample){
float freq_diff = Math::log(float(voice->mix_rate)/float(voice->sample_mix_rate))/Math::log(2.0);
int detune = int(freq_diff*1200.0);
- EM_ASM_( {
- if (_as_voices[$0]!==null) {
- _as_voices[$0].stop(); //stop and byebye
- }
- _as_voices[$0]=_as_audioctx.createBufferSource();
- _as_voices[$0].connect(_as_voice_gain[$0]);
- _as_voices[$0].buffer=_as_samples[$1];
- _as_voices[$0].loopStart.value=$1;
- _as_voices[$0].loopEnd.value=$2;
- _as_voices[$0].loop.value=$3;
- _as_voices[$0].detune.value=$6;
- _as_voice_pan[$0].pan.value=$4;
- _as_voice_gain[$0].gain.value=$5;
- _as_voices[$0].start();
- _as_voices[$0].onended=function() {
- _as_voices[$0].disconnect(_as_voice_gain[$0]);
- _as_voices[$0]=null;
- }
-
- },voice->index,sample->index,sample->mix_rate*sample->loop_begin,sample->mix_rate*sample->loop_end,sample->loop_format!=SAMPLE_LOOP_NONE,voice->pan,voice->volume*fx_volume_scale,detune);
+ /* clang-format off */
+ EM_ASM_({
+ if (_as_voices[$0] !== null) {
+ _as_voices[$0].stop(); //stop and byebye
+ }
+ _as_voices[$0] = _as_audioctx.createBufferSource();
+ _as_voices[$0].connect(_as_voice_gain[$0]);
+ _as_voices[$0].buffer = _as_samples[$1];
+ _as_voices[$0].loopStart.value = $1;
+ _as_voices[$0].loopEnd.value = $2;
+ _as_voices[$0].loop.value = $3;
+ _as_voices[$0].detune.value = $6;
+ _as_voice_pan[$0].pan.value = $4;
+ _as_voice_gain[$0].gain.value = $5;
+ _as_voices[$0].start();
+ _as_voices[$0].onended = function() {
+ _as_voices[$0].disconnect(_as_voice_gain[$0]);
+ _as_voices[$0] = null;
+ }
+ }, voice->index, sample->index, sample->mix_rate * sample->loop_begin, sample->mix_rate * sample->loop_end, sample->loop_format != SAMPLE_LOOP_NONE, voice->pan, voice->volume * fx_volume_scale, detune);
+ /* clang-format on */
voice->active=true;
}
@@ -295,11 +299,11 @@ void AudioServerJavascript::voice_set_volume(RID p_voice, float p_volume){
voice->volume=p_volume;
if (voice->active) {
- EM_ASM_( {
-
- _as_voice_gain[$0].gain.value=$1;
-
- },voice->index,voice->volume*fx_volume_scale);
+ /* clang-format off */
+ EM_ASM_({
+ _as_voice_gain[$0].gain.value = $1;
+ }, voice->index, voice->volume * fx_volume_scale);
+ /* clang-format on */
}
}
@@ -313,11 +317,11 @@ void AudioServerJavascript::voice_set_pan(RID p_voice, float p_pan, float p_dept
voice->pan_height=height;
if (voice->active) {
- EM_ASM_( {
-
- _as_voice_pan[$0].pan.value=$1;
-
- },voice->index,voice->pan);
+ /* clang-format off */
+ EM_ASM_({
+ _as_voice_pan[$0].pan.value = $1;
+ }, voice->index, voice->pan);
+ /* clang-format on */
}
}
void AudioServerJavascript::voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance, float p_gain){
@@ -340,11 +344,11 @@ void AudioServerJavascript::voice_set_mix_rate(RID p_voice, int p_mix_rate){
float freq_diff = Math::log(float(voice->mix_rate)/float(voice->sample_mix_rate))/Math::log(2.0);
int detune = int(freq_diff*1200.0);
- EM_ASM_( {
-
- _as_voices[$0].detune.value=$1;
-
- },voice->index,detune);
+ /* clang-format off */
+ EM_ASM_({
+ _as_voices[$0].detune.value = $1;
+ }, voice->index, detune);
+ /* clang-format on */
}
}
void AudioServerJavascript::voice_set_positional(RID p_voice, bool p_positional){
@@ -419,14 +423,15 @@ void AudioServerJavascript::voice_stop(RID p_voice){
ERR_FAIL_COND(!voice);
if (voice->active) {
-
- EM_ASM_( {
- if (_as_voices[$0]!==null) {
- _as_voices[$0].stop();
- _as_voices[$0].disconnect(_as_voice_gain[$0]);
- _as_voices[$0]=null;
- }
- },voice->index);
+ /* clang-format off */
+ EM_ASM_({
+ if (_as_voices[$0] !== null) {
+ _as_voices[$0].stop();
+ _as_voices[$0].disconnect(_as_voice_gain[$0]);
+ _as_voices[$0] = null;
+ }
+ }, voice->index);
+ /* clang-format on */
voice->active=false;
}
@@ -524,22 +529,25 @@ void AudioServerJavascript::free(RID p_id){
ERR_FAIL_COND(!voice);
if (voice->active) {
- EM_ASM_( {
- if (_as_voices[$0]!==null) {
+ /* clang-format off */
+ EM_ASM_({
+ if (_as_voices[$0] !== null) {
_as_voices[$0].stop();
- _as_voices[$0].disconnect(_as_voice_gain[$0]);
+ _as_voices[$0].disconnect(_as_voice_gain[$0]);
}
- },voice->index);
+ }, voice->index);
+ /* clang-format on */
}
- EM_ASM_( {
+ /* clang-format off */
+ EM_ASM_({
delete _as_voices[$0];
_as_voice_gain[$0].disconnect(_as_voice_pan[$0]);
delete _as_voice_gain[$0];
_as_voice_pan[$0].disconnect(_as_audioctx.destination);
delete _as_voice_pan[$0];
-
- },voice->index);
+ }, voice->index);
+ /* clang-format on */
voice_owner.free(p_id);
memdelete(voice);
@@ -549,10 +557,11 @@ void AudioServerJavascript::free(RID p_id){
Sample *sample = sample_owner.get(p_id);
ERR_FAIL_COND(!sample);
- EM_ASM_( {
+ /* clang-format off */
+ EM_ASM_({
delete _as_samples[$0];
-
- },sample->index);
+ }, sample->index);
+ /* clang-format on */
sample_owner.free(p_id);
memdelete(sample);
@@ -594,21 +603,20 @@ void AudioServerJavascript::mix_to_js(int p_frames) {
int tomix=MIN(todo,INTERNAL_BUFFER_SIZE);
driver_process_chunk(tomix);
-
+ /* clang-format off */
EM_ASM_({
-
- var data = HEAPF32.subarray($0/4, $0/4 + $2*2);
+ var data = HEAPF32.subarray($0 / 4, $0 / 4 + $2 * 2);
for (var channel = 0; channel < _as_output_buffer.numberOfChannels; channel++) {
var outputData = _as_output_buffer.getChannelData(channel);
// Loop through samples
for (var sample = 0; sample < $2; sample++) {
// make output equal to the same as the input
- outputData[sample+$1] = data[sample*2+channel];
+ outputData[sample + $1] = data[sample * 2 + channel];
}
}
-
- },internal_buffer,offset,tomix);
+ }, internal_buffer, offset, tomix);
+ /* clang-format on */
todo-=tomix;
offset+=tomix;
@@ -617,9 +625,13 @@ void AudioServerJavascript::mix_to_js(int p_frames) {
void AudioServerJavascript::init(){
- //EM_ASM(
-// console.log('server is '+audio_server);
-// );
+ /*
+ // clang-format off
+ EM_ASM(
+ console.log('server is ' + audio_server);
+ );
+ // clang-format on
+ */
//int latency = GLOBAL_DEF("javascript/audio_latency",16384);
@@ -632,19 +644,19 @@ void AudioServerJavascript::init(){
int buffer_latency=16384;
+ /* clang-format off */
EM_ASM_( {
-
_as_script_node = _as_audioctx.createScriptProcessor($0, 0, 2);
_as_script_node.connect(_as_audioctx.destination);
console.log(_as_script_node.bufferSize);
-
_as_script_node.onaudioprocess = function(audioProcessingEvent) {
// The output buffer contains the samples that will be modified and played
_as_output_buffer = audioProcessingEvent.outputBuffer;
audio_server_mix_function(_as_output_buffer.getChannelData(0).length);
}
- },buffer_latency);
+ }, buffer_latency);
+ /* clang-format on */
}
@@ -811,23 +823,28 @@ AudioServerJavascript::AudioServerJavascript() {
singleton=this;
sample_base=1;
voice_base=1;
+ /* clang-format off */
EM_ASM(
- _as_samples={};
- _as_voices={};
- _as_voice_pan={};
- _as_voice_gain={};
+ _as_samples = {};
+ _as_voices = {};
+ _as_voice_pan = {};
+ _as_voice_gain = {};
_as_audioctx = new (window.AudioContext || window.webkitAudioContext)();
audio_server_mix_function = Module.cwrap('audio_server_mix_function', 'void', ['number']);
);
+ /* clang-format on */
+ /* clang-format off */
webaudio_mix_rate = EM_ASM_INT_V(
- return _as_audioctx.sampleRate;
- );
+ return _as_audioctx.sampleRate;
+ );
+ /* clang-format on */
print_line("WEBAUDIO MIX RATE: "+itos(webaudio_mix_rate));
event_voice_scale=1.0;
fx_volume_scale=1.0;
stream_volume_scale=1.0;
}
+#endif
diff --git a/platform/javascript/audio_server_javascript.h b/platform/javascript/audio_server_javascript.h
index 8e61e94dfc..2f48e7e79e 100644
--- a/platform/javascript/audio_server_javascript.h
+++ b/platform/javascript/audio_server_javascript.h
@@ -28,8 +28,7 @@
/*************************************************************************/
#ifndef AUDIO_SERVER_JAVASCRIPT_H
#define AUDIO_SERVER_JAVASCRIPT_H
-
-
+#if 0
#include "servers/audio_server.h"
class AudioServerJavascript : public AudioServer {
@@ -224,3 +223,4 @@ public:
};
#endif // AUDIO_SERVER_JAVASCRIPT_H
+#endif
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 2cb6874000..799b550899 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -12,11 +12,7 @@ def get_name():
def can_build():
-
- import os
- if (not os.environ.has_key("EMSCRIPTEN_ROOT")):
- return False
- return True
+ return os.environ.has_key("EMSCRIPTEN_ROOT")
def get_opts():
@@ -37,31 +33,41 @@ def get_flags():
]
+def create(env):
+ # remove Windows' .exe suffix
+ return env.Clone(PROGSUFFIX='')
+
+
+def escape_sources_backslashes(target, source, env, for_signature):
+ return [path.replace('\\','\\\\') for path in env.GetBuildPath(source)]
+
+def escape_target_backslashes(target, source, env, for_signature):
+ return env.GetBuildPath(target[0]).replace('\\','\\\\')
+
+
def configure(env):
env['ENV'] = os.environ
- env.use_windows_spawn_fix('javascript')
env.Append(CPPPATH=['#platform/javascript'])
- em_path = os.environ["EMSCRIPTEN_ROOT"]
-
- env['ENV']['PATH'] = em_path + ":" + env['ENV']['PATH']
- env['CC'] = em_path + '/emcc'
- env['CXX'] = em_path + '/emcc'
- #env['AR'] = em_path+"/emar"
- env['AR'] = em_path + "/emcc"
- env['ARFLAGS'] = "-o"
+ env.PrependENVPath('PATH', os.environ['EMSCRIPTEN_ROOT'])
+ env['CC'] = 'emcc'
+ env['CXX'] = 'em++'
+ env['LINK'] = 'emcc'
+ env['RANLIB'] = 'emranlib'
+ # Emscripten's ar has issues with duplicate file names, so use cc
+ env['AR'] = 'emcc'
+ env['ARFLAGS'] = '-o'
+ if (os.name == 'nt'):
+ # use TempFileMunge on Windows since some commands get too long for
+ # cmd.exe even with spawn_fix
+ # need to escape backslashes for this
+ env['ESCAPED_SOURCES'] = escape_sources_backslashes
+ env['ESCAPED_TARGET'] = escape_target_backslashes
+ env['ARCOM'] = '${TEMPFILE("%s")}' % env['ARCOM'].replace('$SOURCES', '$ESCAPED_SOURCES').replace('$TARGET', '$ESCAPED_TARGET')
-# env['RANLIB'] = em_path+"/emranlib"
- env['RANLIB'] = em_path + "/emcc"
env['OBJSUFFIX'] = '.bc'
env['LIBSUFFIX'] = '.bc'
- env['CCCOM'] = "$CC -o $TARGET $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES"
- env['CXXCOM'] = "$CC -o $TARGET $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES"
-
-# env.Append(LIBS=['c','m','stdc++','log','GLESv1_CM','GLESv2'])
-
-# env["LINKFLAGS"]= string.split(" -g --sysroot="+ld_sysroot+" -Wl,--no-undefined -Wl,-z,noexecstack ")
if (env["target"] == "release"):
env.Append(CCFLAGS=['-O2'])
@@ -79,10 +85,7 @@ def configure(env):
# These flags help keep the file size down
env.Append(CPPFLAGS=["-fno-exceptions", '-DNO_SAFE_CAST', '-fno-rtti'])
env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DNO_FCNTL', '-DMPC_FIXED_POINT', '-DTYPED_METHOD_BIND', '-DNO_THREADS'])
- env.Append(CPPFLAGS=['-DGLES2_ENABLED'])
- env.Append(CPPFLAGS=['-DGLES_NO_CLIENT_ARRAYS'])
- env.Append(CPPFLAGS=['-s', 'FULL_ES2=1'])
-# env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT'])
+ env.Append(CPPFLAGS=['-DGLES3_ENABLED'])
if env['wasm'] == 'yes':
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
@@ -92,7 +95,7 @@ def configure(env):
# what is set during compilation, check TOTAL_MEMORY in Emscripten's
# src/settings.js for the default.
env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1'])
- env["PROGSUFFIX"] += ".webassembly"
+ env.extra_suffix = '.webassembly' + env.extra_suffix
else:
env.Append(CPPFLAGS=['-s', 'ASM_JS=1'])
env.Append(LINKFLAGS=['-s', 'ASM_JS=1'])
@@ -102,14 +105,7 @@ def configure(env):
env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED'])
env.Append(LINKFLAGS=['-O2'])
+ env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1'])
# env.Append(LINKFLAGS=['-g4'])
- # print "CCCOM is:", env.subst('$CCCOM')
- # print "P: ", env['p'], " Platofrm: ", env['platform']
-
import methods
-
- env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
- #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index c151bff45c..2657eaddb5 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -29,15 +29,18 @@
#include "version.h"
#include "export.h"
#include "tools/editor/editor_settings.h"
-#include "tools/editor/editor_import_export.h"
+#include "tools/editor/editor_export.h"
#include "tools/editor/editor_node.h"
#include "io/zip_io.h"
#include "io/marshalls.h"
-#include "globals.h"
+#include "global_config.h"
#include "os/file_access.h"
#include "os/os.h"
#include "platform/javascript/logo.h"
#include "string.h"
+
+
+#if 0
class EditorExportPlatformJavaScript : public EditorExportPlatform {
GDCLASS( EditorExportPlatformJavaScript,EditorExportPlatform );
@@ -181,8 +184,8 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t>& p_html, const St
String current_line = lines[i];
current_line = current_line.replace("$GODOT_TMEM",itos((1<<(max_memory+5))*1024*1024));
current_line = current_line.replace("$GODOT_BASE",p_name);
- current_line = current_line.replace("$GODOT_CANVAS_WIDTH",GlobalConfig::get_singleton()->get("display/width"));
- current_line = current_line.replace("$GODOT_CANVAS_HEIGHT",GlobalConfig::get_singleton()->get("display/height"));
+ current_line = current_line.replace("$GODOT_CANVAS_WIDTH",GlobalConfig::get_singleton()->get("display/window/width"));
+ current_line = current_line.replace("$GODOT_CANVAS_HEIGHT",GlobalConfig::get_singleton()->get("display/window/height"));
current_line = current_line.replace("$GODOT_HEAD_TITLE",!html_title.empty()?html_title:(String) GlobalConfig::get_singleton()->get("application/name"));
current_line = current_line.replace("$GODOT_HEAD_INCLUDE",html_head_include);
current_line = current_line.replace("$GODOT_STYLE_FONT_FAMILY",html_font_family);
@@ -265,7 +268,7 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool
FileAccess *f=FileAccess::open(p_path.get_base_dir()+"/data.pck",FileAccess::WRITE);
if (!f) {
- EditorNode::add_io_error("Could not create file for writing:\n"+p_path.basename()+"_files.js");
+ EditorNode::add_io_error("Could not create file for writing:\n"+p_path.get_basename()+"_files.js");
return ERR_FILE_CANT_WRITE;
}
Error err = save_pack(f);
@@ -307,32 +310,32 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool
if (file=="godot.html") {
- _fix_html(data,p_path.get_file().basename(), p_debug);
+ _fix_html(data,p_path.get_file().get_basename(), p_debug);
file=p_path.get_file();
}
if (file=="godotfs.js") {
_fix_files(data,len);
- file=p_path.get_file().basename()+"fs.js";
+ file=p_path.get_file().get_basename()+"fs.js";
}
if (file=="godot.js") {
- file=p_path.get_file().basename()+".js";
+ file=p_path.get_file().get_basename()+".js";
}
if (file=="godot.asm.js") {
- file=p_path.get_file().basename()+".asm.js";
+ file=p_path.get_file().get_basename()+".asm.js";
}
if (file=="godot.mem") {
- file=p_path.get_file().basename()+".mem";
+ file=p_path.get_file().get_basename()+".mem";
}
if (file=="godot.wasm") {
- file=p_path.get_file().basename()+".wasm";
+ file=p_path.get_file().get_basename()+".wasm";
}
String dst = p_path.get_base_dir().plus_file(file);
@@ -377,7 +380,7 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
logo->create_from_image(img);
max_memory=3;
html_title="";
- html_font_family="arial,sans-serif";
+ html_font_family="'Droid Sans',arial,sans-serif";
html_controls_enabled=true;
pack_mode=PACK_SINGLE_FILE;
}
@@ -414,13 +417,14 @@ EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
}
-
+#endif
void register_javascript_exporter() {
- Ref<EditorExportPlatformJavaScript> exporter = Ref<EditorExportPlatformJavaScript>( memnew(EditorExportPlatformJavaScript) );
- EditorImportExport::get_singleton()->add_export_platform(exporter);
+ //Ref<EditorExportPlatformJavaScript> exporter = Ref<EditorExportPlatformJavaScript>( memnew(EditorExportPlatformJavaScript) );
+ //EditorImportExport::get_singleton()->add_export_platform(exporter);
}
+
diff --git a/platform/javascript/godot_shell.html b/platform/javascript/godot_shell.html
index 3170d2bb9e..65f3b4a340 100644
--- a/platform/javascript/godot_shell.html
+++ b/platform/javascript/godot_shell.html
@@ -3,14 +3,14 @@
<head>
<meta charset="utf-8" />
<title>$GODOT_HEAD_TITLE</title>
- $GODOT_HEAD_INCLUDE
+$GODOT_HEAD_INCLUDE
<style type="text/css">
body {
margin: 0;
border: 0 none;
padding: 0;
text-align: center;
- background-color: black;
+ background-color: #222226;
font-family: $GODOT_STYLE_FONT_FAMILY;
}
@@ -71,7 +71,7 @@
margin: 0;
border: 0 none;
padding: 0;
- background-color: #111;
+ background-color: #0c0c0c;
}
#canvas {
@@ -81,6 +81,7 @@
* calculate cursor coordinates correctly */
border: 0 none;
padding: 0;
+ color: white;
}
@@ -101,6 +102,8 @@
}
#status {
+ line-height: 1.3;
+ cursor: pointer;
visibility: visible;
padding: 4px 6px;
}
@@ -123,7 +126,7 @@
-ms-user-select: none;
}
- #container:hover > #controls {
+ :hover > #controls {
opacity: 1.0;
transition: opacity 60ms ease-in-out;
}
@@ -135,223 +138,289 @@
margin-right: 2px;
}
+ #controls > label > input {
+ vertical-align: middle;
+ }
+
#controls > label > input[type="checkbox"] {
/* override user agent style */
margin-left: 0;
}
- label > input {
- vertical-align: middle;
- }
-
- #display-output { display: none; }
+ #output-toggle { display: none; }
/* Debug output
* ============ */
- #output {
+ #output-panel {
display: none;
- margin: 6px auto;
- border: 2px groove grey;
- padding: 4px;
- outline: none;
+ max-width: $GODOT_CANVAS_WIDTHpx;
+ font-size: small;
+ margin: 6px auto 0;
+ padding: 0 4px 4px;
text-align: left;
+ line-height: 2.2;
+ }
+
+ #output-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ #output-container {
+ padding: 6px;
+ background-color: #2c2a32;
+ box-shadow: inset 0 0 1px 1px #232127;
+ color: #bbb;
+ }
+
+ #output-scroll {
+ line-height: 1;
+ height: 12em;
+ overflow-y: scroll;
white-space: pre-wrap;
font-size: small;
- color: #eee;
- background-color: black;
font-family: "Lucida Console", Monaco, monospace;
}
- /* Export style include
- * ==================== */
+/* Export style include
+ * ==================== */
+
+$GODOT_STYLE_INCLUDE
- $GODOT_STYLE_INCLUDE
</style>
</head>
<body>
<div id="container">
<canvas id="canvas" width="$GODOT_CANVAS_WIDTH" height="$GODOT_CANVAS_HEIGHT" onclick="canvas.ownerDocument.defaultView.focus();" oncontextmenu="event.preventDefault();">
- HTML5 canvas appears to be unsupported in the current browser.<br />Please try updating or use a different browser.
+ HTML5 canvas appears to be unsupported in the current browser.<br />
+ Please try updating or use a different browser.
</canvas>
<div id="status-container">
- <span id="status" class="godot" onclick="this.style.visibility='hidden';">Loading page...</span>
+ <span id="status" class="godot" onclick="this.style.visibility='hidden';">Downloading page...</span>
</div>
<div id="controls" class="godot">
- <label id="display-output"><input id="output-toggle" type="checkbox" autocomplete="off" onchange="Presentation.setOutputVisible(this.checked);" />display output</label>
+ <label id="output-toggle"><input type="checkbox" checked="checked" autocomplete="off" onchange="Presentation.setOutputVisible(this.checked);" />Display Output</label>
<!-- hidden until implemented
- <label><input id="lock-cursor" type="checkbox" autocomplete="off" />lock cursor</label>
- <label><input id="resize-canvas" type="checkbox" autocomplete="off" />resize canvas</label>
+ <label><input class="postRun-enable" type="checkbox" disabled="disabled" autocomplete="off" />lock cursor</label>
+ <label><input class="postRun-enable" type="checkbox" disabled="disabled" autocomplete="off" onchange="Presentation.setCanvasMaximized(this.checked);" />maximize</label>
-->
- <button id="fullscreen" class="godot" type="button" disabled="disabled" autocomplete="off" onclick="Presentation.goFullscreen();">fullscreen</button>
+ <button id="fullscreen" class="godot postRun-enable" type="button" disabled="disabled" autocomplete="off" onclick="Presentation.requestFullscreen();">Fullscreen</button>
</div>
</div>
- <!-- Firefox adds extra space to textarea, but shouldn't matter too much https://bugzilla.mozilla.org/show_bug.cgi?id=33654 -->
- <textarea id="output" rows="10" cols="100" readonly="readonly" style="resize:none"></textarea>
+ <div id="output-panel" class="godot">
+ <div id="output-header">
+ Output:
+ <button class="godot" type="button" autocomplete="off" onclick="Presentation.clearOutput();">Clear</button>
+ </div>
+ <div id="output-container"><div id="output-scroll"></div></div>
+ </div>
+ <!-- Scripts -->
<script type="text/javascript">//<![CDATA[
var Presentation = (function() {
var statusElement = document.getElementById("status");
- var outputElement = document.getElementById("output");
- var doneLoading = false;
-
- function onLoaded() {
- doneLoading = true;
- var fullscreenButtonElement = document.getElementById("fullscreen");
- fullscreenButtonElement.disabled = false;
- }
+ var canvasElement = document.getElementById("canvas");
var presentation = {
- statusElement: statusElement,
- outputElement: outputElement,
- setOutputVisible: function setOutputVisible(visible) {
- outputElement.style.display = (visible?"block":"none");
+ postRun: [
+ function() {
+ var elements = document.getElementsByClassName("postRun-enable");
+ Array.prototype.slice.call(elements).forEach(function(element) {
+ element.disabled = false;
+ });
+ }
+ ],
+ requestFullscreen: function requestFullscreen() {
+ if (typeof Module !== "undefined" && Module.requestFullscreen) {
+ Module.requestFullscreen(false, false);
+ }
+ },
+ /*
+ requestPointerlock: function requestPointerlock() {
+ if (typeof Module !== "undefined" && Module.requestPointerlock) {
+ Module.requestPointerlock(false, false);
+ }
},
+ setCanvasMaximized: function setCanvasMaximized(enabled) {
+ if (typeof Module !== "undefined" && Module.setCanvasMaximized) {
+ Module.setCanvasMaximized(enabled);
+ }
+ },
+ */
setStatusVisible: function setStatusVisible(visible) {
statusElement.style.visibility = (visible?"visible":"hidden");
},
setStatus: function setStatus(text) {
- if (!text || text.length === 0) {
- Presentation.setStatusVisible(false);
- onLoaded();
- } else {
- Presentation.setStatusVisible(true);
- statusElement.innerHTML = text;
+ if (text.length === 0) {
+ // emscripten sets empty string as status after "Running..."
+ // per timeout, but another status may have been set by then
+ if (Presentation.setStatus.lastText === "Running...")
+ Presentation.setStatusVisible(false);
+ return;
}
+ Presentation.setStatus.lastText = text;
+ while (statusElement.lastChild) {
+ statusElement.removeChild(statusElement.lastChild);
+ }
+ var lines = text.split("\n");
+ lines.forEach(function(line, index) {
+ statusElement.appendChild(document.createTextNode(line));
+ statusElement.appendChild(document.createElement("br"));
+ });
+ var closeNote = document.createElement("span");
+ closeNote.style.fontSize = "small";
+ closeNote.textContent = "click to close";
+ statusElement.appendChild(closeNote);
+ Presentation.setStatusVisible(true);
+ },
+ isWebGL2Available: function isWebGL2Available() {
+ var context;
+ try {
+ context = canvasElement.getContext("webgl2") || canvasElement.getContext("experimental-webgl2");
+ } catch (e) {}
+ return !!context;
},
- goFullscreen: function goFullscreen() {
- if (doneLoading) Module.requestFullScreen(false, false);
- }
};
+ window.onerror = function(event) { presentation.setStatus("Failure during start-up\nSee JavaScript console") };
+
if ($GODOT_CONTROLS_ENABLED) { // controls enabled
- (function() {
- var controlsElement = document.getElementById("controls");
- controlsElement.style.visibility="visible";
- })();
+ document.getElementById("controls").style.visibility="visible";
}
if ($GODOT_DEBUG_ENABLED) { // debugging enabled
- (function() {
- var outputToggleLabel = document.getElementById("display-output");
- var outputToggle = document.getElementById("output-toggle");
-
- outputElement.value = ""; // clear browser cache
- outputElement.style.display = "block";
- outputToggle.checked = true;
- outputToggleLabel.style.display = "inline";
-
- presentation.print = function print(text) {
- if (outputElement.value.length !== 0)
- outputElement.value += "\n";
- outputElement.value += text;
- outputElement.scrollTop = outputElement.scrollHeight; // focus on bottom
- };
- })();
+ var outputRoot = document.getElementById("output-panel");
+ var outputElement = document.getElementById("output-scroll");
+ var outputToggle = document.getElementById("output-toggle");
+ const maxOutputMessages = 400;
+
+ presentation.setOutputVisible = function setOutputVisible(visible) {
+ outputRoot.style.display = (visible?"block":"none");
+ };
+ presentation.clearOutput = function clearOutput() {
+ while (outputElement.firstChild) {
+ outputElement.firstChild.remove();
+ }
+ };
+
+ presentation.setOutputVisible(true);
+ outputToggle.style.display = "inline";
+
+ presentation.print = function print(text) {
+ if (arguments.length > 1) {
+ text = Array.prototype.slice.call(arguments).join(" ");
+ }
+ if (text.length <= 0) return;
+ while (outputElement.childElementCount >= maxOutputMessages) {
+ outputElement.firstChild.remove();
+ }
+ var msg = document.createElement("div");
+ if (String.prototype.trim.call(text).startsWith("**ERROR**")
+ || String.prototype.trim.call(text).startsWith("**EXCEPTION**")) {
+ msg.style.color = "#d44";
+ } else if (String.prototype.trim.call(text).startsWith("**WARNING**")) {
+ msg.style.color = "#ccc000";
+ } else if (String.prototype.trim.call(text).startsWith("**SCRIPT ERROR**")) {
+ msg.style.color = "#c6d";
+ }
+ msg.textContent = text;
+ var scrollToBottom = outputElement.scrollHeight - (outputElement.clientHeight + outputElement.scrollTop) < 10;
+ outputElement.appendChild(msg);
+ if (scrollToBottom) {
+ outputElement.scrollTop = outputElement.scrollHeight;
+ }
+ };
+
+ presentation.postRun.push(function() {
+ window.onerror = function(event) { presentation.print("**EXCEPTION**:", event) };
+ });
+
+ } else {
+ presentation.postRun.push(function() { window.onerror = null; });
}
return presentation;
})();
// Emscripten interface
- var Module = (function() {
- var print = (function() {
- if (typeof Presentation.print === "function") {
- return function print(text) {
- if (arguments.length > 1)
- text = Array.prototype.slice.call(arguments).join(" ");
- console.log(text);
- Presentation.print(text);
- };
- } else {
- return function print(text) {
- if (arguments.length > 1)
- text = Array.prototype.slice.call(arguments).join(" ");
- console.log(text);
- };
+ var Module = {
+ TOTAL_MEMORY: $GODOT_TMEM,
+ postRun: (function() {
+ if (typeof Presentation !== "undefined" && Presentation.postRun instanceof Array) {
+ return Presentation.postRun;
}
- })();
-
- var canvas = (function() {
- var canvasElement = document.getElementById("canvas");
-
+ })(),
+ print: function print(text) {
+ if (arguments.length > 1) {
+ text = Array.prototype.slice.call(arguments).join(" ");
+ }
+ console.log(text);
+ if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") {
+ Presentation.print(text);
+ }
+ },
+ printErr: function printErr(text) {
+ if (arguments.length > 1) {
+ text = Array.prototype.slice.call(arguments).join(" ");
+ }
+ console.error(text);
+ if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") {
+ Presentation.print("**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
- canvasElement.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false);
-
- return canvasElement;
- })();
-
- var setStatus = (function() {
- if (typeof Presentation.setStatus === "function")
- return function setStatus(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) {
- if (now - Date.now() < 30) // if this is a progress update, skip it if too soon
- return;
- text = m[1];
- }
- Presentation.setStatus(text);
- };
- else
- return function setStatus(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) {
- if (now - Date.now() < 30) // if this is a progress update, skip it if too soon
- return;
- text = m[1];
- }
- };
- })();
-
- return {
- TOTAL_MEMORY: 268435456,
- preRun: [],
- postRun: [],
- print: print,
- printErr: function printErr(text) {
- if (arguments.length > 1)
- text = Array.prototype.slice.call(arguments).join(" ");
- if (0) { // XXX disabled for safety `if (typeof dump == "function")`
- dump(text + "\n"); // fast, straight to the real console
- } else {
- console.error(text);
- }
- },
- canvas: canvas,
- setStatus: setStatus,
- totalDependencies: 0,
- monitorRunDependencies: function monitorRunDependencies(left) {
- this.totalDependencies = Math.max(this.totalDependencies, left);
- Module.setStatus(left ? "Preparing... (" + (this.totalDependencies-left) + "/" + this.totalDependencies + ")" : "All downloads complete.");
+ canvas.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false);
+ return canvas;
+
+ })(),
+ setStatus: function setStatus(text) {
+ var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ var now = Date.now();
+ if (m) {
+ if (now - Date.now() < 30) // if this is a progress update, skip it if too soon
+ return;
+ text = m[1];
}
- };
- })();
+ if (typeof Presentation !== "undefined" && typeof Presentation.setStatus == "function") {
+ Presentation.setStatus(text);
+ }
+ }
+ };
- Presentation.setStatus("Downloading...");
+ if (!Presentation.isWebGL2Available()) {
+ Presentation.setStatus("WebGL2 appears to be unsupported in the current browser.\nPlease try updating or use a different browser.");
+ Presentation.preventLoading = true;
+ } else {
+ Presentation.setStatus("Downloading...");
+ }
- window.onerror = function(event) {
- // TODO: do not warn on ok events like simulating an infinite loop or exitStatus
- Module.setStatus("Exception thrown, see JavaScript console");
- Module.setStatus = function(text) {
- if (text) Module.printErr("[post-exception status] " + text);
- };
- };
+ if (Presentation.preventLoading) {
+ // prevent *fs.js and Emscripten's SCRIPT placeholder from loading any files
+ Presentation._XHR_send = XMLHttpRequest.prototype.send;
+ XMLHttpRequest.prototype.send = function() {};
+ Presentation._Node_appendChild = Node.prototype.appendChild;
+ Node.prototype.appendChild = function(node) {
+ if (!(node instanceof HTMLScriptElement)) {
+ return Presentation._Node_appendChild.call(this, node);
+ }
+ }
+ }
//]]></script>
<script type="text/javascript" src="$GODOT_BASEfs.js"></script>
- {{{ SCRIPT }}}
+{{{ SCRIPT }}}
+ <script type="text/javascript">
+ if (Presentation.preventLoading) {
+ XMLHttpRequest.prototype.send = Presentation._XHR_send;
+ Node.prototype.appendChild = Presentation._Node_appendChild;
+ }
+ </script>
</body>
</html>
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index 7bbe0ae99b..d84c8bf040 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -41,6 +41,7 @@ JavaScript *JavaScript::get_singleton() {
Variant JavaScript::eval(const String& p_code, bool p_use_global_exec_context) {
union { int i; double d; char* s; } js_data[4];
+ /* clang-format off */
Variant::Type return_type = static_cast<Variant::Type>(EM_ASM_INT({
var eval_ret;
@@ -49,8 +50,7 @@ Variant JavaScript::eval(const String& p_code, bool p_use_global_exec_context) {
// indirect eval call grants global execution context
var global_eval = eval;
eval_ret = global_eval(UTF8ToString($2));
- }
- else {
+ } else {
eval_ret = eval(UTF8ToString($2));
}
} catch (e) {
@@ -125,6 +125,7 @@ Variant JavaScript::eval(const String& p_code, bool p_use_global_exec_context) {
return 0; // NIL
}, js_data, sizeof *js_data, p_code.utf8().get_data(), p_use_global_exec_context));
+ /* clang-format on */
switch(return_type) {
case Variant::BOOL:
@@ -136,7 +137,9 @@ Variant JavaScript::eval(const String& p_code, bool p_use_global_exec_context) {
case Variant::STRING:
{
String str = String::utf8(js_data->s);
+ /* clang-format off */
EM_ASM_({ _free($0); }, js_data->s);
+ /* clang-format on */
return str;
}
case Variant::VECTOR2:
@@ -153,7 +156,7 @@ Variant JavaScript::eval(const String& p_code, bool p_use_global_exec_context) {
void JavaScript::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("eval", "code", "use_global_execution_context"), &JavaScript::eval, false);
+ ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, false);
}
JavaScript::JavaScript() {
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 4c47594810..076f93f0df 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -140,10 +140,9 @@ static void _godot_draw(void) {
extern "C" {
-void main_after_fs_sync(int value) {
+void main_after_fs_sync() {
start_step=1;
- printf("FS SYNCHED!\n");
}
}
@@ -152,16 +151,15 @@ int main(int argc, char *argv[]) {
/* Initialize the window */
- printf("let it go!\n");
+ printf("let it go dude!\n");
glutInit(&argc, argv);
os = new OS_JavaScript(_gfx_init,NULL,NULL);
#if 0
char *args[]={"-test","gui","-v",NULL};
Error err = Main::setup("apk",3,args);
#else
-// char *args[]={"-v",NULL};//
-// Error err = Main::setup("",1,args);
- Error err = Main::setup("",0,NULL);
+ char *args[]={"-main_pack","data.pck",NULL}; //pass location of main pack manually, because it wont get an executable name
+ Error err = Main::setup("",2,args);
#endif
ResourceLoader::set_abort_on_missing_resources(false); //ease up compatibility
@@ -178,26 +176,27 @@ int main(int argc, char *argv[]) {
glutDisplayFunc(_godot_draw);
//glutSpecialFunc(gears_special);
-
-
- //mount persistent filesystem
- EM_ASM(
- FS.mkdir('/userfs');
- FS.mount(IDBFS, {}, '/userfs');
-
-
-
- // sync from persisted state into memory and then
- // run the 'test' function
- FS.syncfs(true, function (err) {
- assert(!err);
- console.log("done syncinc!");
- _after_sync_cb = Module.cwrap('main_after_fs_sync', 'void',['number']);
- _after_sync_cb(0);
-
- });
-
- );
+ //mount persistent file system
+ /* clang-format off */
+ EM_ASM(
+ FS.mkdir('/userfs');
+ FS.mount(IDBFS, {}, '/userfs');
+
+ // sync from persistent state into memory and then
+ // run the 'main_after_fs_sync' function
+ FS.syncfs(true, function(err) {
+
+ if (err) {
+ Module.setStatus('Failed to load persistent data\nPlease allow (third-party) cookies');
+ Module.printErr('Failed to populate IDB file system: ' + err.message);
+ Module.exit();
+ } else {
+ Module.print('Successfully populated IDB file system');
+ ccall('main_after_fs_sync', 'void', []);
+ }
+ });
+ );
+ /* clang-format on */
glutMainLoop();
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 47c8ea89d7..201008b1db 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -27,27 +27,27 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "os_javascript.h"
-#include "drivers/gles2/rasterizer_gles2.h"
+
+#include "drivers/gles3/rasterizer_gles3.h"
#include "core/io/file_access_buffered_fa.h"
#include "drivers/unix/file_access_unix.h"
#include "drivers/unix/dir_access_unix.h"
-
#include "servers/visual/visual_server_raster.h"
-
#include "main/main.h"
-
-#include "core/globals.h"
-#include "stdlib.h"
-#include "emscripten.h"
+#include "core/global_config.h"
#include "dom_keys.h"
+#include <stdlib.h>
+#include <emscripten.h>
+
int OS_JavaScript::get_video_driver_count() const {
return 1;
}
+
const char * OS_JavaScript::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ return "GLES3";
}
OS::VideoMode OS_JavaScript::get_default_video_mode() const {
@@ -215,6 +215,7 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int
// find locale, emscripten only sets "C"
char locale_ptr[16];
+ /* clang-format off */
EM_ASM_({
var locale = "";
if (Module.locale) {
@@ -230,56 +231,26 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int
locale = locale.split('.')[0];
stringToUTF8(locale, $0, 16);
}, locale_ptr);
+ /* clang-format on */
setenv("LANG", locale_ptr, true);
print_line("Init Audio");
- AudioDriverManagerSW::add_driver(&audio_driver_javascript);
+ AudioDriverManager::add_driver(&audio_driver_javascript);
+ audio_driver_javascript.set_singleton();
+ if (audio_driver_javascript.init() != OK) {
- if (true) {
- RasterizerGLES2 *rasterizer_gles22=memnew( RasterizerGLES2(false,false,false,false) );;
- rasterizer_gles22->set_use_framebuffers(false); //not supported by emscripten
- if (gl_extensions)
- rasterizer_gles22->set_extensions(gl_extensions);
- rasterizer = rasterizer_gles22;
- } else {
-// rasterizer = memnew( RasterizerGLES1(true, false) );
+ ERR_PRINT("Initializing audio failed.");
}
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+
print_line("Init VS");
- visual_server = memnew( VisualServerRaster(rasterizer) );
- visual_server->init();
+ visual_server = memnew( VisualServerRaster() );
visual_server->cursor_set_visible(false, 0);
- /*AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
-
- if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
-
- ERR_PRINT("Initializing audio failed.");
- }*/
-
- print_line("Init SM");
-
- //sample_manager = memnew( SampleManagerMallocSW );
- audio_server = memnew( AudioServerJavascript );
-
- print_line("Init Mixer");
-
- //audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false);
- audio_server->init();
-
- print_line("Init SoundServer");
-
- spatial_sound_server = memnew( SpatialSoundServerSW );
- spatial_sound_server->init();
-
- print_line("Init SpatialSoundServer");
-
- spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
- spatial_sound_2d_server->init();
-
- //
print_line("Init Physicsserver");
physics_server = memnew( PhysicsServerSW );
@@ -311,6 +282,8 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int
javascript_eval = memnew(JavaScript);
GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("JavaScript", javascript_eval));
#endif
+
+ visual_server->init();
}
void OS_JavaScript::set_main_loop( MainLoop * p_main_loop ) {
@@ -332,9 +305,11 @@ void OS_JavaScript::finalize() {
void OS_JavaScript::alert(const String& p_alert,const String& p_title) {
+ /* clang-format off */
EM_ASM_({
window.alert(UTF8ToString($0));
}, p_alert.utf8().get_data());
+ /* clang-format on */
}
@@ -366,9 +341,11 @@ int OS_JavaScript::get_mouse_button_state() const {
void OS_JavaScript::set_window_title(const String& p_title) {
+ /* clang-format off */
EM_ASM_({
document.title = UTF8ToString($0);
}, p_title.utf8().get_data());
+ /* clang-format on */
}
//interesting byt not yet
@@ -424,8 +401,10 @@ void OS_JavaScript::set_window_maximized(bool p_enabled) {
set_window_fullscreen(false);
}
else {
+ /* clang-format off */
video_mode.width = EM_ASM_INT_V(return window.innerWidth);
video_mode.height = EM_ASM_INT_V(return window.innerHeight);
+ /* clang-format on */
emscripten_set_canvas_size(video_mode.width, video_mode.height);
}
}
@@ -444,7 +423,9 @@ void OS_JavaScript::set_window_fullscreen(bool p_enable) {
// _browser_resize_callback or _fullscreen_change_callback
EMSCRIPTEN_RESULT result;
if (p_enable) {
+ /* clang-format off */
EM_ASM(Module.requestFullscreen(false, false););
+ /* clang-format on */
}
else {
result = emscripten_exit_fullscreen();
@@ -502,19 +483,15 @@ bool OS_JavaScript::main_loop_iterate() {
time_to_save_sync-=elapsed;
- print_line("elapsed "+itos(elapsed)+" tts "+itos(time_to_save_sync));
-
if (time_to_save_sync<0) {
//time to sync, for real
- // run 'success'
- print_line("DOING SYNCH!");
+ /* clang-format off */
EM_ASM(
- FS.syncfs(function (err) {
- assert(!err);
- console.log("Synched!");
- //ccall('success', 'v');
- });
+ FS.syncfs(function(err) {
+ if (err) { Module.printErr('Failed to save IDB file system: ' + err.message); }
+ });
);
+ /* clang-format on */
}
@@ -561,7 +538,7 @@ void OS_JavaScript::push_input(const InputEvent& p_ev) {
void OS_JavaScript::process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points) {
-// print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
+ //print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
switch(p_what) {
case 0: { //gesture begin
@@ -644,8 +621,8 @@ void OS_JavaScript::process_touch(int p_what,int p_pointer, const Vector<TouchPo
ev.mouse_motion.x=p_points[0].pos.x;
ev.mouse_motion.y=p_points[0].pos.y;
input->set_mouse_pos(Point2(ev.mouse_motion.x,ev.mouse_motion.y));
- ev.mouse_motion.speed_x=input->get_mouse_speed().x;
- ev.mouse_motion.speed_y=input->get_mouse_speed().y;
+ ev.mouse_motion.speed_x=input->get_last_mouse_speed().x;
+ ev.mouse_motion.speed_y=input->get_last_mouse_speed().y;
ev.mouse_motion.relative_x=p_points[0].pos.x-last_mouse.x;
ev.mouse_motion.relative_y=p_points[0].pos.y-last_mouse.y;
last_mouse=p_points[0].pos;
@@ -782,18 +759,12 @@ void OS_JavaScript::main_loop_request_quit() {
main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
}
-void OS_JavaScript::reload_gfx() {
-
- if (gfx_init_func)
- gfx_init_func(gfx_init_ud,use_gl2,video_mode.width,video_mode.height,video_mode.fullscreen);
- if (rasterizer)
- rasterizer->reload_vram();
-}
-
Error OS_JavaScript::shell_open(String p_uri) {
+ /* clang-format off */
EM_ASM_({
window.open(UTF8ToString($0), '_blank');
}, p_uri.utf8().get_data());
+ /* clang-format on */
return OK;
}
@@ -804,8 +775,10 @@ String OS_JavaScript::get_resource_dir() const {
String OS_JavaScript::get_data_dir() const {
- //if (get_data_dir_func)
- // return get_data_dir_func();
+ /*
+ if (get_data_dir_func)
+ return get_data_dir_func();
+ */
return "/userfs";
//return GlobalConfig::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir");
};
@@ -888,7 +861,6 @@ OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, Get
main_loop=NULL;
last_id=1;
gl_extensions=NULL;
- rasterizer=NULL;
window_maximized=false;
get_data_dir_func=p_get_data_dir_func;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 370322e93d..582f128ce8 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -33,17 +33,16 @@
#include "drivers/unix/os_unix.h"
#include "os/main_loop.h"
#include "servers/physics/physics_server_sw.h"
-#include "servers/spatial_sound/spatial_sound_server_sw.h"
-#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
-#include "servers/audio/audio_server_sw.h"
+#include "servers/audio_server.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/visual/rasterizer.h"
#include "audio_server_javascript.h"
#include "audio_driver_javascript.h"
#include "main/input_default.h"
-#include "emscripten/html5.h"
#include "javascript_eval.h"
+#include <emscripten/html5.h>
+
typedef void (*GFXInitFunc)(void *ud,bool gl2,int w, int h, bool fs);
typedef String (*GetDataDirFunc)();
@@ -69,12 +68,7 @@ private:
int64_t time_to_save_sync;
int64_t last_sync_time;
- Rasterizer *rasterizer;
VisualServer *visual_server;
- AudioServerJavascript *audio_server;
- //SampleManagerMallocSW *sample_manager;
- SpatialSoundServerSW *spatial_sound_server;
- SpatialSound2DServerSW *spatial_sound_2d_server;
PhysicsServer *physics_server;
Physics2DServer *physics_2d_server;
AudioDriverJavaScript audio_driver_javascript;
@@ -168,8 +162,6 @@ public:
void set_opengl_extensions(const char* p_gl_extensions);
- void reload_gfx();
-
virtual Error shell_open(String p_uri);
virtual String get_data_dir() const;
String get_executable_path() const;