diff options
-rw-r--r-- | drivers/unix/os_unix.cpp | 3 | ||||
-rw-r--r-- | modules/ik/SCsub | 7 | ||||
-rw-r--r-- | modules/ik/config.py | 8 | ||||
-rw-r--r-- | modules/ik/ik.cpp | 326 | ||||
-rw-r--r-- | modules/ik/ik.h | 74 | ||||
-rw-r--r-- | modules/ik/register_types.cpp | 47 | ||||
-rw-r--r-- | modules/ik/register_types.h | 30 | ||||
-rw-r--r-- | platform/javascript/detect.py | 1 | ||||
-rw-r--r-- | platform/javascript/export/export.cpp | 5 | ||||
-rw-r--r-- | platform/javascript/javascript_main.cpp | 13 | ||||
-rw-r--r-- | platform/javascript/os_javascript.cpp | 281 | ||||
-rw-r--r-- | platform/javascript/os_javascript.h | 30 | ||||
-rw-r--r-- | scene/2d/particles_2d.cpp | 2 | ||||
-rw-r--r-- | thirdparty/README.md | 1 | ||||
-rw-r--r-- | thirdparty/libsimplewebm/OpusVorbisDecoder.cpp | 5 | ||||
-rw-r--r-- | tools/editor/plugins/texture_region_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | tools/editor/project_export.cpp | 209 | ||||
-rw-r--r-- | tools/editor/project_export.h | 11 | ||||
-rw-r--r-- | tools/editor/property_editor.h | 2 |
19 files changed, 462 insertions, 597 deletions
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 271cf302ef..94f5f5b46f 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -522,9 +522,6 @@ String OS_Unix::get_executable_path() const { delete[] resolved_path; return path; -#elif defined(EMSCRIPTEN) - // We return nothing - return String(); #else ERR_PRINT("Warning, don't know how to obtain executable path on this OS! Please override this function properly."); return OS::get_executable_path(); diff --git a/modules/ik/SCsub b/modules/ik/SCsub deleted file mode 100644 index 0882406761..0000000000 --- a/modules/ik/SCsub +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -Import('env') - -env.add_source_files(env.modules_sources, "*.cpp") - -Export('env') diff --git a/modules/ik/config.py b/modules/ik/config.py deleted file mode 100644 index 5698a37295..0000000000 --- a/modules/ik/config.py +++ /dev/null @@ -1,8 +0,0 @@ - - -def can_build(platform): - return True - - -def configure(env): - pass diff --git a/modules/ik/ik.cpp b/modules/ik/ik.cpp deleted file mode 100644 index 35b3ba7e83..0000000000 --- a/modules/ik/ik.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/*************************************************************************/ -/* ik.cpp */ -/* Copyright (c) 2016 Sergey Lapin <slapinid@gmail.com> */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 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 "ik.h" - -bool InverseKinematics::_get(const StringName& p_name,Variant &r_ret) const -{ - - if (String(p_name)=="ik_bone") { - - r_ret=get_bone_name(); - return true; - } - - return false; -} - -bool InverseKinematics::_set(const StringName& p_name, const Variant& p_value) -{ - - if (String(p_name)=="ik_bone") { - - set_bone_name(p_value); - changed = true; - return true; - } - - return false; -} - -void InverseKinematics::_get_property_list( List<PropertyInfo>* p_list ) const -{ - - Skeleton *parent=NULL; - if(get_parent()) - parent=get_parent()->cast_to<Skeleton>(); - - if (parent) { - - String names; - for(int i=0;i<parent->get_bone_count();i++) { - if(i>0) - names+=","; - names+=parent->get_bone_name(i); - } - - p_list->push_back(PropertyInfo(Variant::STRING,"ik_bone",PROPERTY_HINT_ENUM,names)); - } else { - - p_list->push_back(PropertyInfo(Variant::STRING,"ik_bone")); - - } - -} - -void InverseKinematics::_check_bind() -{ - - if (get_parent() && get_parent()->cast_to<Skeleton>()) { - Skeleton *sk = get_parent()->cast_to<Skeleton>(); - int idx = sk->find_bone(ik_bone); - if (idx!=-1) { - ik_bone_no = idx; - bound=true; - } - skel = sk; - } -} - -void InverseKinematics::_check_unbind() -{ - - if (bound) { - - if (get_parent() && get_parent()->cast_to<Skeleton>()) { - Skeleton *sk = get_parent()->cast_to<Skeleton>(); - int idx = sk->find_bone(ik_bone); - if (idx!=-1) - ik_bone_no = idx; - else - ik_bone_no = 0; - skel = sk; - - } - bound=false; - } -} - - -void InverseKinematics::set_bone_name(const String& p_name) -{ - - if (is_inside_tree()) - _check_unbind(); - - ik_bone=p_name; - - if (is_inside_tree()) - _check_bind(); - changed = true; -} - -String InverseKinematics::get_bone_name() const -{ - - return ik_bone; -} - -void InverseKinematics::set_iterations(int itn) -{ - - if (is_inside_tree()) - _check_unbind(); - - iterations=itn; - - if (is_inside_tree()) - _check_bind(); - changed = true; -} - -int InverseKinematics::get_iterations() const -{ - - return iterations; -} - -void InverseKinematics::set_chain_size(int cs) -{ - if (is_inside_tree()) - _check_unbind(); - - chain_size=cs; - chain.clear(); - if (bound) - update_parameters(); - - if (is_inside_tree()) - _check_bind(); - changed = true; -} - -int InverseKinematics::get_chain_size() const -{ - - return chain_size; -} - -void InverseKinematics::set_precision(float p) -{ - - if (is_inside_tree()) - _check_unbind(); - - precision=p; - - if (is_inside_tree()) - _check_bind(); - changed = true; -} - -float InverseKinematics::get_precision() const -{ - - return precision; -} - -void InverseKinematics::set_speed(float p) -{ - - if (is_inside_tree()) - _check_unbind(); - - speed=p; - - if (is_inside_tree()) - _check_bind(); - changed = true; -} - -float InverseKinematics::get_speed() const -{ - - return speed; -} - -void InverseKinematics::update_parameters() -{ - tail_bone = -1; - for (int i = 0; i < skel->get_bone_count(); i++) - if (skel->get_bone_parent(i) == ik_bone_no) - tail_bone = i; - int cur_bone = ik_bone_no; - int its = chain_size; - while (its > 0 && cur_bone >= 0) { - chain.push_back(cur_bone); - cur_bone = skel->get_bone_parent(cur_bone); - its--; - } -} - -void InverseKinematics::_notification(int p_what) -{ - - switch(p_what) { - - case NOTIFICATION_ENTER_TREE: { - - _check_bind(); - if (bound) { - update_parameters(); - changed = false; - set_process(true); - } - } break; - case NOTIFICATION_PROCESS: { - - Spatial *sksp = skel->cast_to<Spatial>(); - if (!bound) - break; - if (!sksp) - break; - if (changed) { - update_parameters(); - changed = false; - } - Vector3 to = get_translation(); - for (int hump = 0; hump < iterations; hump++) { - int depth = 0; - float olderr = 1000.0; - float psign = 1.0; - bool reached = false; - - for (List<int>::Element *b = chain.front(); b; b = b->next()) { - int cur_bone = b->get(); - Vector3 d = skel->get_bone_global_pose(tail_bone).origin; - Vector3 rg = to; - float err = d.distance_squared_to(rg); - if (err < precision) { - if (!reached && err < precision) - reached = true; - break; - } else - if (reached) - reached = false; - if (err > olderr) - psign = -psign; - Transform mod = skel->get_bone_global_pose(cur_bone); - Quat q1 = Quat(mod.basis).normalized(); - Transform mod2 = mod.looking_at(to, Vector3(0.0, 1.0, 0.0)); - Quat q2 = Quat(mod2.basis).normalized(); - if (psign < 0.0) - q2 = q2.inverse(); - Quat q = q1.slerp(q2, speed / (1.0 + 500.0 * depth)).normalized(); - Transform fin = Transform(q); - fin.origin = mod.origin; - skel->set_bone_global_pose(cur_bone, fin); - depth++; - } - if (reached) - break; - - } - - } break; - case NOTIFICATION_EXIT_TREE: { - set_process(false); - - _check_unbind(); - } break; - } -} -void InverseKinematics::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_bone_name","ik_bone"),&InverseKinematics::set_bone_name); - ObjectTypeDB::bind_method(_MD("get_bone_name"),&InverseKinematics::get_bone_name); - ObjectTypeDB::bind_method(_MD("set_iterations","iterations"),&InverseKinematics::set_iterations); - ObjectTypeDB::bind_method(_MD("get_iterations"),&InverseKinematics::get_iterations); - ObjectTypeDB::bind_method(_MD("set_chain_size","chain_size"),&InverseKinematics::set_chain_size); - ObjectTypeDB::bind_method(_MD("get_chain_size"),&InverseKinematics::get_chain_size); - ObjectTypeDB::bind_method(_MD("set_precision","precision"),&InverseKinematics::set_precision); - ObjectTypeDB::bind_method(_MD("get_precision"),&InverseKinematics::get_precision); - ObjectTypeDB::bind_method(_MD("set_speed","speed"),&InverseKinematics::set_speed); - ObjectTypeDB::bind_method(_MD("get_speed"),&InverseKinematics::get_speed); - ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations"), _SCS("set_iterations"), _SCS("get_iterations")); - ADD_PROPERTY(PropertyInfo(Variant::INT, "chain_size"), _SCS("set_chain_size"), _SCS("get_chain_size")); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "precision"), _SCS("set_precision"), _SCS("get_precision")); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), _SCS("set_speed"), _SCS("get_speed")); -} - -InverseKinematics::InverseKinematics() -{ - bound=false; - chain_size = 2; - iterations = 100; - precision = 0.001; - speed = 0.2; - -} - diff --git a/modules/ik/ik.h b/modules/ik/ik.h deleted file mode 100644 index b57d69b026..0000000000 --- a/modules/ik/ik.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************/ -/* ik.h */ -/* Copyright (c) 2016 Sergey Lapin <slapinid@gmail.com> */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 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 IK_H -#define IK_H - -#include "scene/3d/skeleton.h" -class InverseKinematics : public Spatial { - OBJ_TYPE(InverseKinematics, Spatial); - bool bound; - String ik_bone; - int ik_bone_no; - int tail_bone; - int chain_size; - Skeleton *skel; - List<int> chain; - void _check_bind(); - void _check_unbind(); - int iterations; - float precision; - float speed; - bool changed; - -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; - - void _notification(int p_what); - static void _bind_methods(); - void update_parameters(); -public: - Skeleton *get_skeleton(); - void set_bone_name(const String& p_name); - String get_bone_name() const; - void set_iterations(int itn); - int get_iterations() const; - void set_chain_size(int cs); - int get_chain_size() const; - void set_precision(float p); - float get_precision() const; - void set_speed(float p); - float get_speed() const; - InverseKinematics(); -}; - -#endif - diff --git a/modules/ik/register_types.cpp b/modules/ik/register_types.cpp deleted file mode 100644 index e7df7f55b2..0000000000 --- a/modules/ik/register_types.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************/ -/* register_types.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 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 "register_types.h" -#ifndef _3D_DISABLED -#include "object_type_db.h" -#include "ik.h" -#endif - -void register_ik_types() { - -#ifndef _3D_DISABLED - ObjectTypeDB::register_type<InverseKinematics>(); -#endif -} - - - -void unregister_ik_types() { - - -} diff --git a/modules/ik/register_types.h b/modules/ik/register_types.h deleted file mode 100644 index 828917ade7..0000000000 --- a/modules/ik/register_types.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************/ -/* register_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 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_ik_types(); -void unregister_ik_types(); diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 35352becf8..2cb6874000 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -96,6 +96,7 @@ def configure(env): else: env.Append(CPPFLAGS=['-s', 'ASM_JS=1']) env.Append(LINKFLAGS=['-s', 'ASM_JS=1']) + env.Append(LINKFLAGS=['--separate-asm']) if env['javascript_eval'] == 'yes': env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED']) diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 721aef3e50..ab64ffbb45 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -320,6 +320,11 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool file=p_path.get_file().basename()+".js"; } + if (file=="godot.asm.js") { + + file=p_path.get_file().basename()+".asm.js"; + } + if (file=="godot.mem") { file=p_path.get_file().basename()+".mem"; diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index d9342cfe10..586ccc9b4e 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -66,11 +66,12 @@ static void _glut_mouse_button(int button, int state, int x, int y) { if (ev.mouse_button.button_index<4) { if (ev.mouse_button.pressed) { - _mouse_button_mask|=1<<ev.mouse_button.button_index; + _mouse_button_mask |= 1 << (ev.mouse_button.button_index-1); } else { - _mouse_button_mask&=~(1<<ev.mouse_button.button_index); + _mouse_button_mask &= ~(1 << (ev.mouse_button.button_index-1)); } } + ev.mouse_button.button_mask=_mouse_button_mask; uint32_t m = glutGetModifiers(); ev.mouse_button.mod.alt=(m&GLUT_ACTIVE_ALT)!=0; @@ -79,6 +80,11 @@ static void _glut_mouse_button(int button, int state, int x, int y) { os->push_input(ev); + if (ev.mouse_button.button_index==BUTTON_WHEEL_UP || ev.mouse_button.button_index==BUTTON_WHEEL_DOWN) { + // GLUT doesn't send release events for mouse wheel, so send manually + ev.mouse_button.pressed=false; + os->push_input(ev); + } } @@ -148,7 +154,7 @@ 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); + os = new OS_JavaScript(_gfx_init,NULL,NULL); #if 0 char *args[]={"-test","gui","-v",NULL}; Error err = Main::setup("apk",3,args); @@ -162,7 +168,6 @@ int main(int argc, char *argv[]) { glutMouseFunc(_glut_mouse_button); glutMotionFunc(_glut_mouse_motion); - glutMotionFunc(_glut_mouse_motion); glutPassiveMotionFunc(_glut_mouse_motion); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index e802a7e9cb..14af9b3e37 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -37,6 +37,7 @@ #include "main/main.h" #include "core/globals.h" +#include "stdlib.h" #include "emscripten.h" #include "dom_keys.h" @@ -77,6 +78,59 @@ void OS_JavaScript::set_opengl_extensions(const char* p_gl_extensions) { gl_extensions=p_gl_extensions; } +static EM_BOOL _browser_resize_callback(int event_type, const EmscriptenUiEvent *ui_event, void *user_data) { + + ERR_FAIL_COND_V(event_type!=EMSCRIPTEN_EVENT_RESIZE, false); + + OS_JavaScript* os = static_cast<OS_JavaScript*>(user_data); + + // the order in which _browser_resize_callback and + // _fullscreen_change_callback are called is browser-dependent, + // so try adjusting for fullscreen in both + if (os->is_window_fullscreen() || os->is_window_maximized()) { + + OS::VideoMode vm = os->get_video_mode(); + vm.width = ui_event->windowInnerWidth; + vm.height = ui_event->windowInnerHeight; + os->set_video_mode(vm); + emscripten_set_canvas_size(ui_event->windowInnerWidth, ui_event->windowInnerHeight); + } + return false; +} + +static Size2 _windowed_size; + +static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFullscreenChangeEvent *event, void *user_data) { + + ERR_FAIL_COND_V(event_type!=EMSCRIPTEN_EVENT_FULLSCREENCHANGE, false); + + OS_JavaScript* os = static_cast<OS_JavaScript*>(user_data); + String id = String::utf8(event->id); + + // empty id is canvas + if (id.empty() || id=="canvas") { + + OS::VideoMode vm = os->get_video_mode(); + // this event property is the only reliable information on + // browser fullscreen state + vm.fullscreen = event->isFullscreen; + + if (event->isFullscreen) { + vm.width = event->screenWidth; + vm.height = event->screenHeight; + os->set_video_mode(vm); + emscripten_set_canvas_size(vm.width, vm.height); + } + else { + os->set_video_mode(vm); + if (!os->is_window_maximized()) { + os->set_window_size(_windowed_size); + } + } + } + return false; +} + static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) { InputEvent ev; @@ -89,7 +143,9 @@ static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_eve ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode); String unicode = String::utf8(emscripten_event->key); + // check if empty or multi-character (e.g. `CapsLock`) if (unicode.length()!=1) { + // might be empty as well, but better than nonsense unicode = String::utf8(emscripten_event->charValue); } if (unicode.length()==1) { @@ -151,7 +207,30 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int 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; + // nothing to do here, can't fulfil fullscreen request due to + // browser security, window size is already set from HTML + video_mode=p_desired; + video_mode.fullscreen=false; + _windowed_size=get_window_size(); + + // find locale, emscripten only sets "C" + char locale_ptr[16]; + EM_ASM_({ + var locale = ""; + if (Module.locale) { + // best case: server-side script reads Accept-Language early and + // defines the locale to be read here + locale = Module.locale; + } else { + // no luck, use what the JS engine can tell us + // if this turns out not compatible enough, add tests for + // browserLanguage, systemLanguage and userLanguage + locale = navigator.languages ? navigator.languages[0] : navigator.language; + } + locale = locale.split('.')[0]; + stringToUTF8(locale, $0, 16); + }, locale_ptr); + setenv("LANG", locale_ptr, true); print_line("Init Audio"); @@ -210,26 +289,23 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int input = memnew( InputDefault ); - EMSCRIPTEN_RESULT result = emscripten_set_keydown_callback(NULL, this , true, &_keydown_callback); - if (result!=EMSCRIPTEN_RESULT_SUCCESS) { - ERR_PRINTS( "Error while setting Emscripten keydown callback: Code " + itos(result) ); - } - result = emscripten_set_keypress_callback(NULL, this, true, &_keypress_callback); - if (result!=EMSCRIPTEN_RESULT_SUCCESS) { - ERR_PRINTS( "Error while setting Emscripten keypress callback: Code " + itos(result) ); - } - result = emscripten_set_keyup_callback(NULL, this, true, &_keyup_callback); - if (result!=EMSCRIPTEN_RESULT_SUCCESS) { - ERR_PRINTS( "Error while setting Emscripten keyup callback: Code " + itos(result) ); - } - result = emscripten_set_gamepadconnected_callback(NULL, true, &joy_callback_func); - if (result!=EMSCRIPTEN_RESULT_SUCCESS) { - ERR_PRINTS( "Error while setting Emscripten gamepadconnected callback: Code " + itos(result) ); - } - result = emscripten_set_gamepaddisconnected_callback(NULL, true, &joy_callback_func); - if (result!=EMSCRIPTEN_RESULT_SUCCESS) { - ERR_PRINTS( "Error while setting Emscripten gamepaddisconnected callback: Code " + itos(result) ); - } +#define EM_CHECK(ev) if (result!=EMSCRIPTEN_RESULT_SUCCESS)\ + ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result)) +#define SET_EM_CALLBACK(ev, cb) result = emscripten_set_##ev##_callback(NULL, this, true, &cb); EM_CHECK(ev) +#define SET_EM_CALLBACK_NODATA(ev, cb) result = emscripten_set_##ev##_callback(NULL, true, &cb); EM_CHECK(ev) + + EMSCRIPTEN_RESULT result; + SET_EM_CALLBACK(keydown, _keydown_callback) + SET_EM_CALLBACK(keypress, _keypress_callback) + SET_EM_CALLBACK(keyup, _keyup_callback) + SET_EM_CALLBACK(resize, _browser_resize_callback) + SET_EM_CALLBACK(fullscreenchange, _fullscreen_change_callback) + SET_EM_CALLBACK_NODATA(gamepadconnected, joy_callback_func) + SET_EM_CALLBACK_NODATA(gamepaddisconnected, joy_callback_func) + +#undef SET_EM_CALLBACK_NODATA +#undef SET_EM_CALLBACK +#undef EM_CHECK #ifdef JAVASCRIPT_EVAL_ENABLED javascript_eval = memnew(JavaScript); @@ -254,32 +330,11 @@ void OS_JavaScript::finalize() { memdelete(input); } +void OS_JavaScript::alert(const String& p_alert,const String& p_title) { -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()); + EM_ASM_({ + window.alert(UTF8ToString($0)); + }, p_alert.utf8().get_data()); } @@ -298,17 +353,22 @@ 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(); + return input->get_mouse_pos(); } + int OS_JavaScript::get_mouse_button_state() const { - return 0; + return last_button_mask; } -void OS_JavaScript::set_window_title(const String& p_title) { +void OS_JavaScript::set_window_title(const String& p_title) { + EM_ASM_({ + document.title = UTF8ToString($0); + }, p_title.utf8().get_data()); } //interesting byt not yet @@ -317,22 +377,92 @@ void OS_JavaScript::set_window_title(const String& p_title) { void OS_JavaScript::set_video_mode(const VideoMode& p_video_mode,int p_screen) { - + video_mode = p_video_mode; } OS::VideoMode OS_JavaScript::get_video_mode(int p_screen) const { - return default_videomode; + return video_mode; +} + +Size2 OS_JavaScript::get_screen_size(int p_screen) const { + + ERR_FAIL_COND_V(p_screen!=0, Size2()); + + EmscriptenFullscreenChangeEvent ev; + EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev); + ERR_FAIL_COND_V(result!=EMSCRIPTEN_RESULT_SUCCESS, Size2()); + return Size2(ev.screenWidth, ev.screenHeight); +} + +void OS_JavaScript::set_window_size(const Size2 p_size) { + + window_maximized = false; + if (is_window_fullscreen()) { + set_window_fullscreen(false); + } + _windowed_size = p_size; + video_mode.width = p_size.x; + video_mode.height = p_size.y; + emscripten_set_canvas_size(p_size.x, p_size.y); } Size2 OS_JavaScript::get_window_size() const { - return Vector2(default_videomode.width,default_videomode.height); + int canvas[3]; + emscripten_get_canvas_size(canvas, canvas+1, canvas+2); + return Size2(canvas[0], canvas[1]); +} + +void OS_JavaScript::set_window_maximized(bool p_enabled) { + + window_maximized = p_enabled; + if (p_enabled) { + + if (is_window_fullscreen()) { + // _browser_resize callback will set canvas size + set_window_fullscreen(false); + } + else { + video_mode.width = EM_ASM_INT_V(return window.innerWidth); + video_mode.height = EM_ASM_INT_V(return window.innerHeight); + emscripten_set_canvas_size(video_mode.width, video_mode.height); + } + } + else { + set_window_size(_windowed_size); + } +} + +void OS_JavaScript::set_window_fullscreen(bool p_enable) { + + if (p_enable==is_window_fullscreen()) { + return; + } + + // only requesting changes here, if successful, canvas is resized in + // _browser_resize_callback or _fullscreen_change_callback + EMSCRIPTEN_RESULT result; + if (p_enable) { + EM_ASM(Module.requestFullscreen(false, false);); + } + else { + result = emscripten_exit_fullscreen(); + if (result!=EMSCRIPTEN_RESULT_SUCCESS) { + ERR_PRINTS("Failed to exit fullscreen: Code " + itos(result)); + } + } +} + +bool OS_JavaScript::is_window_fullscreen() const { + + return video_mode.fullscreen; } void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { - p_list->push_back(default_videomode); + Size2 screen = get_screen_size(); + p_list->push_back(OS::VideoMode(screen.width, screen.height, true)); } String OS_JavaScript::get_name() { @@ -423,6 +553,9 @@ void OS_JavaScript::push_input(const InputEvent& p_ev) { if (ev.type==InputEvent::MOUSE_MOTION) { input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y)); } + else if (ev.type==InputEvent::MOUSE_BUTTON) { + last_button_mask = ev.mouse_button.button_mask; + } input->parse_input_event(p_ev); } @@ -649,40 +782,26 @@ void OS_JavaScript::main_loop_request_quit() { 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); + 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) { - - if (open_uri_func) - return open_uri_func(p_uri)?ERR_CANT_OPEN:OK; - return ERR_UNAVAILABLE; -}; + EM_ASM_({ + window.open(UTF8ToString($0), '_blank'); + }, p_uri.utf8().get_data()); + return OK; +} 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) @@ -691,6 +810,10 @@ String OS_JavaScript::get_data_dir() const { //return Globals::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir"); }; +String OS_JavaScript::get_executable_path() const { + + return String(); +} void OS_JavaScript::_close_notification_funcs(const String& p_file,int p_flags) { @@ -757,24 +880,18 @@ String OS_JavaScript::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -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; +OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func) { gfx_init_func=p_gfx_init_func; gfx_init_ud=p_gfx_init_ud; + last_button_mask=0; main_loop=NULL; last_id=1; gl_extensions=NULL; rasterizer=NULL; + window_maximized=false; - open_uri_func=p_open_uri_func; get_data_dir_func=p_get_data_dir_func; - get_locale_func=p_get_locale_func; FileAccessUnix::close_notification_func=_close_notification_funcs; time_to_save_sync=-1; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 5b7904805b..95bd64dfe4 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -45,9 +45,7 @@ #include "javascript_eval.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: @@ -61,6 +59,7 @@ private: Vector<TouchPos> touch; Point2 last_mouse; + int last_button_mask; unsigned int last_id; GFXInitFunc gfx_init_func; void*gfx_init_ud; @@ -82,12 +81,11 @@ private: const char* gl_extensions; InputDefault *input; - VideoMode default_videomode; + bool window_maximized; + VideoMode video_mode; MainLoop * main_loop; - OpenURIFunc open_uri_func; GetDataDirFunc get_data_dir_func; - GetLocaleFunc get_locale_func; #ifdef JAVASCRIPT_EVAL_ENABLED JavaScript* javascript_eval; @@ -121,9 +119,12 @@ public: //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 print_error(const char* p_function, const char* p_file, int p_line, const char *p_code, const char* p_rationale, ErrorType p_type) { + + OS::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type); + } + + virtual void alert(const String& p_alert,const String& p_title="ALERT!"); virtual void set_mouse_show(bool p_show); @@ -140,7 +141,15 @@ public: 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 Size2 get_screen_size(int p_screen=0) const; + + virtual void set_window_size(const Size2); virtual Size2 get_window_size() const; + virtual void set_window_maximized(bool p_enabled); + virtual bool is_window_maximized() const { return window_maximized; } + virtual void set_window_fullscreen(bool p_enable); + virtual bool is_window_fullscreen() const; + virtual String get_name(); virtual MainLoop *get_main_loop() const; @@ -158,14 +167,13 @@ public: 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; + String get_executable_path() 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); @@ -175,7 +183,7 @@ public: virtual String get_joy_guid(int p_device) const; bool joy_connection_changed(int p_type, const EmscriptenGamepadEvent *p_event); - 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(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func); ~OS_JavaScript(); }; diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 29dad630d6..3101f616d6 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -563,7 +563,7 @@ void Particles2D::_notification(int p_what) { } } - float initial_size = param[PARAM_INITIAL_SIZE]+param[PARAM_INITIAL_SIZE]*_rand_from_seed(&rand_seed)*randomness[PARAM_FINAL_SIZE]; + float initial_size = param[PARAM_INITIAL_SIZE]+param[PARAM_INITIAL_SIZE]*_rand_from_seed(&rand_seed)*randomness[PARAM_INITIAL_SIZE]; float final_size = param[PARAM_FINAL_SIZE]+param[PARAM_FINAL_SIZE]*_rand_from_seed(&rand_seed)*randomness[PARAM_FINAL_SIZE]; float size_mult=initial_size*(1.0-ptime) + final_size*ptime; diff --git a/thirdparty/README.md b/thirdparty/README.md index 3adbbea59b..4b8e6b01ad 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -98,6 +98,7 @@ Files extracted from upstream source: ## libsimplewebm - Upstream: https://github.com/zaps166/libsimplewebm +- Version: 05cfdc2 (git) - License: MIT, BSD-3-Clause diff --git a/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp b/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp index d7869f599b..06447aca57 100644 --- a/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp +++ b/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp @@ -43,16 +43,17 @@ struct VorbisDecoder OpusVorbisDecoder::OpusVorbisDecoder(const WebMDemuxer &demuxer) : m_vorbis(NULL), m_opus(NULL), - m_numSamples(0), - m_channels(demuxer.getChannels()) + m_numSamples(0) { switch (demuxer.getAudioCodec()) { case WebMDemuxer::AUDIO_VORBIS: + m_channels = demuxer.getChannels(); if (openVorbis(demuxer)) return; break; case WebMDemuxer::AUDIO_OPUS: + m_channels = demuxer.getChannels(); if (openOpus(demuxer)) return; break; diff --git a/tools/editor/plugins/texture_region_editor_plugin.cpp b/tools/editor/plugins/texture_region_editor_plugin.cpp index 4a24c4d344..9348f683f2 100644 --- a/tools/editor/plugins/texture_region_editor_plugin.cpp +++ b/tools/editor/plugins/texture_region_editor_plugin.cpp @@ -388,9 +388,9 @@ void TextureRegionEditor::_region_input(const InputEvent& p_input) drag_index = -1; } } - } else if (mb.button_index == BUTTON_WHEEL_UP) { + } else if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) { _zoom_in(); - } else if (mb.button_index == BUTTON_WHEEL_DOWN) { + } else if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) { _zoom_out(); } } else if (p_input.type==InputEvent::MOUSE_MOTION) { diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index 103962716b..f4f3959729 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -589,6 +589,11 @@ void ProjectExportDialog::custom_action(const String&) { return; } + if (platform.to_lower()=="android" && _check_android_setting(exporter)==false){ + // not filled all field for Android release + return; + } + String extension = exporter->get_binary_extension(); file_export_password->set_editable( exporter->requires_password(exporter->is_debugging_enabled()) ); @@ -602,6 +607,204 @@ void ProjectExportDialog::custom_action(const String&) { } +LineEdit* ProjectExportDialog::_create_keystore_input(Control* container, const String& p_label, const String& name) { + + HBoxContainer* hb=memnew(HBoxContainer); + Label* lb=memnew(Label); + LineEdit* input=memnew(LineEdit); + + lb->set_text(p_label); + lb->set_custom_minimum_size(Size2(140*EDSCALE,0)); + lb->set_align(Label::ALIGN_RIGHT); + + input->set_custom_minimum_size(Size2(170*EDSCALE,0)); + input->set_name(name); + + hb->add_constant_override("separation", 10*EDSCALE); + hb->add_child(lb); + hb->add_child(input); + container->add_child(hb); + + return input; + +} + +void ProjectExportDialog::_create_android_keystore_window() { + + keystore_file_dialog = memnew( EditorFileDialog ); + add_child(keystore_file_dialog); + keystore_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_DIR); + keystore_file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + keystore_file_dialog->set_current_dir( "res://" ); + + keystore_file_dialog->set_title(TTR("Target Path:")); + keystore_file_dialog->connect("dir_selected", this,"_keystore_dir_selected"); + + keystore_create_dialog=memnew(ConfirmationDialog); + VBoxContainer* vb=memnew(VBoxContainer); + vb->set_size(Size2(340*EDSCALE,0)); + keystore_create_dialog->set_title(TTR("Create Android keystore")); + + _create_keystore_input(vb, TTR("Full name"), "name"); + _create_keystore_input(vb, TTR("Organizational unit"), "unit"); + _create_keystore_input(vb, TTR("Organization"), "org"); + _create_keystore_input(vb, TTR("City"), "city"); + _create_keystore_input(vb, TTR("State"), "state"); + _create_keystore_input(vb, TTR("2 letter country code"), "code"); + _create_keystore_input(vb, TTR("User alias"), "alias"); + LineEdit* pass=_create_keystore_input(vb, TTR("Password"), "pass"); + pass->set_placeholder(TTR("at least 6 characters")); + _create_keystore_input(vb, TTR("File name"), "file"); + + Label* lb_path=memnew(Label); + LineEdit* path=memnew(LineEdit); + Button* btn=memnew(Button); + HBoxContainer* hb=memnew(HBoxContainer); + + lb_path->set_text(TTR("Path : (better to save outside of project)")); + path->set_h_size_flags(SIZE_EXPAND_FILL); + path->set_name("path"); + btn->set_text(" .. "); + btn->connect("pressed", keystore_file_dialog, "popup_centered_ratio"); + + vb->add_spacer(); + vb->add_child(lb_path); + hb->add_child(path); + hb->add_child(btn); + vb->add_child(hb); + + keystore_create_dialog->add_child(vb); + keystore_create_dialog->set_child_rect(vb); + add_child(keystore_create_dialog); + + keystore_create_dialog->connect("confirmed", this, "_create_android_keystore"); + path->connect("text_changed", this, "_check_keystore_path"); + + confirm_keystore = memnew(ConfirmationDialog); + confirm_keystore->connect("confirmed", keystore_create_dialog, "popup_centered_minsize"); + add_child(confirm_keystore); + +} + +void ProjectExportDialog::_keystore_dir_selected(const String& path) { + + LineEdit* edit=keystore_create_dialog->find_node("path", true, false)->cast_to<LineEdit>(); + edit->set_text(path.simplify_path()); + +} + +void ProjectExportDialog::_keystore_created() { + + if (error->is_connected("popup_hide", this, "_keystore_created")){ + error->disconnect("popup_hide", this, "_keystore_created"); + } + custom_action("export_pck"); + +} + +void ProjectExportDialog::_check_keystore_path(const String& path) { + + LineEdit* edit=keystore_create_dialog->find_node("path", true, false)->cast_to<LineEdit>(); + bool exists = DirAccess::exists(path); + if (!exists) { + edit->add_color_override("font_color", Color(1,0,0,1)); + } else { + edit->add_color_override("font_color", Color(0,1,0,1)); + } + +} + +void ProjectExportDialog::_create_android_keystore() { + + Vector<String> names=String("name,unit,org,city,state,code,alias,pass").split(","); + String path=keystore_create_dialog->find_node("path", true, false)->cast_to<LineEdit>()->get_text(); + String file=keystore_create_dialog->find_node("file", true, false)->cast_to<LineEdit>()->get_text(); + + if (file.ends_with(".keystore")==false) { + file+=".keystore"; + } + String fullpath=path.plus_file(file); + String info="CN=$name, OU=$unit, O=$org, L=$city, S=$state, C=$code"; + Dictionary dic; + + for (int i=0;i<names.size();i++){ + LineEdit* edit = keystore_create_dialog->find_node(names[i], true, false)->cast_to<LineEdit>(); + dic[names[i]]=edit->get_text(); + info=info.replace("$"+names[i], edit->get_text()); + } + + String jarsigner=EditorSettings::get_singleton()->get("android/jarsigner"); + String keytool=jarsigner.get_base_dir().plus_file("keytool"); + String os_name=OS::get_singleton()->get_name(); + if (os_name.to_lower()=="windows") { + keytool+=".exe"; + } + + bool exist=FileAccess::exists(keytool); + if (!exist) { + error->set_text("Can't find 'keytool'"); + error->popup_centered_minsize(); + return; + } + + List<String> args; + args.push_back("-genkey"); + args.push_back("-v"); + args.push_back("-keystore"); + args.push_back(fullpath); + args.push_back("-alias"); + args.push_back(dic["alias"]); + args.push_back("-storepass"); + args.push_back(dic["pass"]); + args.push_back("-keypass"); + args.push_back(dic["pass"]); + args.push_back("-keyalg"); + args.push_back("RSA"); + args.push_back("-keysize"); + args.push_back("2048"); + args.push_back("-validity"); + args.push_back("10000"); + args.push_back("-dname"); + args.push_back(info); + int retval; + OS::get_singleton()->execute(keytool,args,true,NULL,NULL,&retval); + + if (retval==0) { // success + platform_options->_edit_set("keystore/release", fullpath); + platform_options->_edit_set("keystore/release_user", dic["alias"]); + platform_options->_edit_set("keystore/release_password", dic["pass"]); + + error->set_text("Android keystore created at \n"+fullpath); + error->connect("popup_hide", this, "_keystore_created"); + error->popup_centered_minsize(); + } else { // fail + error->set_text("Fail to create android keystore at \n"+fullpath); + error->popup_centered_minsize(); + } + +} + +bool ProjectExportDialog::_check_android_setting(const Ref<EditorExportPlatform>& exporter) { + + bool is_debugging = exporter->get("debug/debugging_enabled"); + String release = exporter->get("keystore/release"); + String user = exporter->get("keystore/release_user"); + String password = exporter->get("keystore/release_password"); + + if (!is_debugging && (release=="" || user=="" || password=="")){ + if (release==""){ + confirm_keystore->set_text(TTR("Release keystore is not set.\nDo you want to create one?")); + confirm_keystore->popup_centered_minsize(); + } else { + error->set_text(TTR("Fill Keystore/Release User and Release Password")); + error->popup_centered_minsize(); + } + return false; + } + + return true; + +} void ProjectExportDialog::_group_selected() { @@ -1123,6 +1326,10 @@ void ProjectExportDialog::_bind_methods() { ObjectTypeDB::bind_method(_MD("export_platform"),&ProjectExportDialog::export_platform); + ObjectTypeDB::bind_method(_MD("_create_android_keystore"),&ProjectExportDialog::_create_android_keystore); + ObjectTypeDB::bind_method(_MD("_check_keystore_path"),&ProjectExportDialog::_check_keystore_path); + ObjectTypeDB::bind_method(_MD("_keystore_dir_selected"),&ProjectExportDialog::_keystore_dir_selected); + ObjectTypeDB::bind_method(_MD("_keystore_created"),&ProjectExportDialog::_keystore_created); // ADD_SIGNAL(MethodInfo("instance")); @@ -1479,6 +1686,8 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) { ei="EditorIcons"; ot="Object"; pending_update_tree=true; + + _create_android_keystore_window(); } diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h index 8cf2bf3afc..c749e04b95 100644 --- a/tools/editor/project_export.h +++ b/tools/editor/project_export.h @@ -73,6 +73,7 @@ private: bool pending_update_tree; AcceptDialog *error; ConfirmationDialog *confirm; + ConfirmationDialog *confirm_keystore; Button *button_reload; LineEdit *filters, *filters_exclude; @@ -145,6 +146,9 @@ private: SpinBox *sample_max_hz; CheckButton *sample_trim; + ConfirmationDialog* keystore_create_dialog; + EditorFileDialog* keystore_file_dialog; + void _export_mode_changed(int p_idx); void _prop_edited(String what); @@ -190,6 +194,13 @@ private: void _export_action_pck(const String& p_file); void ok_pressed(); void custom_action(const String&); + LineEdit* _create_keystore_input(Control* container, const String& p_label, const String& name); + void _create_android_keystore_window(); + void _create_android_keystore(); + bool _check_android_setting(const Ref<EditorExportPlatform>& exporter); + void _check_keystore_path(const String& path); + void _keystore_dir_selected(const String& path); + void _keystore_created(); void _save_export_cfg(); void _format_toggled(); diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index 3fe332bf87..cd9e754cb6 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -219,6 +219,8 @@ class PropertyEditor : public Control { void _edit_button(Object *p_item, int p_column, int p_button); void _node_removed(Node *p_node); + +friend class ProjectExportDialog; void _edit_set(const String& p_name, const Variant& p_value); void _draw_flags(Object *ti,const Rect2& p_rect); |