diff options
-rw-r--r-- | core/os/keyboard.cpp | 121 | ||||
-rw-r--r-- | core/os/keyboard.h | 1 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 4 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 3 | ||||
-rw-r--r-- | main/SCsub | 2 | ||||
-rw-r--r-- | modules/bullet/shape_bullet.cpp | 54 | ||||
-rw-r--r-- | modules/bullet/shape_bullet.h | 7 | ||||
-rw-r--r-- | modules/gdnative/gdnative.cpp | 231 | ||||
-rw-r--r-- | modules/gdnative/gdnative.h | 6 | ||||
-rw-r--r-- | modules/gdscript/gdscript_highlighter.cpp | 12 | ||||
-rw-r--r-- | modules/gdscript/gdscript_highlighter.h | 2 | ||||
-rw-r--r-- | modules/gdscript/register_types.cpp | 2 | ||||
-rw-r--r-- | platform/android/java_glue.cpp | 27 | ||||
-rw-r--r-- | platform/javascript/detect.py | 7 | ||||
-rw-r--r-- | platform/javascript/engine.js | 40 | ||||
-rw-r--r-- | platform/javascript/pre.js | 2 | ||||
-rw-r--r-- | platform/osx/godot_main_osx.mm | 2 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 109 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 5 |
19 files changed, 394 insertions, 243 deletions
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index fa53cc85c8..9dfc91e308 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -461,99 +461,6 @@ const char *find_keycode_name(int p_keycode) { return ""; } -struct _KeyCodeReplace { - int from; - int to; -}; - -static const _KeyCodeReplace _keycode_replace_qwertz[] = { - { KEY_Y, KEY_Z }, - { KEY_Z, KEY_Y }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_azerty[] = { - { KEY_W, KEY_Z }, - { KEY_Z, KEY_W }, - { KEY_A, KEY_Q }, - { KEY_Q, KEY_A }, - { KEY_SEMICOLON, KEY_M }, - { KEY_M, KEY_SEMICOLON }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_qzerty[] = { - { KEY_W, KEY_Z }, - { KEY_Z, KEY_W }, - { KEY_SEMICOLON, KEY_M }, - { KEY_M, KEY_SEMICOLON }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_dvorak[] = { - { KEY_UNDERSCORE, KEY_BRACELEFT }, - { KEY_EQUAL, KEY_BRACERIGHT }, - { KEY_Q, KEY_APOSTROPHE }, - { KEY_W, KEY_COMMA }, - { KEY_E, KEY_PERIOD }, - { KEY_R, KEY_P }, - { KEY_T, KEY_Y }, - { KEY_Y, KEY_F }, - { KEY_U, KEY_G }, - { KEY_I, KEY_C }, - { KEY_O, KEY_R }, - { KEY_P, KEY_L }, - { KEY_BRACELEFT, KEY_SLASH }, - { KEY_BRACERIGHT, KEY_EQUAL }, - { KEY_A, KEY_A }, - { KEY_S, KEY_O }, - { KEY_D, KEY_E }, - { KEY_F, KEY_U }, - { KEY_G, KEY_I }, - { KEY_H, KEY_D }, - { KEY_J, KEY_H }, - { KEY_K, KEY_T }, - { KEY_L, KEY_N }, - { KEY_SEMICOLON, KEY_S }, - { KEY_APOSTROPHE, KEY_UNDERSCORE }, - { KEY_Z, KEY_SEMICOLON }, - { KEY_X, KEY_Q }, - { KEY_C, KEY_J }, - { KEY_V, KEY_K }, - { KEY_B, KEY_X }, - { KEY_N, KEY_B }, - { KEY_M, KEY_M }, - { KEY_COMMA, KEY_W }, - { KEY_PERIOD, KEY_V }, - { KEY_SLASH, KEY_Z }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_neo[] = { - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_colemak[] = { - { KEY_E, KEY_F }, - { KEY_R, KEY_P }, - { KEY_T, KEY_G }, - { KEY_Y, KEY_J }, - { KEY_U, KEY_L }, - { KEY_I, KEY_U }, - { KEY_O, KEY_Y }, - { KEY_P, KEY_SEMICOLON }, - { KEY_S, KEY_R }, - { KEY_D, KEY_S }, - { KEY_F, KEY_T }, - { KEY_G, KEY_D }, - { KEY_J, KEY_N }, - { KEY_K, KEY_E }, - { KEY_L, KEY_I }, - { KEY_SEMICOLON, KEY_O }, - { KEY_N, KEY_K }, - { 0, 0 } -}; - int keycode_get_count() { const _KeyCodeText *kct = &_keycodes[0]; @@ -574,31 +481,3 @@ int keycode_get_value_by_index(int p_index) { const char *keycode_get_name_by_index(int p_index) { return _keycodes[p_index].text; } - -int latin_keyboard_keycode_convert(int p_keycode) { - - const _KeyCodeReplace *kcr = NULL; - switch (OS::get_singleton()->get_latin_keyboard_variant()) { - - case OS::LATIN_KEYBOARD_QWERTY: return p_keycode; break; - case OS::LATIN_KEYBOARD_QWERTZ: kcr = _keycode_replace_qwertz; break; - case OS::LATIN_KEYBOARD_AZERTY: kcr = _keycode_replace_azerty; break; - case OS::LATIN_KEYBOARD_QZERTY: kcr = _keycode_replace_qzerty; break; - case OS::LATIN_KEYBOARD_DVORAK: kcr = _keycode_replace_dvorak; break; - case OS::LATIN_KEYBOARD_NEO: kcr = _keycode_replace_neo; break; - case OS::LATIN_KEYBOARD_COLEMAK: kcr = _keycode_replace_colemak; break; - default: return p_keycode; - } - - if (!kcr) { - return p_keycode; - } - - while (kcr->from) { - if (kcr->from == p_keycode) - return kcr->to; - kcr++; - } - - return p_keycode; -} diff --git a/core/os/keyboard.h b/core/os/keyboard.h index 4c253fa4ce..a0e6f8b2ef 100644 --- a/core/os/keyboard.h +++ b/core/os/keyboard.h @@ -331,6 +331,5 @@ const char *find_keycode_name(int p_keycode); int keycode_get_count(); int keycode_get_value_by_index(int p_index); const char *keycode_get_name_by_index(int p_index); -int latin_keyboard_keycode_convert(int p_keycode); #endif diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 02d851288a..5b6b3d44f2 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2085,9 +2085,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ case RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MUL: { glBlendEquation(GL_FUNC_ADD); if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO); } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE); } } break; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index f847382995..d5783c9b1a 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1671,6 +1671,8 @@ void FileSystemDock::_files_gui_input(Ref<InputEvent> p_event) { _file_option(FILE_COPY_PATH); } else if (ED_IS_SHORTCUT("filesystem_dock/delete", p_event)) { _file_option(FILE_REMOVE); + } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { + _file_option(FILE_RENAME); } } } @@ -1781,6 +1783,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KEY_MASK_CMD | KEY_C); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), KEY_DELETE); + ED_SHORTCUT("filesystem_dock/rename", TTR("Rename")); HBoxContainer *toolbar_hbc = memnew(HBoxContainer); add_child(toolbar_hbc); diff --git a/main/SCsub b/main/SCsub index 9eddc4f5b6..e2bf03234f 100644 --- a/main/SCsub +++ b/main/SCsub @@ -121,7 +121,7 @@ def make_default_controller_mappings(target, source, env): g.write("\t\"{}\",\n".format(mapping)) g.write("#endif\n") - g.write("};\n") + g.write("\tNULL\n};\n") g.close() env.main_sources = [] diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 9cbf83689b..76d9614465 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -125,14 +125,13 @@ btScaledBvhTriangleMeshShape *ShapeBullet::create_shape_concave(btBvhTriangleMes } } -btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size) { +btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { const btScalar ignoredHeightScale(1); - const btScalar fieldHeight(500); // Meters const int YAxis = 1; // 0=X, 1=Y, 2=Z const bool flipQuadEdges = false; const void *heightsPtr = p_heights.read().ptr(); - return bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, -fieldHeight, fieldHeight, YAxis, PHY_FLOAT, flipQuadEdges)); + return bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, p_min_height, p_max_height, YAxis, PHY_FLOAT, flipQuadEdges)); } btRayShape *ShapeBullet::create_shape_ray(real_t p_length, bool p_slips_on_slope) { @@ -387,19 +386,44 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) { Dictionary d = p_data; ERR_FAIL_COND(!d.has("width")); ERR_FAIL_COND(!d.has("depth")); - ERR_FAIL_COND(!d.has("cell_size")); ERR_FAIL_COND(!d.has("heights")); + real_t l_min_height = 0.0; + real_t l_max_height = 0.0; + + // If specified, min and max height will be used as precomputed values + if (d.has("min_height")) + l_min_height = d["min_height"]; + if (d.has("max_height")) + l_max_height = d["max_height"]; + + ERR_FAIL_COND(l_min_height > l_max_height); + int l_width = d["width"]; int l_depth = d["depth"]; - real_t l_cell_size = d["cell_size"]; PoolVector<real_t> l_heights = d["heights"]; ERR_FAIL_COND(l_width <= 0); ERR_FAIL_COND(l_depth <= 0); - ERR_FAIL_COND(l_cell_size <= CMP_EPSILON); - ERR_FAIL_COND(l_heights.size() != (width * depth)); - setup(heights, width, depth, cell_size); + ERR_FAIL_COND(l_heights.size() != (l_width * l_depth)); + + // Compute min and max heights if not specified. + if (!d.has("min_height") && !d.has("max_height")) { + + PoolVector<real_t>::Read r = heights.read(); + int heights_size = heights.size(); + + for (int i = 0; i < heights_size; ++i) { + real_t h = r[i]; + + if (h < l_min_height) + l_min_height = h; + else if (h > l_max_height) + l_max_height = h; + } + } + + setup(l_heights, l_width, l_depth, l_min_height, l_max_height); } Variant HeightMapShapeBullet::get_data() const { @@ -410,8 +434,14 @@ PhysicsServer::ShapeType HeightMapShapeBullet::get_type() const { return PhysicsServer::SHAPE_HEIGHTMAP; } -void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size) { +void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { + // TODO cell size must be tweaked using localScaling, which is a shared property for all Bullet shapes + { // Copy + + // TODO If Godot supported 16-bit integer image format, we could share the same memory block for heightfields + // without having to copy anything, optimizing memory and loading performance (Bullet only reads and doesn't take ownership of the data). + const int heights_size = p_heights.size(); heights.resize(heights_size); PoolVector<real_t>::Read p_heights_r = p_heights.read(); @@ -420,14 +450,16 @@ void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int heights_w[i] = p_heights_r[i]; } } + width = p_width; depth = p_depth; - cell_size = p_cell_size; + min_height = p_min_height; + max_height = p_max_height; notifyShapeChanged(); } btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { - btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, cell_size)); + btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, min_height, max_height)); cs->setLocalScaling(p_implicit_scale); prepare(cs); cs->setMargin(p_margin); diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 2acba90e36..abeea0f9ce 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -85,7 +85,7 @@ public: /// IMPORTANT: Remember to delete the shape interface by calling: delete my_shape->getMeshInterface(); static class btConvexPointCloudShape *create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); static class btScaledBvhTriangleMeshShape *create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); - static class btHeightfieldTerrainShape *create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size); + static class btHeightfieldTerrainShape *create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); static class btRayShape *create_shape_ray(real_t p_length, bool p_slips_on_slope); }; @@ -199,7 +199,8 @@ public: PoolVector<real_t> heights; int width; int depth; - real_t cell_size; + real_t min_height; + real_t max_height; HeightMapShapeBullet(); @@ -209,7 +210,7 @@ public: virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); private: - void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size); + void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); }; class RayShapeBullet : public ShapeBullet { diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 42c3028f2c..897588385a 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -66,8 +66,169 @@ GDNativeLibrary::GDNativeLibrary() { GDNativeLibrary::~GDNativeLibrary() { } +bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_property) { + + String name = p_name; + + if (name.begins_with("entry/")) { + String key = name.substr(6, name.length() - 6); + + config_file->set_value("entry", key, p_property); + + set_config_file(config_file); + + return true; + } + + if (name.begins_with("dependency/")) { + String key = name.substr(11, name.length() - 11); + + config_file->set_value("dependencies", key, p_property); + + set_config_file(config_file); + + return true; + } + + return false; +} + +bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const { + String name = p_name; + + if (name.begins_with("entry/")) { + String key = name.substr(6, name.length() - 6); + + r_property = config_file->get_value("entry", key); + + return true; + } + + if (name.begins_with("dependency/")) { + String key = name.substr(11, name.length() - 11); + + r_property = config_file->get_value("dependencies", key); + + return true; + } + + return false; +} + +void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { + // set entries + List<String> entry_key_list; + + if (config_file->has_section("entry")) + config_file->get_section_keys("entry", &entry_key_list); + + for (List<String>::Element *E = entry_key_list.front(); E; E = E->next()) { + String key = E->get(); + + PropertyInfo prop; + + prop.type = Variant::STRING; + prop.name = "entry/" + key; + + p_list->push_back(prop); + } + + // set dependencies + List<String> dependency_key_list; + + if (config_file->has_section("dependencies")) + config_file->get_section_keys("dependencies", &dependency_key_list); + + for (List<String>::Element *E = dependency_key_list.front(); E; E = E->next()) { + String key = E->get(); + + PropertyInfo prop; + + prop.type = Variant::STRING; + prop.name = "dependency/" + key; + + p_list->push_back(prop); + } +} + +void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) { + + set_singleton(p_config_file->get_value("general", "singleton", default_singleton)); + set_load_once(p_config_file->get_value("general", "load_once", default_load_once)); + set_symbol_prefix(p_config_file->get_value("general", "symbol_prefix", default_symbol_prefix)); + set_reloadable(p_config_file->get_value("general", "reloadable", default_reloadable)); + + String entry_lib_path; + { + + List<String> entry_keys; + + if (p_config_file->has_section("entry")) + p_config_file->get_section_keys("entry", &entry_keys); + + for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + entry_lib_path = p_config_file->get_value("entry", key); + break; + } + } + + Vector<String> dependency_paths; + { + + List<String> dependency_keys; + + if (p_config_file->has_section("dependencies")) + p_config_file->get_section_keys("dependencies", &dependency_keys); + + for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + dependency_paths = p_config_file->get_value("dependencies", key); + break; + } + } + + current_library_path = entry_lib_path; + current_dependencies = dependency_paths; +} + void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_config_file"), &GDNativeLibrary::get_config_file); + ClassDB::bind_method(D_METHOD("set_config_file", "config_file"), &GDNativeLibrary::set_config_file); ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path); ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies); @@ -82,6 +243,8 @@ void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix); ClassDB::bind_method(D_METHOD("set_reloadable", "reloadable"), &GDNativeLibrary::set_reloadable); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "config_file", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile"), "set_config_file", "get_config_file"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton"); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "symbol_prefix"), "set_symbol_prefix", "get_symbol_prefix"); @@ -337,73 +500,7 @@ RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_or *r_error = err; } - lib->set_singleton(config->get_value("general", "singleton", default_singleton)); - lib->set_load_once(config->get_value("general", "load_once", default_load_once)); - lib->set_symbol_prefix(config->get_value("general", "symbol_prefix", default_symbol_prefix)); - lib->set_reloadable(config->get_value("general", "reloadable", default_reloadable)); - - String entry_lib_path; - { - - List<String> entry_keys; - config->get_section_keys("entry", &entry_keys); - - for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - entry_lib_path = config->get_value("entry", key); - break; - } - } - - Vector<String> dependency_paths; - { - - List<String> dependency_keys; - config->get_section_keys("dependencies", &dependency_keys); - - for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - dependency_paths = config->get_value("dependencies", key); - break; - } - } - - lib->current_library_path = entry_lib_path; - lib->current_dependencies = dependency_paths; + lib->set_config_file(config); return lib; } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 3298ea950f..b17bb94f1c 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -66,8 +66,14 @@ public: GDNativeLibrary(); ~GDNativeLibrary(); + virtual bool _set(const StringName &p_name, const Variant &p_property); + virtual bool _get(const StringName &p_name, Variant &r_property) const; + virtual void _get_property_list(List<PropertyInfo> *p_list) const; + _FORCE_INLINE_ Ref<ConfigFile> get_config_file() { return config_file; } + void set_config_file(Ref<ConfigFile> p_config_file); + // things that change per-platform // so there are no setters for this _FORCE_INLINE_ String get_current_library_path() const { diff --git a/modules/gdscript/gdscript_highlighter.cpp b/modules/gdscript/gdscript_highlighter.cpp index 1e9f602d86..5b8b652c29 100644 --- a/modules/gdscript/gdscript_highlighter.cpp +++ b/modules/gdscript/gdscript_highlighter.cpp @@ -58,7 +58,7 @@ static bool _is_hex_symbol(CharType c) { return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); } -Map<int, TextEdit::HighlighterInfo> GDSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) { +Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) { Map<int, TextEdit::HighlighterInfo> color_map; bool prev_is_char = false; @@ -255,17 +255,17 @@ Map<int, TextEdit::HighlighterInfo> GDSyntaxHighlighter::_get_line_syntax_highli return color_map; } -String GDSyntaxHighlighter::get_name() { +String GDScriptSyntaxHighlighter::get_name() { return "GDScript"; } -List<String> GDSyntaxHighlighter::get_supported_languages() { +List<String> GDScriptSyntaxHighlighter::get_supported_languages() { List<String> languages; languages.push_back("GDScript"); return languages; } -void GDSyntaxHighlighter::_update_cache() { +void GDScriptSyntaxHighlighter::_update_cache() { font_color = text_editor->get_color("font_color"); symbol_color = text_editor->get_color("symbol_color"); function_color = text_editor->get_color("function_color"); @@ -273,6 +273,6 @@ void GDSyntaxHighlighter::_update_cache() { member_color = text_editor->get_color("member_variable_color"); } -SyntaxHighlighter *GDSyntaxHighlighter::create() { - return memnew(GDSyntaxHighlighter); +SyntaxHighlighter *GDScriptSyntaxHighlighter::create() { + return memnew(GDScriptSyntaxHighlighter); } diff --git a/modules/gdscript/gdscript_highlighter.h b/modules/gdscript/gdscript_highlighter.h index 0148e6ac1b..ef1bdd4103 100644 --- a/modules/gdscript/gdscript_highlighter.h +++ b/modules/gdscript/gdscript_highlighter.h @@ -33,7 +33,7 @@ #include "scene/gui/text_edit.h" -class GDSyntaxHighlighter : public SyntaxHighlighter { +class GDScriptSyntaxHighlighter : public SyntaxHighlighter { private: // colours Color font_color; diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 4cf13e3b71..85c94c3596 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -93,7 +93,7 @@ void register_gdscript_types() { ResourceSaver::add_resource_format_saver(resource_saver_gd); #ifdef TOOLS_ENABLED - ScriptEditor::register_create_syntax_highlighter_function(GDSyntaxHighlighter::create); + ScriptEditor::register_create_syntax_highlighter_function(GDScriptSyntaxHighlighter::create); EditorNode::add_init_callback(_editor_init); #endif } diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 9baf58c3eb..579c06f76b 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -936,6 +936,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { + if (step == 0) + return; + os_android->main_loop_request_go_back(); } @@ -976,6 +979,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) { + if (step == 0) + return; + Vector<OS_Android::TouchPos> points; for (int i = 0; i < count; i++) { @@ -1250,6 +1256,8 @@ static unsigned int android_get_keysym(unsigned int p_code) { } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) { + if (step == 0) + return; OS_Android::JoypadEvent jevent; jevent.device = p_device; @@ -1261,6 +1269,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { + if (step == 0) + return; OS_Android::JoypadEvent jevent; jevent.device = p_device; @@ -1272,6 +1282,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) { + if (step == 0) + return; + OS_Android::JoypadEvent jevent; jevent.device = p_device; jevent.type = OS_Android::JOY_EVENT_HAT; @@ -1301,6 +1314,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { + if (step == 0) + return; Ref<InputEventKey> ievent; ievent.instance(); @@ -1344,14 +1359,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) { - if (os_android && step > 0) - os_android->main_loop_focusin(); + if (step == 0) + return; + + os_android->main_loop_focusin(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) { - if (os_android && step > 0) - os_android->main_loop_focusout(); + if (step == 0) + return; + + os_android->main_loop_focusout(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) { diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index be1866987a..a48cb872ee 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -139,13 +139,6 @@ def configure(env): # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) - # engine.js uses FS but is not currently evaluated by Emscripten, so export FS. - # TODO: Getting rid of this export is desirable. - extra_exports = [ - 'FS', - ] - env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="%s"' % repr(extra_exports)]) - env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0']) # TODO: Reevaluate usage of this setting now that engine.js manages engine runtime. diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index e6fb48d0d2..e4839af433 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -1,3 +1,5 @@ + exposedLibs['PATH'] = PATH; + exposedLibs['FS'] = FS; return Module; }, }; @@ -12,6 +14,13 @@ var loadingFiles = {}; + function getPathLeaf(path) { + + while (path.endsWith('/')) + path = path.slice(0, -1); + return path.slice(path.lastIndexOf('/') + 1); + } + function getBasePath(path) { if (path.endsWith('/')) @@ -23,14 +32,15 @@ function getBaseName(path) { - path = getBasePath(path); - return path.slice(path.lastIndexOf('/') + 1); + return getPathLeaf(getBasePath(path)); } Engine = function Engine() { this.rtenv = null; + var LIBS = {}; + var initPromise = null; var unloadAfterInit = true; @@ -80,11 +90,11 @@ return new Promise(function(resolve, reject) { rtenvProps.onRuntimeInitialized = resolve; rtenvProps.onAbort = reject; - rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps); + rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps, LIBS); }); } - this.preloadFile = function(pathOrBuffer, bufferFilename) { + this.preloadFile = function(pathOrBuffer, destPath) { if (pathOrBuffer instanceof ArrayBuffer) { pathOrBuffer = new Uint8Array(pathOrBuffer); @@ -93,14 +103,14 @@ } if (pathOrBuffer instanceof Uint8Array) { preloadedFiles.push({ - name: bufferFilename, + path: destPath, buffer: pathOrBuffer }); return Promise.resolve(); } else if (typeof pathOrBuffer === 'string') { return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { preloadedFiles.push({ - name: pathOrBuffer, + path: destPath || pathOrBuffer, buffer: xhr.response }); }); @@ -119,7 +129,12 @@ this.startGame = function(mainPack) { executableName = getBaseName(mainPack); - return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then( + return Promise.all([ + // Load from directory, + this.init(getBasePath(mainPack)), + // ...but write to root where the engine expects it. + this.preloadFile(mainPack, getPathLeaf(mainPack)) + ]).then( Function.prototype.apply.bind(synchronousStart, this, []) ); }; @@ -163,7 +178,16 @@ this.rtenv.thisProgram = executableName || getBaseName(basePath); preloadedFiles.forEach(function(file) { - this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); + var dir = LIBS.PATH.dirname(file.path); + try { + LIBS.FS.stat(dir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + LIBS.FS.mkdirTree(dir); + } + LIBS.FS.createDataFile('/', file.path, new Uint8Array(file.buffer), true, true, true); }, this); preloadedFiles = null; diff --git a/platform/javascript/pre.js b/platform/javascript/pre.js index 311aa44fda..02194bc75e 100644 --- a/platform/javascript/pre.js +++ b/platform/javascript/pre.js @@ -1,2 +1,2 @@ var Engine = { - RuntimeEnvironment: function(Module) { + RuntimeEnvironment: function(Module, exposedLibs) { diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 6ccbaf896b..64116fa1e0 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -101,5 +101,5 @@ int main(int argc, char **argv) { Main::cleanup(); - return 0; + return os.get_exit_code(); }; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index ef23d61141..18e5fc1404 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -192,6 +192,7 @@ static Vector2 get_mouse_pos(NSEvent *event) { // Note: called before main loop init! char *utfs = strdup([filename UTF8String]); OS_OSX::singleton->open_with_filename.parse_utf8(utfs); + free(utfs); return YES; } @@ -838,6 +839,108 @@ static int translateKey(unsigned int key) { return table[key]; } +struct _KeyCodeMap { + UniChar kchar; + int kcode; +}; + +static const _KeyCodeMap _keycodes[55] = { + { '`', KEY_QUOTELEFT }, + { '~', KEY_ASCIITILDE }, + { '0', KEY_KP_0 }, + { '1', KEY_KP_1 }, + { '2', KEY_KP_2 }, + { '3', KEY_KP_3 }, + { '4', KEY_KP_4 }, + { '5', KEY_KP_5 }, + { '6', KEY_KP_6 }, + { '7', KEY_KP_7 }, + { '8', KEY_KP_8 }, + { '9', KEY_KP_9 }, + { '-', KEY_MINUS }, + { '_', KEY_UNDERSCORE }, + { '=', KEY_EQUAL }, + { '+', KEY_PLUS }, + { 'q', KEY_Q }, + { 'w', KEY_W }, + { 'e', KEY_E }, + { 'r', KEY_R }, + { 't', KEY_T }, + { 'y', KEY_Y }, + { 'u', KEY_U }, + { 'i', KEY_I }, + { 'o', KEY_O }, + { 'p', KEY_P }, + { '[', KEY_BRACERIGHT }, + { ']', KEY_BRACELEFT }, + { '{', KEY_BRACERIGHT }, + { '}', KEY_BRACELEFT }, + { 'a', KEY_A }, + { 's', KEY_S }, + { 'd', KEY_D }, + { 'f', KEY_F }, + { 'g', KEY_G }, + { 'h', KEY_H }, + { 'j', KEY_J }, + { 'k', KEY_K }, + { 'l', KEY_L }, + { ';', KEY_SEMICOLON }, + { ':', KEY_COLON }, + { '\'', KEY_APOSTROPHE }, + { '\"', KEY_QUOTEDBL }, + { '\\', KEY_BACKSLASH }, + { '#', KEY_NUMBERSIGN }, + { 'z', KEY_Z }, + { 'x', KEY_X }, + { 'c', KEY_C }, + { 'v', KEY_V }, + { 'b', KEY_B }, + { 'n', KEY_N }, + { 'm', KEY_M }, + { ',', KEY_COMMA }, + { '.', KEY_PERIOD }, + { '/', KEY_SLASH } +}; + +static int remapKey(unsigned int key) { + + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + if (!currentKeyboard) + return translateKey(key); + + CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + if (!layoutData) + return nil; + + const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); + + UInt32 keysDown = 0; + UniChar chars[4]; + UniCharCount realLength; + + OSStatus err = UCKeyTranslate(keyboardLayout, + key, + kUCKeyActionDisplay, + 0, + LMGetKbdType(), + kUCKeyTranslateNoDeadKeysBit, + &keysDown, + sizeof(chars) / sizeof(chars[0]), + &realLength, + chars); + + if (err != noErr) { + return translateKey(key); + } + + for (unsigned int i = 0; i < 55; i++) { + if (_keycodes[i].kchar == chars[0]) { + return _keycodes[i].kcode; + } + } + return translateKey(key); +} + - (void)keyDown:(NSEvent *)event { //disable raw input in IME mode @@ -847,7 +950,7 @@ static int translateKey(unsigned int key) { ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.scancode = remapKey([event keyCode]); ke.unicode = 0; push_to_key_event_buffer(ke); @@ -900,7 +1003,7 @@ static int translateKey(unsigned int key) { } ke.osx_state = mod; - ke.scancode = latin_keyboard_keycode_convert(translateKey(key)); + ke.scancode = remapKey(key); ke.unicode = 0; push_to_key_event_buffer(ke); @@ -916,7 +1019,7 @@ static int translateKey(unsigned int key) { ke.osx_state = [event modifierFlags]; ke.pressed = false; ke.echo = false; - ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.scancode = remapKey([event keyCode]); ke.unicode = 0; push_to_key_event_buffer(ke); diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index d5a9bfb606..37aeef8999 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -1492,11 +1492,6 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID } }, { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID } }, - { "abs", TYPE_UINT, { TYPE_UINT, TYPE_VOID } }, - { "abs", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "abs", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "abs", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID } }, - { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, |