diff options
Diffstat (limited to 'platform/javascript')
| -rw-r--r-- | platform/javascript/SCsub | 25 | ||||
| -rw-r--r-- | platform/javascript/audio_driver_javascript.cpp | 91 | ||||
| -rw-r--r-- | platform/javascript/audio_driver_javascript.h | 56 | ||||
| -rw-r--r-- | platform/javascript/detect.py | 102 | ||||
| -rw-r--r-- | platform/javascript/export/export.cpp | 452 | ||||
| -rw-r--r-- | platform/javascript/export/export.h | 29 | ||||
| -rw-r--r-- | platform/javascript/javascript_main.cpp | 251 | ||||
| -rw-r--r-- | platform/javascript/logo.png | bin | 0 -> 4807 bytes | |||
| -rw-r--r-- | platform/javascript/os_javascript.cpp | 593 | ||||
| -rw-r--r-- | platform/javascript/os_javascript.h | 164 | ||||
| -rw-r--r-- | platform/javascript/platform_config.h | 29 |
11 files changed, 1792 insertions, 0 deletions
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub new file mode 100644 index 000000000..fd1bb39e9 --- /dev/null +++ b/platform/javascript/SCsub @@ -0,0 +1,25 @@ +Import('env') + +javascript_files = [ + "os_javascript.cpp", + "audio_driver_javascript.cpp", + "javascript_main.cpp" +] + +#env.Depends('#core/math/vector3.h', 'vector3_psp.h') + +#obj = env.SharedObject('godot_javascript.cpp') + +env_javascript = env.Clone() +if env['target'] == "profile": + env_javascript.Append(CPPFLAGS=['-DPROFILER_ENABLED']) + +javascript_objects=[] +for x in javascript_files: + javascript_objects.append( env_javascript.Object( x ) ) + +prog = None + +#env_javascript.SharedLibrary("#platform/javascript/libgodot_javascript.so",[javascript_objects]) + +env.Program('#bin/godot.html', javascript_objects) diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp new file mode 100644 index 000000000..2a77806fb --- /dev/null +++ b/platform/javascript/audio_driver_javascript.cpp @@ -0,0 +1,91 @@ +/*************************************************************************/ +/* audio_driver_javascript.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "audio_driver_javascript.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 { + + return "JavaScript"; +} + +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; +} +void AudioDriverJavaScript::lock(){ + + //if (active && mutex) + // mutex->lock(); + +} +void AudioDriverJavaScript::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 new file mode 100644 index 000000000..9fe93c56a --- /dev/null +++ b/platform/javascript/audio_driver_javascript.h @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* audio_driver_javascript.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef AUDIO_DRIVER_JAVASCRIPT_H +#define AUDIO_DRIVER_JAVASCRIPT_H + + +#include "servers/audio/audio_server_sw.h" +#include "os/mutex.h" + +class AudioDriverJavaScript : public AudioDriverSW { +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 void lock(); + virtual void unlock(); + virtual void finish(); + + + AudioDriverJavaScript(); +}; + + +#endif diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py new file mode 100644 index 000000000..da92c0869 --- /dev/null +++ b/platform/javascript/detect.py @@ -0,0 +1,102 @@ +import os +import sys +import string + +def is_active(): + return True + +def get_name(): + return "JavaScript" + +def can_build(): + + import os + if (not os.environ.has_key("EMSCRIPTEN_ROOT")): + return False + return True + +def get_opts(): + + return [ + ['compress','Compress JS Executable','no'] + ] + +def get_flags(): + + return [ + ('lua', 'no'), + ('tools', 'no'), + ('nedmalloc', 'no'), + ('theora', 'no'), + ('tools', 'no'), + ('nedmalloc', 'no'), + ('vorbis', 'yes'), + ('musepack', 'no'), + ('squirrel', 'no'), + ('squish', 'no'), + ('speex', 'no'), + ('old_scenes', 'no'), +# ('default_gui_theme', 'no'), + + #('builtin_zlib', 'no'), + ] + + + +def configure(env): + + + env.Append(CPPPATH=['#platform/android']) + + env['OBJSUFFIX'] = ".js.o" + env['LIBSUFFIX'] = ".js.a" + env['PROGSUFFIX'] = ".html" + + 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['RANLIB'] = em_path+"/emranlib" + +# 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']) + env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX'] + env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX'] + + elif (env["target"]=="release_debug"): + + env.Append(CCFLAGS=['-O2','-DDEBUG_ENABLED']) + env['OBJSUFFIX'] = "_optd"+env['OBJSUFFIX'] + env['LIBSUFFIX'] = "_optd"+env['LIBSUFFIX'] + + elif (env["target"]=="debug"): + + env.Append(CCFLAGS=['-D_DEBUG', '-Wall', '-O2', '-DDEBUG_ENABLED']) + env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']) + + env.Append(CPPFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST','-fno-rtti']) + env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-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','ASM_JS=1']) + env.Append(CPPFLAGS=['-s','FULL_ES2=1']) +# env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT']) + if (env["compress"]=="yes"): + lzma_binpath = em_path+"/third_party/lzma.js/lzma-native" + lzma_decoder = em_path+"/third_party/lzma.js/lzma-decoder.js" + lzma_dec = "LZMA.decompress" + + env.Append(LINKFLAGS=['--compression',lzma_binpath+","+lzma_decoder+","+lzma_dec]) + + env.Append(LINKFLAGS=['-s','ASM_JS=1']) + env.Append(LINKFLAGS=['-O2']) + + diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp new file mode 100644 index 000000000..a81fabe08 --- /dev/null +++ b/platform/javascript/export/export.cpp @@ -0,0 +1,452 @@ +/*************************************************************************/ +/* export.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "version.h" +#include "export.h" +#include "tools/editor/editor_settings.h" +#include "tools/editor/editor_import_export.h" +#include "tools/editor/editor_node.h" +#include "io/zip_io.h" +#include "io/marshalls.h" +#include "globals.h" +#include "os/file_access.h" +#include "os/os.h" +#include "platform/javascript/logo.h" +#include "string.h" +class EditorExportPlatformJavaScript : public EditorExportPlatform { + + OBJ_TYPE( EditorExportPlatformJavaScript,EditorExportPlatform ); + + String custom_release_package; + String custom_debug_package; + + enum PackMode { + PACK_SINGLE_FILE, + PACK_MULTIPLE_FILES + }; + + + PackMode pack_mode; + + bool show_run; + + int max_memory; + int version_code; + + Ref<ImageTexture> logo; + + static Error save_pack_file_js(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total); + +protected: + + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; + +public: + + virtual String get_name() const { return "HTML5"; } + virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; } + virtual Ref<Texture> get_logo() const { return logo; } + + + virtual bool poll_devices() { return show_run?true:false;} + virtual int get_device_count() const { return show_run?1:0; }; + virtual String get_device_name(int p_device) const { return "Run in Browser"; } + virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; } + virtual Error run(int p_device); + + virtual bool requieres_password(bool p_debug) const { return false; } + virtual String get_binary_extension() const { return "html"; } + virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + + virtual bool can_export(String *r_error=NULL) const; + + EditorExportPlatformJavaScript(); + ~EditorExportPlatformJavaScript(); +}; + +bool EditorExportPlatformJavaScript::_set(const StringName& p_name, const Variant& p_value) { + + String n=p_name; + + if (n=="custom_package/debug") + custom_debug_package=p_value; + else if (n=="custom_package/release") + custom_release_package=p_value; + else if (n=="browser/enable_run") + show_run=p_value; + else if (n=="options/memory_size") + max_memory=p_value; + else if (n=="options/pack_mode") + pack_mode=PackMode(int(p_value)); + else + return false; + + return true; +} + +bool EditorExportPlatformJavaScript::_get(const StringName& p_name,Variant &r_ret) const{ + + String n=p_name; + + if (n=="custom_package/debug") + r_ret=custom_debug_package; + else if (n=="custom_package/release") + r_ret=custom_release_package; + else if (n=="browser/enable_run") + r_ret=show_run; + else if (n=="options/memory_size") + r_ret=max_memory; + else if (n=="options/pack_mode") + r_ret=pack_mode; + else + return false; + + return true; +} +void EditorExportPlatformJavaScript::_get_property_list( List<PropertyInfo> *p_list) const{ + + p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_FILE,"zip")); + p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_FILE,"zip")); + p_list->push_back( PropertyInfo( Variant::INT, "options/pack_mode",PROPERTY_HINT_ENUM,"Single File, Multiple Files")); + p_list->push_back( PropertyInfo( Variant::INT, "options/memory_size",PROPERTY_HINT_ENUM,"32mb,64mb,128mb,256mb,512mb,1024mb")); + p_list->push_back( PropertyInfo( Variant::BOOL, "browser/enable_run")); + + //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)")); + +} + + +static const char* files_pre=""\ +"var Module;\n"\ +"if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');\n"\ +"if (!Module.expectedDataFileDownloads) {\n"\ +" Module.expectedDataFileDownloads = 0;\n"\ +" Module.finishedDataFileDownloads = 0;\n"\ +"}\n"\ +"Module.expectedDataFileDownloads++;\n"\ +"(function() {\n"\ +"\n"\ +" function runWithFS() {\n"\ +"function assert(check, msg) {\n"\ +" if (!check) throw msg + new Error().stack;\n"\ +"} \n"; + +static const char* files_post=""\ +"}\n"\ +"if (Module['calledRun']) {\n"\ +" runWithFS();\n"\ +"} else {\n"\ +" if (!Module['preRun']) Module['preRun'] = [];\n"\ +" Module[\"preRun\"].push(runWithFS); // FS is not initialized yet, wait for it\n"\ +"}\n"\ +"})();"; + + +static void _fix_html(Vector<uint8_t>& html,const String& name,int max_memory) { + + + String str; + String strnew; + str.parse_utf8((const char*)html.ptr(),html.size()); + Vector<String> lines=str.split("\n"); + for(int i=0;i<lines.size();i++) { + if (lines[i].find("godot.js")!=-1) { + strnew+="<script type=\"text/javascript\" src=\""+name+"_files.js\"></script>\n"; + strnew+="<script async type=\"text/javascript\" src=\""+name+".js\"></script>\n"; + } else if (lines[i].find("var Module")!=-1) { + strnew+=lines[i]; + strnew+="TOTAL_MEMORY:"+itos(max_memory*1024*1024)+","; + } else { + strnew+=lines[i]+"\n"; + } + } + + CharString cs = strnew.utf8(); + html.resize(cs.size()); + for(int i=9;i<cs.size();i++) { + html[i]=cs[i]; + } +} + + +struct JSExportData { + + EditorProgress *ep; + FileAccess *f; + +}; + + +static void store_file_buffer(FileAccess*f,const String& p_path,const Vector<uint8_t>& p_data) { + + + String pre = "Module['FS_createDataFile']('/', '"+p_path.replace("res://","")+"',["; + CharString cs = pre.utf8(); + f->store_buffer((const uint8_t*)cs.ptr(),cs.length()); + for(int i=0;i<p_data.size();i++) { + + + uint8_t c=','; + if (i>0) + f->store_buffer(&c,1); + + uint8_t str[4]; + uint8_t d = p_data[i]; + if (d<10) { + str[0]='0'+d; + str[1]=0; + f->store_buffer(str,1); + } else if (d<100) { + + str[0]='0'+d/10; + str[1]='0'+d%10; + str[2]=0; + f->store_buffer(str,2); + + } else { + str[0]='0'+d/100; + str[1]='0'+(d/10)%10; + str[2]='0'+d%10; + str[3]=0; + f->store_buffer(str,3); + } + } + String post = "],true,true);\n"; + cs = post.utf8(); + f->store_buffer((const uint8_t*)cs.ptr(),cs.length()); +} + + +Error EditorExportPlatformJavaScript::save_pack_file_js(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { + + JSExportData *ed=(JSExportData*)p_userdata; + + FileAccess *f=(FileAccess *)p_userdata; + store_file_buffer(ed->f,p_path,p_data); + ed->ep->step("File: "+p_path,3+p_file*100/p_total); + return OK; + +} + +Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p_debug,const String& p_password) { + + + String src_template; + + EditorProgress ep("export","Exporting for javascript",104); + + String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/"; + + if (p_debug) { + + src_template=custom_debug_package!=""?custom_debug_package:template_path+"javascript_debug.zip"; + } else { + + src_template=custom_release_package!=""?custom_release_package:template_path+"javascript_release.zip"; + + } + + + FileAccess *src_f=NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + + ep.step("Exporting to HTML5",0); + + unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io); + if (!pkg) { + + EditorNode::add_io_error("Could not find template HTML5 to export:\n"+src_template); + return ERR_FILE_NOT_FOUND; + } + + ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); + int ret = unzGoToFirstFile(pkg); + + + while(ret==UNZ_OK) { + + //get filename + unz_file_info info; + char fname[16384]; + ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); + + String file=fname; + + Vector<uint8_t> data; + data.resize(info.uncompressed_size); + + //read + unzOpenCurrentFile(pkg); + unzReadCurrentFile(pkg,data.ptr(),data.size()); + unzCloseCurrentFile(pkg); + + //write + + if (file=="godot.html") { + + _fix_html(data,p_path.get_file().basename(),1<<(max_memory+5)); + file=p_path.get_file(); + } + if (file=="godot.js") { + + //_fix_godot(data); + file=p_path.get_file().basename()+".js"; + } + + String dst = p_path.get_base_dir().plus_file(file); + FileAccess *f=FileAccess::open(dst,FileAccess::WRITE); + if (!f) { + EditorNode::add_io_error("Could not create file for writing:\n"+dst); + unzClose(pkg); + return ERR_FILE_CANT_WRITE; + } + f->store_buffer(data.ptr(),data.size()); + memdelete(f); + + + ret = unzGoToNextFile(pkg); + } + + + ep.step("Finding Files..",1); + + Vector<String> remaps; + + FileAccess *f=FileAccess::open(p_path.basename()+"_files.js",FileAccess::WRITE); + if (!f) { + EditorNode::add_io_error("Could not create file for writing:\n"+p_path.basename()+"_files.js"); + return ERR_FILE_CANT_WRITE; + } + + f->store_buffer((const uint8_t*)files_pre,strlen(files_pre)); + + if (pack_mode==PACK_SINGLE_FILE) { + + String ftmp = EditorSettings::get_singleton()->get_settings_path()+"/tmp/webpack.pck"; + FileAccess *f2 = FileAccess::open(ftmp,FileAccess::WRITE); + if (!f2) { + memdelete(f); + return ERR_CANT_CREATE; + } + Error err = save_pack(f2,false); + memdelete(f2); + if (err) { + memdelete(f); + return ERR_CANT_CREATE; + } + + Vector<uint8_t> data = FileAccess::get_file_as_array(ftmp); + store_file_buffer(f,"data.pck",data); + + + } else { + JSExportData ed; + ed.ep=&ep; + ed.f=f; + + Error err =export_project_files(save_pack_file_js,&ed,false); + if (err) + return err; + } + f->store_buffer((const uint8_t*)files_post,strlen(files_post)); + memdelete(f); + + + return OK; + +} + + +Error EditorExportPlatformJavaScript::run(int p_device) { + + String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html"; + Error err = export_project(path,true,""); + if (err) + return err; + + OS::get_singleton()->shell_open(path); + + return OK; +} + + +EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { + + show_run=false; + Image img( _javascript_logo ); + logo = Ref<ImageTexture>( memnew( ImageTexture )); + logo->create_from_image(img); + max_memory=3; + pack_mode=PACK_SINGLE_FILE; +} + +bool EditorExportPlatformJavaScript::can_export(String *r_error) const { + + + bool valid=true; + String err; + String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/"; + + if (!FileAccess::exists(exe_path+"javascript_debug.zip") || !FileAccess::exists(exe_path+"javascript_release.zip")) { + valid=false; + err+="No export templates found.\nDownload and install export templates.\n"; + } + + if (custom_debug_package!="" && !FileAccess::exists(custom_debug_package)) { + valid=false; + err+="Custom debug package not found.\n"; + } + + if (custom_release_package!="" && !FileAccess::exists(custom_release_package)) { + valid=false; + err+="Custom release package not found.\n"; + } + + if (r_error) + *r_error=err; + + return valid; +} + + +EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() { + +} + + +void register_javascript_exporter() { + + + Ref<EditorExportPlatformJavaScript> exporter = Ref<EditorExportPlatformJavaScript>( memnew(EditorExportPlatformJavaScript) ); + EditorImportExport::get_singleton()->add_export_platform(exporter); + + +} + diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h new file mode 100644 index 000000000..2b575c914 --- /dev/null +++ b/platform/javascript/export/export.h @@ -0,0 +1,29 @@ +/*************************************************************************/ +/* export.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +void register_javascript_exporter(); diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp new file mode 100644 index 000000000..81485bab8 --- /dev/null +++ b/platform/javascript/javascript_main.cpp @@ -0,0 +1,251 @@ +/*************************************************************************/ +/* javascript_main.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include <GL/glut.h> +#include "os_javascript.h" +#include "main/main.h" +#include "io/resource_loader.h" +#include "os/keyboard.h" +OS_JavaScript *os=NULL; + +static void _gfx_init(void *ud,bool gl2,int w, int h,bool fs) { + + glutInitWindowSize(w, h); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutCreateWindow("godot"); + +} + + +static void _glut_skey(bool pressed,int key) { + + InputEvent ev; + ev.type=InputEvent::KEY; + ev.key.pressed=pressed; + switch(key) { + case GLUT_KEY_F1: ev.key.scancode=KEY_F1; break; + case GLUT_KEY_F2: ev.key.scancode=KEY_F2; break; + case GLUT_KEY_F3: ev.key.scancode=KEY_F3; break; + case GLUT_KEY_F4: ev.key.scancode=KEY_F4; break; + case GLUT_KEY_F5: ev.key.scancode=KEY_F5; break; + case GLUT_KEY_F6: ev.key.scancode=KEY_F6; break; + case GLUT_KEY_F7: ev.key.scancode=KEY_F7; break; + case GLUT_KEY_F8: ev.key.scancode=KEY_F8; break; + case GLUT_KEY_F9: ev.key.scancode=KEY_F9; break; + case GLUT_KEY_F10: ev.key.scancode=KEY_F10; break; + case GLUT_KEY_F11: ev.key.scancode=KEY_F11; break; + case GLUT_KEY_F12: ev.key.scancode=KEY_F12; break; + case GLUT_KEY_LEFT: ev.key.scancode=KEY_LEFT; break; + case GLUT_KEY_UP: ev.key.scancode=KEY_UP; break; + case GLUT_KEY_RIGHT: ev.key.scancode=KEY_RIGHT; break; + case GLUT_KEY_DOWN: ev.key.scancode=KEY_DOWN; break; + case GLUT_KEY_PAGE_UP: ev.key.scancode=KEY_PAGEUP; break; + case GLUT_KEY_PAGE_DOWN: ev.key.scancode=KEY_PAGEDOWN; break; + case GLUT_KEY_HOME: ev.key.scancode=KEY_HOME; break; + case GLUT_KEY_END: ev.key.scancode=KEY_END; break; + case GLUT_KEY_INSERT: ev.key.scancode=KEY_INSERT; break; + } + + + uint32_t m = glutGetModifiers(); + ev.key.mod.alt=(m&GLUT_ACTIVE_ALT)!=0; + ev.key.mod.shift=(m&GLUT_ACTIVE_SHIFT)!=0; + ev.key.mod.control=(m&GLUT_ACTIVE_CTRL)!=0; + + os->push_input(ev); +} + +static void _glut_skey_up(int key, int x, int y) { + + _glut_skey(false,key); +} + +static void _glut_skey_down(int key, int x, int y) { + + _glut_skey(true,key); +} + +static void _glut_key(bool pressed,unsigned char key) { + + InputEvent ev; + ev.type=InputEvent::KEY; + ev.key.pressed=pressed; + switch(key) { + case '\n': ev.key.scancode=KEY_RETURN; break; + case 0x1b: ev.key.scancode=KEY_ESCAPE; break; + case 8: ev.key.scancode=KEY_BACKSPACE; break; + case 0x7f: ev.key.scancode=KEY_DELETE; break; + case 0x20: ev.key.scancode=KEY_SPACE; ev.key.unicode=key; break; + default: { + ev.key.unicode=key; + } + } + + + uint32_t m = glutGetModifiers(); + ev.key.mod.alt=(m&GLUT_ACTIVE_ALT)!=0; + ev.key.mod.shift=(m&GLUT_ACTIVE_SHIFT)!=0; + ev.key.mod.control=(m&GLUT_ACTIVE_CTRL)!=0; + + os->push_input(ev); + +} + +static void _glut_key_up(unsigned char key, int x, int y) { + + _glut_key(false,key); +} + +static void _glut_key_down(unsigned char key, int x, int y) { + + _glut_key(true,key); +} + +static uint32_t _mouse_button_mask=0; + +static void _glut_mouse_button(int button, int state, int x, int y) { + + InputEvent ev; + ev.type=InputEvent::MOUSE_BUTTON; + switch(button) { + case GLUT_LEFT_BUTTON: ev.mouse_button.button_index=BUTTON_LEFT; break; + case GLUT_MIDDLE_BUTTON: ev.mouse_button.button_index=BUTTON_MIDDLE; break; + case GLUT_RIGHT_BUTTON: ev.mouse_button.button_index=BUTTON_RIGHT; break; + case 3: ev.mouse_button.button_index=BUTTON_WHEEL_UP; break; + case 4: ev.mouse_button.button_index=BUTTON_WHEEL_DOWN; break; + } + + + ev.mouse_button.pressed=state==GLUT_DOWN; + ev.mouse_button.x=x; + ev.mouse_button.y=y; + ev.mouse_button.global_x=x; + ev.mouse_button.global_y=y; + + if (ev.mouse_button.button_index<4) { + if (ev.mouse_button.pressed) { + _mouse_button_mask|=1<<ev.mouse_button.button_index; + } else { + _mouse_button_mask&=~(1<<ev.mouse_button.button_index); + } + } + + uint32_t m = glutGetModifiers(); + ev.mouse_button.mod.alt=(m&GLUT_ACTIVE_ALT)!=0; + ev.mouse_button.mod.shift=(m&GLUT_ACTIVE_SHIFT)!=0; + ev.mouse_button.mod.control=(m&GLUT_ACTIVE_CTRL)!=0; + + os->push_input(ev); + +} + + +static int _glut_prev_x=0; +static int _glut_prev_y=0; + +static void _glut_mouse_motion(int x, int y) { + + InputEvent ev; + ev.type=InputEvent::MOUSE_MOTION; + ev.mouse_motion.button_mask=_mouse_button_mask; + ev.mouse_motion.x=x; + ev.mouse_motion.y=y; + ev.mouse_motion.global_x=x; + ev.mouse_motion.global_y=y; + ev.mouse_motion.relative_x=x-_glut_prev_x; + ev.mouse_motion.relative_y=y-_glut_prev_y; + _glut_prev_x=x; + _glut_prev_y=y; + + uint32_t m = glutGetModifiers(); + ev.mouse_motion.mod.alt=(m&GLUT_ACTIVE_ALT)!=0; + ev.mouse_motion.mod.shift=(m&GLUT_ACTIVE_SHIFT)!=0; + ev.mouse_motion.mod.control=(m&GLUT_ACTIVE_CTRL)!=0; + + os->push_input(ev); + +} + +static void _gfx_idle() { + + glutPostRedisplay(); +} + +static void _godot_draw(void) { + + os->main_loop_iterate(); + glutSwapBuffers(); +} + +int main(int argc, char *argv[]) { + /* Initialize the window */ + + printf("let it go!\n"); + glutInit(&argc, argv); + os = new OS_JavaScript(_gfx_init,NULL,NULL,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); + +#endif + ResourceLoader::set_abort_on_missing_resources(false); //ease up compatibility + Main::start(); + + glutSpecialUpFunc(_glut_skey_up); + glutSpecialFunc(_glut_skey_down); + glutKeyboardUpFunc(_glut_key_up); + glutKeyboardFunc(_glut_key_down); + glutMouseFunc(_glut_mouse_button); + glutMotionFunc(_glut_mouse_motion); + glutMotionFunc(_glut_mouse_motion); + glutPassiveMotionFunc(_glut_mouse_motion); + + + + /* Set up glut callback functions */ + glutIdleFunc (_gfx_idle); +// glutReshapeFunc(gears_reshape); + glutDisplayFunc(_godot_draw); + //glutSpecialFunc(gears_special); + os->main_loop_begin(); + + glutMainLoop(); + + return 0; +} + + +/* + * + *09] <azakai|2__> reduz: yes, define TOTAL_MEMORY on Module. for example var Module = { TOTAL_MEMORY: 12345.. }; before the main + * + */ diff --git a/platform/javascript/logo.png b/platform/javascript/logo.png Binary files differnew file mode 100644 index 000000000..07e0a4129 --- /dev/null +++ b/platform/javascript/logo.png diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp new file mode 100644 index 000000000..c131a7e84 --- /dev/null +++ b/platform/javascript/os_javascript.cpp @@ -0,0 +1,593 @@ +/*************************************************************************/ +/* os_javascript.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "os_javascript.h" +#include "drivers/gles2/rasterizer_gles2.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" + +int OS_JavaScript::get_video_driver_count() const { + + return 1; +} +const char * OS_JavaScript::get_video_driver_name(int p_driver) const { + + return "GLES2"; +} + +OS::VideoMode OS_JavaScript::get_default_video_mode() const { + + return OS::VideoMode(); +} + +int OS_JavaScript::get_audio_driver_count() const { + + return 1; +} + +const char * OS_JavaScript::get_audio_driver_name(int p_driver) const { + + return "JavaScript"; +} + +void OS_JavaScript::initialize_core() { + + OS_Unix::initialize_core(); + FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES); + +} + +void OS_JavaScript::set_opengl_extensions(const char* p_gl_extensions) { + + ERR_FAIL_COND(!p_gl_extensions); + gl_extensions=p_gl_extensions; +} + +void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { + + print_line("Init OS"); + + if (gfx_init_func) + gfx_init_func(gfx_init_ud,use_gl2,p_desired.width,p_desired.height,p_desired.fullscreen); + + default_videomode=p_desired; + + print_line("Init Audio"); + + AudioDriverManagerSW::add_driver(&audio_driver_javascript); + + 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) ); + } + + print_line("Init VS"); + + visual_server = memnew( VisualServerRaster(rasterizer) ); + visual_server->init(); + 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( AudioServerSW(sample_manager) ); + + 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 ); + physics_server->init(); + physics_2d_server = memnew( Physics2DServerSW ); + physics_2d_server->init(); + + input = memnew( InputDefault ); + +} + +void OS_JavaScript::set_main_loop( MainLoop * p_main_loop ) { + + main_loop=p_main_loop; + input->set_main_loop(p_main_loop); + +} + +void OS_JavaScript::delete_main_loop() { + + memdelete( main_loop ); +} + +void OS_JavaScript::finalize() { + + memdelete(input); +} + + +void OS_JavaScript::vprint(const char* p_format, va_list p_list, bool p_stderr) { + + if (p_stderr) { + + vfprintf(stderr,p_format,p_list); + fflush(stderr); + } else { + + vprintf(p_format,p_list); + fflush(stdout); + } +} + +void OS_JavaScript::print(const char *p_format, ... ) { + + va_list argp; + va_start(argp, p_format); + vprintf(p_format, argp ); + va_end(argp); + +} + +void OS_JavaScript::alert(const String& p_alert) { + + print("ALERT: %s\n",p_alert.utf8().get_data()); +} + + +void OS_JavaScript::set_mouse_show(bool p_show) { + + //javascript has no mouse... +} + +void OS_JavaScript::set_mouse_grab(bool p_grab) { + + //it really has no mouse...! +} + +bool OS_JavaScript::is_mouse_grab_enabled() const { + + //*sigh* technology has evolved so much since i was a kid.. + return false; +} +Point2 OS_JavaScript::get_mouse_pos() const { + + return Point2(); +} +int OS_JavaScript::get_mouse_button_state() const { + + return 0; +} +void OS_JavaScript::set_window_title(const String& p_title) { + + +} + +//interesting byt not yet +//void set_clipboard(const String& p_text); +//String get_clipboard() const; + +void OS_JavaScript::set_video_mode(const VideoMode& p_video_mode,int p_screen) { + + +} + +OS::VideoMode OS_JavaScript::get_video_mode(int p_screen) const { + + return default_videomode; +} +void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { + + p_list->push_back(default_videomode); +} + +String OS_JavaScript::get_name() { + + return "HTML5"; +} + +MainLoop *OS_JavaScript::get_main_loop() const { + + return main_loop; +} + +bool OS_JavaScript::can_draw() const { + + return true; //always? +} + +void OS_JavaScript::set_cursor_shape(CursorShape p_shape) { + + //javascript really really really has no mouse.. how amazing.. +} + +void OS_JavaScript::main_loop_begin() { + + if (main_loop) + main_loop->init(); +} +bool OS_JavaScript::main_loop_iterate() { + + if (!main_loop) + return false; + return Main::iteration(); +} + +void OS_JavaScript::main_loop_end() { + + if (main_loop) + main_loop->finish(); + +} + +void OS_JavaScript::main_loop_focusout() { + + if (main_loop) + main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); + //audio_driver_javascript.set_pause(true); + +} + +void OS_JavaScript::main_loop_focusin(){ + + if (main_loop) + main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); + //audio_driver_javascript.set_pause(false); + +} + +void OS_JavaScript::push_input(const InputEvent& p_ev) { + + InputEvent ev = p_ev; + ev.ID=last_id++; + input->parse_input_event(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())); + + switch(p_what) { + case 0: { //gesture begin + + if (touch.size()) { + //end all if exist + InputEvent ev; + ev.type=InputEvent::MOUSE_BUTTON; + ev.ID=last_id++; + ev.mouse_button.button_index=BUTTON_LEFT; + ev.mouse_button.button_mask=BUTTON_MASK_LEFT; + ev.mouse_button.pressed=false; + ev.mouse_button.x=touch[0].pos.x; + ev.mouse_button.y=touch[0].pos.y; + ev.mouse_button.global_x=touch[0].pos.x; + ev.mouse_button.global_y=touch[0].pos.y; + input->parse_input_event(ev); + + + for(int i=0;i<touch.size();i++) { + + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.ID=last_id++; + ev.screen_touch.index=touch[i].id; + ev.screen_touch.pressed=false; + ev.screen_touch.x=touch[i].pos.x; + ev.screen_touch.y=touch[i].pos.y; + input->parse_input_event(ev); + + } + } + + touch.resize(p_points.size()); + for(int i=0;i<p_points.size();i++) { + touch[i].id=p_points[i].id; + touch[i].pos=p_points[i].pos; + } + + { + //send mouse + InputEvent ev; + ev.type=InputEvent::MOUSE_BUTTON; + ev.ID=last_id++; + ev.mouse_button.button_index=BUTTON_LEFT; + ev.mouse_button.button_mask=BUTTON_MASK_LEFT; + ev.mouse_button.pressed=true; + ev.mouse_button.x=touch[0].pos.x; + ev.mouse_button.y=touch[0].pos.y; + ev.mouse_button.global_x=touch[0].pos.x; + ev.mouse_button.global_y=touch[0].pos.y; + last_mouse=touch[0].pos; + input->parse_input_event(ev); + } + + + //send touch + for(int i=0;i<touch.size();i++) { + + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.ID=last_id++; + ev.screen_touch.index=touch[i].id; + ev.screen_touch.pressed=true; + ev.screen_touch.x=touch[i].pos.x; + ev.screen_touch.y=touch[i].pos.y; + input->parse_input_event(ev); + } + + } break; + case 1: { //motion + + + if (p_points.size()) { + //send mouse, should look for point 0? + InputEvent ev; + ev.type=InputEvent::MOUSE_MOTION; + ev.ID=last_id++; + ev.mouse_motion.button_mask=BUTTON_MASK_LEFT; + 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.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; + input->parse_input_event(ev); + } + + ERR_FAIL_COND(touch.size()!=p_points.size()); + + for(int i=0;i<touch.size();i++) { + + int idx=-1; + for(int j=0;j<p_points.size();j++) { + + if (touch[i].id==p_points[j].id) { + idx=j; + break; + } + + } + + ERR_CONTINUE(idx==-1); + + if (touch[i].pos==p_points[idx].pos) + continue; //no move unncesearily + + InputEvent ev; + ev.type=InputEvent::SCREEN_DRAG; + ev.ID=last_id++; + ev.screen_drag.index=touch[i].id; + ev.screen_drag.x=p_points[idx].pos.x; + ev.screen_drag.y=p_points[idx].pos.y; + ev.screen_drag.relative_x=p_points[idx].pos.x - touch[i].pos.x; + ev.screen_drag.relative_y=p_points[idx].pos.y - touch[i].pos.y; + input->parse_input_event(ev); + touch[i].pos=p_points[idx].pos; + } + + + } break; + case 2: { //release + + + + if (touch.size()) { + //end all if exist + InputEvent ev; + ev.type=InputEvent::MOUSE_BUTTON; + ev.ID=last_id++; + ev.mouse_button.button_index=BUTTON_LEFT; + ev.mouse_button.button_mask=BUTTON_MASK_LEFT; + ev.mouse_button.pressed=false; + ev.mouse_button.x=touch[0].pos.x; + ev.mouse_button.y=touch[0].pos.y; + ev.mouse_button.global_x=touch[0].pos.x; + ev.mouse_button.global_y=touch[0].pos.y; + input->parse_input_event(ev); + + + for(int i=0;i<touch.size();i++) { + + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.ID=last_id++; + ev.screen_touch.index=touch[i].id; + ev.screen_touch.pressed=false; + ev.screen_touch.x=touch[i].pos.x; + ev.screen_touch.y=touch[i].pos.y; + input->parse_input_event(ev); + + } + touch.clear(); + } + + } break; + case 3: { // add tuchi + + + + + + ERR_FAIL_INDEX(p_pointer,p_points.size()); + + TouchPos tp=p_points[p_pointer]; + touch.push_back(tp); + + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.ID=last_id++; + ev.screen_touch.index=tp.id; + ev.screen_touch.pressed=true; + ev.screen_touch.x=tp.pos.x; + ev.screen_touch.y=tp.pos.y; + input->parse_input_event(ev); + + } break; + case 4: { + + + for(int i=0;i<touch.size();i++) { + if (touch[i].id==p_pointer) { + + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.ID=last_id++; + ev.screen_touch.index=touch[i].id; + ev.screen_touch.pressed=false; + ev.screen_touch.x=touch[i].pos.x; + ev.screen_touch.y=touch[i].pos.y; + input->parse_input_event(ev); + touch.remove(i); + i--; + } + } + + } break; + + } + +} + +void OS_JavaScript::process_accelerometer(const Vector3& p_accelerometer) { + + input->set_accelerometer(p_accelerometer); +} + +bool OS_JavaScript::has_touchscreen_ui_hint() const { + + return true; +} + +void OS_JavaScript::main_loop_request_quit() { + + if (main_loop) + main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); +} + +void OS_JavaScript::set_display_size(Size2 p_size) { + + default_videomode.width=p_size.x; + default_videomode.height=p_size.y; +} + +void OS_JavaScript::reload_gfx() { + + if (gfx_init_func) + gfx_init_func(gfx_init_ud,use_gl2,default_videomode.width,default_videomode.height,default_videomode.fullscreen); + if (rasterizer) + rasterizer->reload_vram(); +} + +Error OS_JavaScript::shell_open(String p_uri) { + + if (open_uri_func) + return open_uri_func(p_uri)?ERR_CANT_OPEN:OK; + return ERR_UNAVAILABLE; +}; + +String OS_JavaScript::get_resource_dir() const { + + return "/"; //javascript has it's own filesystem for resources inside the APK +} + +String OS_JavaScript::get_locale() const { + + if (get_locale_func) + return get_locale_func(); + return OS_Unix::get_locale(); +} + + +String OS_JavaScript::get_data_dir() const { + + if (get_data_dir_func) + return get_data_dir_func(); + return "/"; + //return Globals::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir"); +}; + + + + +OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func) { + + + default_videomode.width=800; + default_videomode.height=600; + default_videomode.fullscreen=true; + default_videomode.resizable=false; + + gfx_init_func=p_gfx_init_func; + gfx_init_ud=p_gfx_init_ud; + main_loop=NULL; + last_id=1; + gl_extensions=NULL; + rasterizer=NULL; + + open_uri_func=p_open_uri_func; + get_data_dir_func=p_get_data_dir_func; + get_locale_func=p_get_locale_func; + + +} + +OS_JavaScript::~OS_JavaScript() { + + +} diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h new file mode 100644 index 000000000..dfc93d3ff --- /dev/null +++ b/platform/javascript/os_javascript.h @@ -0,0 +1,164 @@ +/*************************************************************************/ +/* os_javascript.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef OS_JAVASCRIPT_H +#define OS_JAVASCRIPT_H + +#include "os/input.h" +#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/physics_2d/physics_2d_server_sw.h" +#include "servers/visual/rasterizer.h" + +#include "audio_driver_javascript.h" + +typedef void (*GFXInitFunc)(void *ud,bool gl2,int w, int h, bool fs); +typedef int (*OpenURIFunc)(const String&); +typedef String (*GetDataDirFunc)(); +typedef String (*GetLocaleFunc)(); + +class OS_JavaScript : public OS_Unix { +public: + + struct TouchPos { + int id; + Point2 pos; + }; + +private: + + Vector<TouchPos> touch; + + Point2 last_mouse; + unsigned int last_id; + GFXInitFunc gfx_init_func; + void*gfx_init_ud; + + bool use_gl2; + + Rasterizer *rasterizer; + VisualServer *visual_server; + AudioServerSW *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; + const char* gl_extensions; + + InputDefault *input; + VideoMode default_videomode; + MainLoop * main_loop; + + OpenURIFunc open_uri_func; + GetDataDirFunc get_data_dir_func; + GetLocaleFunc get_locale_func; + +public: + + // functions used by main to initialize/deintialize the OS + virtual int get_video_driver_count() const; + virtual const char * get_video_driver_name(int p_driver) const; + + virtual VideoMode get_default_video_mode() const; + + virtual int get_audio_driver_count() const; + virtual const char * get_audio_driver_name(int p_driver) const; + + virtual void initialize_core(); + virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); + + virtual void set_main_loop( MainLoop * p_main_loop ); + virtual void delete_main_loop(); + + virtual void finalize(); + + + typedef int64_t ProcessID; + + static OS* get_singleton(); + + virtual void vprint(const char* p_format, va_list p_list, bool p_stderr=false); + virtual void print(const char *p_format, ... ); + virtual void alert(const String& p_alert); + + + virtual void set_mouse_show(bool p_show); + virtual void set_mouse_grab(bool p_grab); + virtual bool is_mouse_grab_enabled() const; + virtual Point2 get_mouse_pos() const; + virtual int get_mouse_button_state() const; + virtual void set_window_title(const String& p_title); + + //virtual void set_clipboard(const String& p_text); + //virtual String get_clipboard() const; + + virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0); + virtual VideoMode get_video_mode(int p_screen=0) const; + virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + + virtual String get_name(); + virtual MainLoop *get_main_loop() const; + + virtual bool can_draw() const; + + virtual void set_cursor_shape(CursorShape p_shape); + + void main_loop_begin(); + bool main_loop_iterate(); + void main_loop_request_quit(); + void main_loop_end(); + void main_loop_focusout(); + void main_loop_focusin(); + + virtual bool has_touchscreen_ui_hint() const; + + void set_opengl_extensions(const char* p_gl_extensions); + void set_display_size(Size2 p_size); + + void reload_gfx(); + + virtual Error shell_open(String p_uri); + virtual String get_data_dir() const; + virtual String get_resource_dir() const; + virtual String get_locale() const; + + void process_accelerometer(const Vector3& p_accelerometer); + void process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points); + void push_input(const InputEvent& p_ev); + OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func); + ~OS_JavaScript(); + +}; + +#endif diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h new file mode 100644 index 000000000..38fc934ae --- /dev/null +++ b/platform/javascript/platform_config.h @@ -0,0 +1,29 @@ +/*************************************************************************/ +/* platform_config.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include <alloca.h> |
