diff --git a/SConstruct b/SConstruct index 537bb0e395a..11b35e0b4bb 100644 --- a/SConstruct +++ b/SConstruct @@ -123,6 +123,7 @@ opts.Add('disable_3d', 'Disable 3D nodes for smaller executable (yes/no)', "no") opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no") opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no') opts.Add('extra_suffix', 'Custom extra suffix added to the base filename of all generated binary files.', '') +opts.Add('vsproj', 'Generate Visual Studio Project. (yes/no)', 'no') # add platform specific options @@ -177,6 +178,25 @@ if selected_platform in platform_list: else: env = env_base.Clone() + if env['vsproj']=="yes": + env.vs_incs = [] + env.vs_srcs = [] + + def AddToVSProject( sources ): + for x in sources: + if type(x) == type(""): + fname = env.File(x).path + else: + fname = env.File(x)[0].path + pieces = fname.split(".") + if len(pieces)>0: + basename = pieces[0] + basename = basename.replace('\\\\','/') + env.vs_srcs = env.vs_srcs + [basename + ".cpp"] + env.vs_incs = env.vs_incs + [basename + ".h"] + #print basename + env.AddToVSProject = AddToVSProject + env.extra_suffix="" if env["extra_suffix"] != '' : @@ -330,6 +350,32 @@ if selected_platform in platform_list: SConscript("main/SCsub") SConscript("platform/"+selected_platform+"/SCsub"); # build selected platform + + # Microsoft Visual Studio Project Generation + if (env['vsproj'])=="yes": + + AddToVSProject(env.core_sources) + AddToVSProject(env.main_sources) + AddToVSProject(env.modules_sources) + AddToVSProject(env.scene_sources) + AddToVSProject(env.servers_sources) + AddToVSProject(env.tool_sources) + + debug_variants = ['Debug|Win32']+['Debug|x64'] + release_variants = ['Release|Win32']+['Release|x64'] + release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64'] + variants = debug_variants + release_variants + release_debug_variants + debug_targets = ['Debug']+['Debug'] + release_targets = ['Release']+['Release'] + release_debug_targets = ['ReleaseDebug']+['ReleaseDebug'] + targets = debug_targets + release_targets + release_debug_targets + msvproj = env.MSVSProject(target = ['#godot' + env['MSVSPROJECTSUFFIX'] ], + incs = env.vs_incs, + srcs = env.vs_srcs, + runfile = targets, + buildtarget = targets, + auto_build_solution=1, + variant = variants) else: diff --git a/core/globals.cpp b/core/globals.cpp index b128914de59..23d8c16ace0 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -1381,7 +1381,7 @@ Globals::Globals() { set("application/name","" ); set("application/main_scene",""); - custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"xml,res,scn,xscn"); + custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"scn,res,xscn,xml"); set("application/disable_stdout",false); set("application/use_shared_user_dir",true); diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 749f7d16419..2880c4ebdab 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -39,7 +39,7 @@ void FileAccessMemory::register_file(String p_name, Vector p_data) { if (!files) { files = memnew((Map >)); - }; + } String name; if (Globals::get_singleton()) @@ -49,7 +49,7 @@ void FileAccessMemory::register_file(String p_name, Vector p_data) { name = DirAccess::normalize_path(name); (*files)[name] = p_data; -}; +} void FileAccessMemory::cleanup() { @@ -57,13 +57,13 @@ void FileAccessMemory::cleanup() { return; memdelete(files); -}; +} FileAccess* FileAccessMemory::create() { return memnew(FileAccessMemory); -}; +} bool FileAccessMemory::file_exists(const String& p_name) { @@ -71,7 +71,7 @@ bool FileAccessMemory::file_exists(const String& p_name) { name = DirAccess::normalize_path(name); return files && (files->find(name) != NULL); -}; +} Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) { @@ -89,57 +89,57 @@ Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) { pos = 0; return OK; -}; +} void FileAccessMemory::close() { data = NULL; -}; +} bool FileAccessMemory::is_open() const { return data != NULL; -}; +} void FileAccessMemory::seek(size_t p_position) { ERR_FAIL_COND(!data); pos = p_position; -}; +} void FileAccessMemory::seek_end(int64_t p_position) { ERR_FAIL_COND(!data); pos = length + p_position; -}; +} size_t FileAccessMemory::get_pos() const { ERR_FAIL_COND_V(!data, 0); return pos; -}; +} size_t FileAccessMemory::get_len() const { ERR_FAIL_COND_V(!data, 0); return length; -}; +} bool FileAccessMemory::eof_reached() const { return pos >= length; -}; +} uint8_t FileAccessMemory::get_8() const { - uint8_t ret; + uint8_t ret = 0; if (pos < length) { ret = data[pos]; - }; + } ++pos; return ret; -}; +} int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const { @@ -156,19 +156,19 @@ int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const { pos += p_length; return read; -}; +} Error FileAccessMemory::get_error() const { return pos >= length ? ERR_FILE_EOF : OK; -}; +} void FileAccessMemory::store_8(uint8_t p_byte) { ERR_FAIL_COND(!data); ERR_FAIL_COND(pos >= length); data[pos++] = p_byte; -}; +} void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) { @@ -176,11 +176,11 @@ void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) { int write = MIN(p_length, left); if (write < p_length) { WARN_PRINT("Writing less data than requested"); - }; + } copymem(&data[pos], p_src, write); pos += p_length; -}; +} FileAccessMemory::FileAccessMemory() { diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index bf1211f2b31..339a6d0528a 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -92,7 +92,9 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o void PackedData::add_pack_source(PackSource *p_source) { - sources.push_back(p_source); + if (p_source != NULL) { + sources.push_back(p_source); + } }; PackedData *PackedData::singleton=NULL; diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index 5922d839071..3e625ba6fd7 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -309,6 +309,7 @@ Error ResourceInteractiveLoaderXML::_parse_array_element(Vector &buff,bool buff_max++; buff.resize(buff_max); + buffptr=buff.ptr(); } @@ -1849,7 +1850,7 @@ void ResourceFormatSaverXMLInstance::escape(String& p_str) { p_str=p_str.replace(">","<"); p_str=p_str.replace("'","'"); p_str=p_str.replace("\"","""); - for (int i=1;i<32;i++) { + for (char i=1;i<32;i++) { char chr[2]={i,0}; const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; @@ -2563,7 +2564,7 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res List property_list; res->get_property_list(&property_list); - property_list.sort(); +// property_list.sort(); for(List::Element *PE = property_list.front();PE;PE=PE->next()) { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 7e441cea1fa..03b6c9759b3 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -117,6 +117,7 @@ Ref ResourceFormatLoader::load_interactive(const Stri RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) { + String path=p_path; //or this must be implemented Ref ril = load_interactive(p_path); @@ -150,9 +151,13 @@ void ResourceFormatLoader::get_dependencies(const String& p_path,List *p RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) { - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); - local_path=find_complete_path(p_path,p_type_hint); + local_path=find_complete_path(local_path,p_type_hint); ERR_FAIL_COND_V(local_path=="",RES()); if (!p_no_cache && ResourceCache::has(local_path)) { @@ -209,7 +214,11 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n Ref ResourceLoader::load_import_metadata(const String &p_path) { - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); String extension=p_path.extension(); bool found=false; @@ -283,9 +292,13 @@ Ref ResourceLoader::load_interactive(const String &p_ - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); - local_path=find_complete_path(p_path,p_type_hint); + local_path=find_complete_path(local_path,p_type_hint); ERR_FAIL_COND_V(local_path=="",Ref()); @@ -340,7 +353,13 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l void ResourceLoader::get_dependencies(const String& p_path,List *p_dependencies) { - String local_path = Globals::get_singleton()->localize_path(p_path); + + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); + String remapped_path = PathRemap::get_singleton()->get_remap(local_path); String extension=remapped_path.extension(); @@ -359,7 +378,11 @@ void ResourceLoader::get_dependencies(const String& p_path,List *p_depen String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) { - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); return find_complete_path(local_path,p_type); @@ -367,7 +390,12 @@ String ResourceLoader::guess_full_filename(const String &p_path,const String& p_ String ResourceLoader::get_resource_type(const String &p_path) { - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); + String remapped_path = PathRemap::get_singleton()->get_remap(local_path); String extension=remapped_path.extension(); diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 6ad5c7499b4..3c94ac5bc78 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -36,8 +36,9 @@ uint32_t Math::default_seed=1; #define PHI 0x9e3779b9 -static uint32_t Q[4096], c = 362436; - +#if 0 +static uint32_t Q[4096]; +#endif uint32_t Math::rand_from_seed(uint32_t *seed) { @@ -269,7 +270,7 @@ bool Math::is_inf(double p_val) { uint32_t Math::larger_prime(uint32_t p_val) { - static const int primes[] = { + static const uint32_t primes[] = { 5, 13, 23, diff --git a/core/method_bind.h b/core/method_bind.h index d32050cc5d2..49c64bd11c3 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -98,7 +98,7 @@ struct VariantCaster {\ #define CHECK_ARG(m_arg)\ if ((m_arg-1)get_type(),argtype)) {\ + if (!Variant::can_convert_strict(p_args[m_arg-1]->get_type(),argtype)) {\ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\ r_error.argument=m_arg-1;\ r_error.expected=argtype;\ diff --git a/core/object.cpp b/core/object.cpp index 07e24655c2a..c1904d05d76 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1282,6 +1282,23 @@ void Object::get_signal_list(List *p_signals ) const { } } + +void Object::get_all_signal_connections(List *p_connections) const { + + const StringName *S=NULL; + + while((S=signal_map.next(S))) { + + const Signal *s=&signal_map[*S]; + + for(int i=0;islot_map.size();i++) { + + p_connections->push_back(s->slot_map.getv(i).conn); + } + } + +} + void Object::get_signal_connection_list(const StringName& p_signal,List *p_connections) const { const Signal *s=signal_map.getptr(p_signal); diff --git a/core/object.h b/core/object.h index 44464ab1999..fc64b91412c 100644 --- a/core/object.h +++ b/core/object.h @@ -574,6 +574,7 @@ public: void emit_signal(const StringName& p_name,VARIANT_ARG_LIST); void get_signal_list(List *p_signals ) const; void get_signal_connection_list(const StringName& p_signal,List *p_connections) const; + void get_all_signal_connections(List *p_connections) const; Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector& p_binds=Vector(),uint32_t p_flags=0); void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method); diff --git a/core/ustring.cpp b/core/ustring.cpp index ffd22c1f8f6..5df95ac4c2e 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3297,8 +3297,11 @@ String String::path_to_file(const String& p_path) const { String src=this->replace("\\","/").get_base_dir(); String dst=p_path.replace("\\","/").get_base_dir(); - - return src.path_to(dst)+p_path.get_file(); + String rel = src.path_to(dst); + if (rel==dst) // failed + return p_path; + else + return rel+p_path.get_file(); } String String::path_to(const String& p_path) const { @@ -3333,7 +3336,9 @@ String String::path_to(const String& p_path) const { String src_begin=src.get_slice("/",0); String dst_begin=dst.get_slice("/",0); - ERR_FAIL_COND_V(src_begin!=dst_begin,p_path); //return dst absolute path + if (src_begin!=dst_begin) + return p_path; //impossible to do this + base=src_begin; src=src.substr(src_begin.length(),src.length()); dst=dst.substr(dst_begin.length(),dst.length()); diff --git a/core/variant.cpp b/core/variant.cpp index fe6a6b3e4f2..d7817ac2689 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -258,12 +258,12 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) { case MATRIX32: { - static const Type invalid[]={ + static const Type valid[]={ TRANSFORM, NIL }; - invalid_types=invalid; + valid_types=valid; } break; case QUAT: { @@ -299,6 +299,256 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) { } break; + case COLOR: { + + static const Type valid[] = { + //STRING, + //INT, + NIL, + }; + + valid_types = valid; + + } break; + + case _RID: { + + static const Type valid[]={ + OBJECT, + NIL + }; + + valid_types=valid; + } break; + case OBJECT: { + + static const Type valid[]={ + NIL + }; + + valid_types=valid; + } break; + case NODE_PATH: { + + static const Type valid[]={ + STRING, + NIL + }; + + valid_types=valid; + } break; + case ARRAY: { + + + static const Type valid[]={ + RAW_ARRAY, + INT_ARRAY, + STRING_ARRAY, + REAL_ARRAY, + COLOR_ARRAY, + VECTOR2_ARRAY, + VECTOR3_ARRAY, + NIL + }; + + valid_types=valid; + } break; + // arrays + case RAW_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + + valid_types=valid; + } break; + case INT_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + valid_types=valid; + } break; + case REAL_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + + valid_types=valid; + } break; + case STRING_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + valid_types=valid; + } break; + case VECTOR2_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + valid_types=valid; + + } break; + case VECTOR3_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + valid_types=valid; + + } break; + case COLOR_ARRAY: { + + static const Type valid[]={ + ARRAY, + NIL + }; + + valid_types=valid; + + } break; + default: {} + } + + + if (valid_types) { + + int i=0; + while(valid_types[i]!=NIL) { + + if (p_type_from==valid_types[i]) + return true; + i++; + } + } else if (invalid_types) { + + + int i=0; + while(invalid_types[i]!=NIL) { + + if (p_type_from==invalid_types[i]) + return false; + i++; + } + } + + return false; + +} + +bool Variant::can_convert_strict(Variant::Type p_type_from,Variant::Type p_type_to) { + + if (p_type_from==p_type_to) + return true; + if (p_type_to==NIL && p_type_from!=NIL) //nil can convert to anything + return true; + + if (p_type_from == NIL) { + return (p_type_to == OBJECT); + }; + + const Type *valid_types=NULL; + const Type *invalid_types=NULL; + + switch(p_type_to) { + case BOOL: { + + static const Type valid[]={ + INT, + REAL, + //STRING, + NIL, + }; + + valid_types=valid; + } break; + case INT: { + + static const Type valid[]={ + BOOL, + REAL, + //STRING, + NIL, + }; + + valid_types=valid; + + } break; + case REAL: { + + static const Type valid[]={ + BOOL, + INT, + //STRING, + NIL, + }; + + valid_types=valid; + + } break; + case STRING: { + + + static const Type valid[]={ + NODE_PATH, + NIL + }; + + valid_types=valid; + } break; + case MATRIX32: { + + + static const Type valid[]={ + TRANSFORM, + NIL + }; + + valid_types=valid; + } break; + case QUAT: { + + static const Type valid[]={ + MATRIX3, + NIL + }; + + valid_types=valid; + + } break; + case MATRIX3: { + + static const Type valid[]={ + QUAT, + NIL + }; + + valid_types=valid; + + + } break; + case TRANSFORM: { + + static const Type valid[]={ + MATRIX32, + QUAT, + MATRIX3, + NIL + }; + + valid_types=valid; + + } break; + case COLOR: { static const Type valid[] = { @@ -532,7 +782,7 @@ bool Variant::is_zero() const { } break; case QUAT: { - *reinterpret_cast(_data._mem)==Quat(); + return *reinterpret_cast(_data._mem)==Quat(); } break; case MATRIX3: { diff --git a/core/variant.h b/core/variant.h index 85c7b92c0da..5f338ef667f 100644 --- a/core/variant.h +++ b/core/variant.h @@ -165,7 +165,8 @@ public: _FORCE_INLINE_ Type get_type() const { return type; } static String get_type_name(Variant::Type p_type); - static bool can_convert(Type p_type_from,Type p_type_to); + static bool can_convert(Type p_type_from, Type p_type_to); + static bool can_convert_strict(Type p_type_from, Type p_type_to); diff --git a/demos/2d/isometric/bastiles.res b/demos/2d/isometric/bastiles.res index 2161c88f1e8..50f3c783216 100644 Binary files a/demos/2d/isometric/bastiles.res and b/demos/2d/isometric/bastiles.res differ diff --git a/demos/2d/isometric/dungeon.scn b/demos/2d/isometric/dungeon.scn index 58c530d5c53..64efc257c0c 100644 Binary files a/demos/2d/isometric/dungeon.scn and b/demos/2d/isometric/dungeon.scn differ diff --git a/demos/2d/isometric/tileset.scn b/demos/2d/isometric/tileset.scn index edb0bc0276d..c04ea5382c0 100644 Binary files a/demos/2d/isometric/tileset.scn and b/demos/2d/isometric/tileset.scn differ diff --git a/demos/2d/isometric/troll.scn b/demos/2d/isometric/troll.scn index f5d87c36318..19b566fe05e 100644 Binary files a/demos/2d/isometric/troll.scn and b/demos/2d/isometric/troll.scn differ diff --git a/demos/2d/isometric_light/cubio.scn b/demos/2d/isometric_light/cubio.scn index c52b7dfd4be..fc931b0c8dc 100644 Binary files a/demos/2d/isometric_light/cubio.scn and b/demos/2d/isometric_light/cubio.scn differ diff --git a/demos/2d/isometric_light/engine.cfg b/demos/2d/isometric_light/engine.cfg index 0d9e432d5de..08393f17240 100644 --- a/demos/2d/isometric_light/engine.cfg +++ b/demos/2d/isometric_light/engine.cfg @@ -1,5 +1,6 @@ [application] +name="Isometric 2D + Lighting" main_scene="res://map.scn" [input] diff --git a/demos/2d/isometric_light/map.scn b/demos/2d/isometric_light/map.scn index c1d11f8e4cd..89002f991fe 100644 Binary files a/demos/2d/isometric_light/map.scn and b/demos/2d/isometric_light/map.scn differ diff --git a/demos/2d/isometric_light/tileset.res b/demos/2d/isometric_light/tileset.res index dab6f36f577..f64a4e32bd3 100644 Binary files a/demos/2d/isometric_light/tileset.res and b/demos/2d/isometric_light/tileset.res differ diff --git a/demos/2d/kinematic_char/circle.png b/demos/2d/kinematic_char/circle.png new file mode 100644 index 00000000000..ddb3ac4b9c2 Binary files /dev/null and b/demos/2d/kinematic_char/circle.png differ diff --git a/demos/2d/kinematic_char/colworld.scn b/demos/2d/kinematic_char/colworld.scn index 6c73e8b1268..e66705368d8 100644 Binary files a/demos/2d/kinematic_char/colworld.scn and b/demos/2d/kinematic_char/colworld.scn differ diff --git a/demos/2d/kinematic_char/long_obstacle.png b/demos/2d/kinematic_char/long_obstacle.png new file mode 100644 index 00000000000..88cb22daee6 Binary files /dev/null and b/demos/2d/kinematic_char/long_obstacle.png differ diff --git a/demos/2d/kinematic_char/player.gd b/demos/2d/kinematic_char/player.gd index e8b3cc8d008..329382408bf 100644 --- a/demos/2d/kinematic_char/player.gd +++ b/demos/2d/kinematic_char/player.gd @@ -21,6 +21,9 @@ const STOP_FORCE = 1300 const JUMP_SPEED = 200 const JUMP_MAX_AIRBORNE_TIME=0.2 +const SLIDE_STOP_VELOCITY=1.0 #one pixel per second +const SLIDE_STOP_MIN_TRAVEL=1.0 #one pixel + var velocity = Vector2() var on_air_time=100 var jumping=false @@ -31,8 +34,6 @@ func _fixed_process(delta): #create forces var force = Vector2(0,GRAVITY) - - var stop = velocity.x!=0.0 var walk_left = Input.is_action_pressed("move_left") var walk_right = Input.is_action_pressed("move_right") @@ -86,25 +87,42 @@ func _fixed_process(delta): #char is on floor on_air_time=0 floor_velocity=get_collider_velocity() - #velocity.y=0 - #But we were moving and our motion was interrupted, - #so try to complete the motion by "sliding" - #by the normal - motion = n.slide(motion) - velocity = n.slide(velocity) - - #then move again - move(motion) + + if (on_air_time==0 and force.x==0 and get_travel().length() < SLIDE_STOP_MIN_TRAVEL and abs(velocity.x) < SLIDE_STOP_VELOCITY and get_collider_velocity()==Vector2()): + #Since this formula will always slide the character around, + #a special case must be considered to to stop it from moving + #if standing on an inclined floor. Conditions are: + # 1) Standing on floor (on_air_time==0) + # 2) Did not move more than one pixel (get_travel().length() < SLIDE_STOP_MIN_TRAVEL) + # 3) Not moving horizontally (abs(velocity.x) < SLIDE_STOP_VELOCITY) + # 4) Collider is not moving + + revert_motion() + velocity.y=0.0 + + else: + #For every other case of motion,our motion was interrupted. + #Try to complete the motion by "sliding" + #by the normal + + motion = n.slide(motion) + velocity = n.slide(velocity) + #then move again + move(motion) if (floor_velocity!=Vector2()): #if floor moves, move with floor move(floor_velocity*delta) if (jumping and velocity.y>0): + #if falling, no longer jumping jumping=false if (on_air_time + + + + 0 + 100, 10 + + + + + "conn_count" + 0 + "conns" + + "names" + + "one_way_platform" + "StaticBody2D" + "_import_path" + "visibility/visible" + "visibility/opacity" + "visibility/self_opacity" + "visibility/light_mask" + "transform/pos" + "transform/rot" + "transform/scale" + "z/z" + "z/relative" + "input/pickable" + "shape_count" + "shapes/0/shape" + "shapes/0/transform" + "shapes/0/trigger" + "collision/layers" + "collision/mask" + "one_way_collision/direction" + "one_way_collision/max_depth" + "constant_linear_velocity" + "constant_angular_velocity" + "friction" + "bounce" + "__meta__" + "sprite" + "Sprite" + "texture" + "centered" + "offset" + "flip_h" + "flip_v" + "vframes" + "hframes" + "frame" + "modulate" + "region" + "region_rect" + "CollisionShape2D" + "shape" + "trigger" + + "node_count" + 3 + "nodes" + -1, -1, 1, 0, -1, 24, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 1, 12, 8, 13, 3, 14, 9, 15, 10, 16, 8, 17, 3, 18, 3, 19, 11, 20, 12, 21, 4, 22, 5, 23, 2, 24, 5, 25, 13, 0, 0, 0, 27, 26, -1, 21, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 1, 28, 14, 29, 1, 30, 4, 31, 8, 32, 8, 33, 3, 34, 3, 35, 7, 36, 15, 37, 8, 38, 16, 0, 0, 0, 39, 39, -1, 12, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 17, 8, 5, 9, 6, 10, 7, 11, 1, 40, 9, 41, 8, 0 + "variants" + + "" + True + 1 + 1 + 0, 0 + 0 + 1, 1 + 0 + False + + 1, -0, 0, 1, 1.46304, -13.1672 + 0, 1 + 20 + + "__editor_plugin_screen__" + "2D" + "__editor_plugin_states__" + + "2D" + + "ofs" + -133.699, -110.553 + "snap_grid" + False + "snap_offset" + 0, 0 + "snap_pixel" + False + "snap_relative" + False + "snap_rotation" + False + "snap_rotation_offset" + 0 + "snap_rotation_step" + 0.261799 + "snap_show_grid" + False + "snap_step" + 10, 10 + "zoom" + 2.050546 + + "3D" + + "ambient_light_color" + 0.15, 0.15, 0.15, 1 + "default_light" + True + "default_srgb" + False + "deflight_rot_x" + 0.942478 + "deflight_rot_y" + 0.628319 + "fov" + 45 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 + "viewports" + + + "distance" + 4 + "listener" + True + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "zfar" + 500 + "znear" + 0.1 + + + "__editor_run_settings__" + + "custom_args" + "-l $scene" + "run_mode" + 0 + + + + 1, 1, 1, 1 + 0, 0, 0, 0 + 1.46304, -13.1672 + + "version" + 1 + + + + \ No newline at end of file diff --git a/demos/2d/platformer/player.gd b/demos/2d/platformer/player.gd index b08105212ce..9ee189df21e 100644 --- a/demos/2d/platformer/player.gd +++ b/demos/2d/platformer/player.gd @@ -33,7 +33,6 @@ var shooting=false var WALK_ACCEL = 800.0 var WALK_DEACCEL= 800.0 var WALK_MAX_VELOCITY= 200.0 -var GRAVITY = 700.0 var AIR_ACCEL = 200.0 var AIR_DEACCEL= 200.0 var JUMP_VELOCITY=460 diff --git a/demos/2d/platformer/stage.xml b/demos/2d/platformer/stage.xml index 610057183b9..4d6083adf64 100644 --- a/demos/2d/platformer/stage.xml +++ b/demos/2d/platformer/stage.xml @@ -1,17 +1,22 @@ - - + - - + - + + + + + "conn_count" + 0 + "conns" + "names" - + "stage" "Node" "_import_path" @@ -39,6 +44,7 @@ "collision/friction" "collision/bounce" "collision/layers" + "collision/mask" "tile_data" "coins" "coin" @@ -84,8 +90,6 @@ "coin 31 7 3" "coin 31 7 4" "coin 31 7 5" - "player" - "RigidBody2D" "props" "moving_platform" "Node2D" @@ -94,6 +98,10 @@ "moving_platform 2" "moving_platform 3" "seesaw" + "one_way_platform" + "StaticBody2D" + "player" + "RigidBody2D" "music" "StreamPlayer" "stream/stream" @@ -143,22 +151,139 @@ "uppercase" "percent_visible" - "version" - 1 - "conn_count" - 0 "node_count" - 66 + 67 + "nodes" + -1, -1, 1, 0, -1, 2, 2, 0, 3, 1, 0, 0, 0, 5, 4, -1, 25, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 8, 14, 2, 15, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 8, 22, 14, 23, 14, 24, 3, 25, 6, 26, 4, 27, 4, 28, 15, 3, 16, 0, 0, 0, 1, 29, -1, 1, 2, 0, 0, 2, 0, 31, 30, 17, 3, 2, 0, 10, 18, 3, 19, 0, 2, 0, 31, 32, 17, 3, 2, 0, 10, 20, 3, 19, 0, 2, 0, 31, 33, 17, 3, 2, 0, 10, 21, 3, 19, 0, 2, 0, 31, 34, 17, 3, 2, 0, 10, 22, 3, 19, 0, 2, 0, 31, 35, 17, 3, 2, 0, 10, 23, 3, 19, 0, 2, 0, 31, 36, 17, 3, 2, 0, 10, 24, 3, 19, 0, 2, 0, 31, 37, 17, 3, 2, 0, 10, 25, 3, 19, 0, 2, 0, 31, 38, 17, 3, 2, 0, 10, 26, 3, 19, 0, 2, 0, 31, 39, 17, 3, 2, 0, 10, 27, 3, 19, 0, 2, 0, 31, 40, 17, 3, 2, 0, 10, 28, 3, 19, 0, 2, 0, 31, 41, 17, 3, 2, 0, 10, 29, 3, 19, 0, 2, 0, 31, 42, 17, 3, 2, 0, 10, 30, 3, 19, 0, 2, 0, 31, 43, 17, 3, 2, 0, 10, 31, 3, 19, 0, 2, 0, 31, 44, 17, 3, 2, 0, 10, 32, 3, 19, 0, 2, 0, 31, 45, 17, 3, 2, 0, 10, 33, 3, 19, 0, 2, 0, 31, 46, 17, 3, 2, 0, 10, 34, 3, 19, 0, 2, 0, 31, 47, 17, 3, 2, 0, 10, 35, 3, 19, 0, 2, 0, 31, 48, 17, 3, 2, 0, 10, 36, 3, 19, 0, 2, 0, 31, 49, 17, 3, 2, 0, 10, 37, 3, 19, 0, 2, 0, 31, 50, 17, 3, 2, 0, 10, 38, 3, 19, 0, 2, 0, 31, 51, 17, 3, 2, 0, 10, 39, 3, 19, 0, 2, 0, 31, 52, 17, 3, 2, 0, 10, 40, 3, 19, 0, 2, 0, 31, 53, 17, 3, 2, 0, 10, 41, 3, 19, 0, 2, 0, 31, 54, 17, 3, 2, 0, 10, 42, 3, 19, 0, 2, 0, 31, 55, 17, 3, 2, 0, 10, 43, 3, 19, 0, 2, 0, 31, 56, 17, 3, 2, 0, 10, 44, 3, 19, 0, 2, 0, 31, 57, 17, 3, 2, 0, 10, 45, 3, 19, 0, 2, 0, 31, 58, 17, 3, 2, 0, 10, 46, 3, 19, 0, 2, 0, 31, 59, 17, 3, 2, 0, 10, 47, 3, 19, 0, 2, 0, 31, 60, 17, 3, 2, 0, 10, 48, 3, 19, 0, 2, 0, 31, 61, 17, 3, 2, 0, 10, 49, 3, 19, 0, 2, 0, 31, 62, 17, 3, 2, 0, 10, 50, 3, 19, 0, 2, 0, 31, 63, 17, 3, 2, 0, 10, 51, 3, 19, 0, 2, 0, 31, 64, 17, 3, 2, 0, 10, 52, 3, 19, 0, 2, 0, 31, 65, 17, 3, 2, 0, 10, 53, 3, 19, 0, 2, 0, 31, 66, 17, 3, 2, 0, 10, 54, 3, 19, 0, 2, 0, 31, 67, 17, 3, 2, 0, 10, 55, 3, 19, 0, 2, 0, 31, 68, 17, 3, 2, 0, 10, 56, 3, 19, 0, 2, 0, 31, 69, 17, 3, 2, 0, 10, 57, 3, 19, 0, 2, 0, 31, 70, 17, 3, 2, 0, 10, 58, 3, 19, 0, 2, 0, 31, 71, 17, 3, 2, 0, 10, 59, 3, 19, 0, 2, 0, 31, 72, 17, 3, 2, 0, 10, 60, 3, 19, 0, 0, 0, 1, 73, -1, 1, 2, 0, 0, 45, 0, 75, 74, 61, 5, 2, 0, 10, 62, 3, 63, 76, 64, 77, 65, 0, 45, 0, 75, 78, 61, 5, 2, 0, 10, 66, 3, 63, 76, 67, 77, 68, 0, 45, 0, 75, 79, 61, 5, 2, 0, 10, 69, 3, 63, 76, 70, 77, 68, 0, 45, 0, 75, 80, 71, 3, 2, 0, 10, 72, 3, 73, 0, 45, 0, 82, 81, 74, 3, 2, 0, 10, 75, 3, 76, 0, 0, 0, 84, 83, 77, 3, 2, 0, 10, 78, 3, 79, 0, 0, 0, 86, 85, -1, 7, 2, 0, 87, 80, 88, 14, 89, 2, 90, 81, 91, 2, 92, 14, 0, 0, 0, 1, 93, -1, 1, 2, 0, 0, 53, 0, 84, 94, 82, 3, 2, 0, 10, 83, 3, 84, 0, 53, 0, 84, 95, 82, 3, 2, 0, 10, 85, 3, 84, 0, 53, 0, 84, 96, 82, 3, 2, 0, 10, 86, 3, 84, 0, 53, 0, 84, 97, 82, 3, 2, 0, 10, 87, 3, 84, 0, 53, 0, 84, 98, 82, 3, 2, 0, 10, 88, 3, 84, 0, 53, 0, 84, 99, 82, 3, 2, 0, 10, 89, 3, 84, 0, 53, 0, 84, 100, 82, 3, 2, 0, 10, 90, 3, 84, 0, 53, 0, 84, 101, 82, 3, 2, 0, 10, 91, 3, 84, 0, 53, 0, 84, 102, 82, 3, 2, 0, 10, 92, 3, 84, 0, 53, 0, 84, 103, 82, 3, 2, 0, 10, 93, 3, 84, 0, 53, 0, 84, 104, 82, 3, 2, 0, 10, 94, 3, 84, 0, 0, 0, 106, 105, 95, 2, 2, 0, 3, 96, 0, 0, 0, 107, 107, -1, 30, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 108, 97, 109, 98, 110, 99, 111, 100, 112, 0, 113, 0, 114, 0, 115, 0, 116, 2, 117, 2, 118, 13, 119, 3, 120, 6, 121, 101, 122, 3, 123, 102, 124, 6, 125, 14, 126, 14, 127, 103, 128, 8, 129, 8, 130, 2, 131, 14, 132, 104, 0 "variants" - + "" + "__editor_plugin_screen__" + "2D" "__editor_plugin_states__" + "2D" + + "ofs" + 328.379, 822.226 + "snap_grid" + False + "snap_offset" + 0, 0 + "snap_pixel" + False + "snap_relative" + False + "snap_rotation" + False + "snap_rotation_offset" + 0 + "snap_rotation_step" + 0.261799 + "snap_show_grid" + False + "snap_step" + 10, 10 + "zoom" + 1.108032 + + "3D" + + "ambient_light_color" + 0.15, 0.15, 0.15, 1 + "default_light" + True + "default_srgb" + False + "deflight_rot_x" + 0.942478 + "deflight_rot_y" + 0.628319 + "fov" + 45 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 + "viewports" + + + "distance" + 18.643827 + "listener" + True + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "zfar" + 500 + "znear" + 0.1 + "Script" "current" - 2 + 0 "sources" "res://moving_platform.gd" @@ -167,111 +292,6 @@ "res://coin.gd" - "2D" - - "pixel_snap" - False - "zoom" - 0.814506 - "use_snap" - False - "snap_vec" - 10, 10 - "ofs" - 177.488, 709.633 - - "3D" - - "deflight_rot_y" - 0.628319 - "zfar" - 500 - "fov" - 45 - "viewports" - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - True - "use_environment" - False - "use_orthogonal" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - False - "use_environment" - False - "use_orthogonal" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - False - "use_environment" - False - "use_orthogonal" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - False - "use_environment" - False - "use_orthogonal" - False - "pos" - 0, 0, 0 - - - "viewport_mode" - 1 - "default_light" - True - "ambient_light_color" - 0.15, 0.15, 0.15, 1 - "show_grid" - True - "show_origin" - True - "znear" - 0.1 - "default_srgb" - False - "deflight_rot_x" - 0.942478 - "__editor_run_settings__" @@ -280,8 +300,6 @@ "run_mode" 0 - "__editor_plugin_screen__" - "3D" True 1 @@ -296,20 +314,103 @@ 1, 0, 0, 1, 0, 0 2 False - 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870925, 1048587, 13, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 0, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 + 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 0, 983052, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870914, 1048587, 536870922, 1048588, 2, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114122, 536870925, 1114123, 11, 1114124, 13, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 0, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 "_edit_lock_" True - - "_editor_collapsed" - True - - 672, 1120 + 672, 1179 + "__editor_plugin_screen__" + "2D" "__editor_plugin_states__" + "2D" + + "ofs" + -34.3697, -21.6562 + "pixel_snap" + False + "zoom" + 3.794776 + + "3D" + + "default_light" + True + "fov" + 45 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 + "viewports" + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "zfar" + 500 + "znear" + 0.1 + "Script" "current" @@ -321,91 +422,6 @@ "res://coin.gd" - "2D" - - "pixel_snap" - False - "zoom" - 3.794776 - "ofs" - -34.3697, -21.6562 - - "3D" - - "fov" - 45 - "zfar" - 500 - "viewports" - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "viewport_mode" - 1 - "default_light" - True - "show_grid" - True - "znear" - 0.1 - "show_origin" - True - "__editor_run_settings__" @@ -414,11 +430,9 @@ "run_mode" 0 - "__editor_plugin_screen__" - "2D" - 704, 1120 - 736, 1120 + 704, 1179 + 736, 1179 1120, 992 1152, 992 1184, 992 @@ -458,141 +472,98 @@ 4300.75, 541.058 4236.75, 541.058 4172.75, 541.058 - - 251.684, 1045.6 + + 1451.86, 742.969 + "__editor_plugin_screen__" + "2D" "__editor_plugin_states__" - "Script" - - "current" - 0 - "sources" - - "res://player.gd" - - "2D" + "ofs" + -210.652, -172.81 "pixel_snap" False "zoom" - 2.272073 - "use_snap" - False - "ofs" - -181.946, -86.2812 - "snap" - 10 + 1.360373 "3D" + "default_light" + True "fov" - 45 - "zfar" - 500 + 400 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 "viewports" "distance" 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - True + "pos" + 0, 0, 0 "use_environment" False "use_orthogonal" False - "pos" - 0, 0, 0 + "x_rot" + 0 + "y_rot" + 0 "distance" 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - False + "pos" + 0, 0, 0 "use_environment" False "use_orthogonal" False - "pos" - 0, 0, 0 + "x_rot" + 0 + "y_rot" + 0 "distance" 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - False + "pos" + 0, 0, 0 "use_environment" False "use_orthogonal" False - "pos" - 0, 0, 0 + "x_rot" + 0 + "y_rot" + 0 "distance" 4 - "x_rot" - 0 - "y_rot" - 0 - "listener" - False + "pos" + 0, 0, 0 "use_environment" False "use_orthogonal" False - "pos" - 0, 0, 0 + "x_rot" + 0 + "y_rot" + 0 - "deflight_rot_y" - 0.628319 - "default_light" - True - "viewport_mode" - 1 - "ambient_light_color" - 0.15, 0.15, 0.15, 1 - "show_grid" - True + "zfar" + 500 "znear" 0.1 - "show_origin" - True - "deflight_rot_x" - 0.942478 - "default_srgb" - False - - "__editor_run_settings__" - - "custom_args" - "-l $scene" - "run_mode" - 0 - - "__editor_plugin_screen__" - "Script" - - - 1451.86, 742.969 - - "__editor_plugin_states__" - "Script" "current" @@ -605,91 +576,6 @@ "res://coin.gd" - "2D" - - "pixel_snap" - False - "zoom" - 1.360373 - "ofs" - -210.652, -172.81 - - "3D" - - "fov" - 400 - "zfar" - 500 - "viewports" - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "viewport_mode" - 1 - "default_light" - True - "show_grid" - True - "znear" - 0.1 - "show_origin" - True - "__editor_run_settings__" @@ -698,8 +584,6 @@ "run_mode" 0 - "__editor_plugin_screen__" - "2D" 0, 140 5 @@ -711,92 +595,94 @@ 2402.79, 849.52 + "__editor_plugin_screen__" + "2D" "__editor_plugin_states__" "2D" + "ofs" + -116.979, -109.897 "pixel_snap" False "zoom" 2.050547 - "ofs" - -116.979, -109.897 "3D" + "default_light" + True "fov" 400 - "zfar" - 500 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 "viewports" "distance" 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False "x_rot" 0 "y_rot" 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 "distance" 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False "x_rot" 0 "y_rot" 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 "distance" 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False "x_rot" 0 "y_rot" 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 "distance" 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False "x_rot" 0 "y_rot" 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - "viewport_mode" - 1 - "default_light" - True - "show_grid" - True + "zfar" + 500 "znear" 0.1 - "show_origin" - True "__editor_run_settings__" @@ -806,16 +692,364 @@ "run_mode" 0 + + + 927.698, 1120.81 + "__editor_plugin_screen__" "2D" + "__editor_plugin_states__" + + "2D" + + "ofs" + -133.699, -110.553 + "snap_grid" + False + "snap_offset" + 0, 0 + "snap_pixel" + False + "snap_relative" + False + "snap_rotation" + False + "snap_rotation_offset" + 0 + "snap_rotation_step" + 0.261799 + "snap_show_grid" + False + "snap_step" + 10, 10 + "zoom" + 2.050546 + + "3D" + + "ambient_light_color" + 0.15, 0.15, 0.15, 1 + "default_light" + True + "default_srgb" + False + "deflight_rot_x" + 0.942478 + "deflight_rot_y" + 0.628319 + "fov" + 45 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 + "viewports" + + + "distance" + 4 + "listener" + True + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "zfar" + 500 + "znear" + 0.1 + + + "__editor_run_settings__" + + "custom_args" + "-l $scene" + "run_mode" + 0 + + + + 251.684, 1045.6 + + "__editor_plugin_screen__" + "Script" + "__editor_plugin_states__" + + "2D" + + "ofs" + -181.946, -86.2812 + "pixel_snap" + False + "snap" + 10 + "use_snap" + False + "zoom" + 2.272073 + + "3D" + + "ambient_light_color" + 0.15, 0.15, 0.15, 1 + "default_light" + True + "default_srgb" + False + "deflight_rot_x" + 0.942478 + "deflight_rot_y" + 0.628319 + "fov" + 45 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 + "viewports" + + + "distance" + 4 + "listener" + True + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "listener" + False + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "zfar" + 500 + "znear" + 0.1 + + "Script" + + "current" + 0 + "sources" + + "res://player.gd" + + + + "__editor_run_settings__" + + "custom_args" + "-l $scene" + "run_mode" + 0 + 2 834.664, 1309.6 + "__editor_plugin_screen__" + "2D" "__editor_plugin_states__" + "2D" + + "ofs" + -227.625, -197.9 + "pixel_snap" + False + "zoom" + 1.108033 + + "3D" + + "default_light" + True + "fov" + 45 + "show_grid" + True + "show_origin" + True + "viewport_mode" + 1 + "viewports" + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "distance" + 4 + "pos" + 0, 0, 0 + "use_environment" + False + "use_orthogonal" + False + "x_rot" + 0 + "y_rot" + 0 + + + "zfar" + 500 + "znear" + 0.1 + "Script" "current" @@ -825,91 +1059,6 @@ "res://enemy.gd" - "2D" - - "pixel_snap" - False - "zoom" - 1.108033 - "ofs" - -227.625, -197.9 - - "3D" - - "fov" - 45 - "zfar" - 500 - "viewports" - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "distance" - 4 - "x_rot" - 0 - "y_rot" - 0 - "use_orthogonal" - False - "use_environment" - False - "pos" - 0, 0, 0 - - - "viewport_mode" - 1 - "default_light" - True - "show_grid" - True - "znear" - 0.1 - "show_origin" - True - "__editor_run_settings__" @@ -918,8 +1067,6 @@ "run_mode" 0 - "__editor_plugin_screen__" - "2D" 707.665, 1225.05 1125.21, 1053.06 @@ -933,8 +1080,45 @@ 2406.63, 815.115 + "__editor_plugin_screen__" + "2D" "__editor_plugin_states__" + "2D" + + "ofs" + -5, -25 + "zoom" + 1 + + "3D" + + "fov" + 45 + "window_0" + + "default_light" + True + "distance" + 4 + "pos" + 0, 0, 0 + "show_grid" + True + "show_origin" + True + "x_rot" + 0.337 + "y_rot" + -0.575 + + "window_mode" + 0 + "zfar" + 500 + "znear" + 0.1 + "Script" "current" @@ -947,41 +1131,6 @@ "res://coin.gd" - "2D" - - "zoom" - 1 - "ofs" - -5, -25 - - "3D" - - "zfar" - 500 - "fov" - 45 - "window_mode" - 0 - "window_0" - - "distance" - 4 - "x_rot" - 0.337 - "default_light" - True - "y_rot" - -0.575 - "show_grid" - True - "show_origin" - True - "pos" - 0, 0, 0 - - "znear" - 0.1 - "__editor_run_settings__" @@ -990,8 +1139,6 @@ "run_mode" 0 - "__editor_plugin_screen__" - "2D" 12 -202 @@ -1002,10 +1149,8 @@ "This is a simple demo on how to make a platformer game with Godot."This version uses physics and the 2D physics engine for motion and collision.""The demo also shows the benefits of using the scene system, where coins,"enemies and the player are edited separatedly and instanced in the stage.""To edit the base tiles for the tileset, open the tileset_edit.xml file and follow "instructions."" -1 - "nodes" - -1, -1, 1, 0, -1, 2, 2, 0, 3, 1, 0, 0, 0, 5, 4, -1, 24, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 8, 14, 2, 15, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 8, 22, 14, 23, 14, 24, 3, 25, 6, 26, 4, 27, 15, 3, 16, 0, 0, 0, 1, 28, -1, 2, 2, 0, 3, 17, 0, 2, 0, 30, 29, 18, 3, 2, 0, 10, 19, 3, 20, 0, 2, 0, 30, 31, 18, 3, 2, 0, 10, 21, 3, 20, 0, 2, 0, 30, 32, 18, 3, 2, 0, 10, 22, 3, 20, 0, 2, 0, 30, 33, 18, 3, 2, 0, 10, 23, 3, 20, 0, 2, 0, 30, 34, 18, 3, 2, 0, 10, 24, 3, 20, 0, 2, 0, 30, 35, 18, 3, 2, 0, 10, 25, 3, 20, 0, 2, 0, 30, 36, 18, 3, 2, 0, 10, 26, 3, 20, 0, 2, 0, 30, 37, 18, 3, 2, 0, 10, 27, 3, 20, 0, 2, 0, 30, 38, 18, 3, 2, 0, 10, 28, 3, 20, 0, 2, 0, 30, 39, 18, 3, 2, 0, 10, 29, 3, 20, 0, 2, 0, 30, 40, 18, 3, 2, 0, 10, 30, 3, 20, 0, 2, 0, 30, 41, 18, 3, 2, 0, 10, 31, 3, 20, 0, 2, 0, 30, 42, 18, 3, 2, 0, 10, 32, 3, 20, 0, 2, 0, 30, 43, 18, 3, 2, 0, 10, 33, 3, 20, 0, 2, 0, 30, 44, 18, 3, 2, 0, 10, 34, 3, 20, 0, 2, 0, 30, 45, 18, 3, 2, 0, 10, 35, 3, 20, 0, 2, 0, 30, 46, 18, 3, 2, 0, 10, 36, 3, 20, 0, 2, 0, 30, 47, 18, 3, 2, 0, 10, 37, 3, 20, 0, 2, 0, 30, 48, 18, 3, 2, 0, 10, 38, 3, 20, 0, 2, 0, 30, 49, 18, 3, 2, 0, 10, 39, 3, 20, 0, 2, 0, 30, 50, 18, 3, 2, 0, 10, 40, 3, 20, 0, 2, 0, 30, 51, 18, 3, 2, 0, 10, 41, 3, 20, 0, 2, 0, 30, 52, 18, 3, 2, 0, 10, 42, 3, 20, 0, 2, 0, 30, 53, 18, 3, 2, 0, 10, 43, 3, 20, 0, 2, 0, 30, 54, 18, 3, 2, 0, 10, 44, 3, 20, 0, 2, 0, 30, 55, 18, 3, 2, 0, 10, 45, 3, 20, 0, 2, 0, 30, 56, 18, 3, 2, 0, 10, 46, 3, 20, 0, 2, 0, 30, 57, 18, 3, 2, 0, 10, 47, 3, 20, 0, 2, 0, 30, 58, 18, 3, 2, 0, 10, 48, 3, 20, 0, 2, 0, 30, 59, 18, 3, 2, 0, 10, 49, 3, 20, 0, 2, 0, 30, 60, 18, 3, 2, 0, 10, 50, 3, 20, 0, 2, 0, 30, 61, 18, 3, 2, 0, 10, 51, 3, 20, 0, 2, 0, 30, 62, 18, 3, 2, 0, 10, 52, 3, 20, 0, 2, 0, 30, 63, 18, 3, 2, 0, 10, 53, 3, 20, 0, 2, 0, 30, 64, 18, 3, 2, 0, 10, 54, 3, 20, 0, 2, 0, 30, 65, 18, 3, 2, 0, 10, 55, 3, 20, 0, 2, 0, 30, 66, 18, 3, 2, 0, 10, 56, 3, 20, 0, 2, 0, 30, 67, 18, 3, 2, 0, 10, 57, 3, 20, 0, 2, 0, 30, 68, 18, 3, 2, 0, 10, 58, 3, 20, 0, 2, 0, 30, 69, 18, 3, 2, 0, 10, 59, 3, 20, 0, 2, 0, 30, 70, 18, 3, 2, 0, 10, 60, 3, 20, 0, 2, 0, 30, 71, 18, 3, 2, 0, 10, 61, 3, 20, 0, 0, 0, 73, 72, 62, 3, 2, 0, 10, 63, 3, 64, 0, 0, 0, 1, 74, -1, 1, 2, 0, 0, 46, 0, 76, 75, 65, 5, 2, 0, 10, 66, 3, 67, 77, 68, 78, 69, 0, 46, 0, 76, 79, 65, 5, 2, 0, 10, 70, 3, 67, 77, 71, 78, 72, 0, 46, 0, 76, 80, 65, 5, 2, 0, 10, 73, 3, 67, 77, 74, 78, 72, 0, 46, 0, 76, 81, 75, 3, 2, 0, 10, 76, 3, 77, 0, 0, 0, 83, 82, -1, 7, 2, 0, 84, 78, 85, 14, 86, 2, 87, 79, 88, 2, 89, 14, 0, 0, 0, 1, 90, -1, 1, 2, 0, 0, 52, 0, 73, 91, 80, 3, 2, 0, 10, 81, 3, 82, 0, 52, 0, 73, 92, 80, 3, 2, 0, 10, 83, 3, 82, 0, 52, 0, 73, 93, 80, 3, 2, 0, 10, 84, 3, 82, 0, 52, 0, 73, 94, 80, 3, 2, 0, 10, 85, 3, 82, 0, 52, 0, 73, 95, 80, 3, 2, 0, 10, 86, 3, 82, 0, 52, 0, 73, 96, 80, 3, 2, 0, 10, 87, 3, 82, 0, 52, 0, 73, 97, 80, 3, 2, 0, 10, 88, 3, 82, 0, 52, 0, 73, 98, 80, 3, 2, 0, 10, 89, 3, 82, 0, 52, 0, 73, 99, 80, 3, 2, 0, 10, 90, 3, 82, 0, 52, 0, 73, 100, 80, 3, 2, 0, 10, 91, 3, 82, 0, 52, 0, 73, 101, 80, 3, 2, 0, 10, 92, 3, 82, 0, 0, 0, 103, 102, 93, 2, 2, 0, 3, 94, 0, 0, 0, 104, 104, -1, 30, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 105, 95, 106, 96, 107, 97, 108, 98, 109, 0, 110, 0, 111, 0, 112, 0, 113, 2, 114, 2, 115, 13, 116, 3, 117, 6, 118, 99, 119, 3, 120, 100, 121, 6, 122, 14, 123, 14, 124, 101, 125, 8, 126, 8, 127, 2, 128, 14, 129, 102, 0 - "conns" - + "version" + 1 diff --git a/demos/2d/tetris/grid.gd b/demos/2d/tetris/grid.gd index dc89300881e..8708d168e4a 100644 --- a/demos/2d/tetris/grid.gd +++ b/demos/2d/tetris/grid.gd @@ -143,6 +143,7 @@ func restart_pressed(): cells.clear() get_node("gameover").set_text("") piece_active=true + get_node("../restart").release_focus() update() diff --git a/demos/3d/navmesh/navmesh.scn b/demos/3d/navmesh/navmesh.scn index 73df340b1ec..1202985decb 100644 Binary files a/demos/3d/navmesh/navmesh.scn and b/demos/3d/navmesh/navmesh.scn differ diff --git a/demos/3d/platformer/coin.scn b/demos/3d/platformer/coin.scn index 449bb0f8958..a4148b40607 100644 Binary files a/demos/3d/platformer/coin.scn and b/demos/3d/platformer/coin.scn differ diff --git a/demos/3d/platformer/enemy.gd b/demos/3d/platformer/enemy.gd index 1d0e0315d92..cbbb2fe725c 100644 --- a/demos/3d/platformer/enemy.gd +++ b/demos/3d/platformer/enemy.gd @@ -45,7 +45,7 @@ func _integrate_forces(state): state.set_angular_velocity( -dp.cross(up).normalized() *33.0) get_node("AnimationPlayer").play("impact") get_node("AnimationPlayer").queue("explode") - set_friction(true) + set_friction(1) cc.disabled=true get_node("sound").play("hit") return diff --git a/demos/3d/platformer/enemy.scn b/demos/3d/platformer/enemy.scn index b3f69af600a..06d725061d6 100644 Binary files a/demos/3d/platformer/enemy.scn and b/demos/3d/platformer/enemy.scn differ diff --git a/demos/3d/shader_materials/shader_materials.scn b/demos/3d/shader_materials/shader_materials.scn index d6a3efe73f7..243c6c8f06b 100644 Binary files a/demos/3d/shader_materials/shader_materials.scn and b/demos/3d/shader_materials/shader_materials.scn differ diff --git a/demos/3d/truck_town/engine.cfg b/demos/3d/truck_town/engine.cfg index f47c0de4fa8..3c340e6dcd2 100644 --- a/demos/3d/truck_town/engine.cfg +++ b/demos/3d/truck_town/engine.cfg @@ -1,5 +1,6 @@ [application] +name="Truck Town" main_scene="res://car_select.scn" [display] diff --git a/demos/gui/rich_text_bbcode/engine.cfg b/demos/gui/rich_text_bbcode/engine.cfg index 5fb2587d91a..e0ea296f6d9 100644 --- a/demos/gui/rich_text_bbcode/engine.cfg +++ b/demos/gui/rich_text_bbcode/engine.cfg @@ -1,3 +1,4 @@ [application] +name="Rich Text Label (BBCode)" main_scene="res://rich_text_bbcode.scn" diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index 5eb58176196..1609dda6996 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -1,6 +1,8 @@ extends Control +var mousepos + func _fixed_process(delta): var modetext = "Mode:\n" @@ -31,7 +33,7 @@ func _fixed_process(delta): get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) ) - get_node("Label_MousePosition").set_text(str("Mouse Position:\n", Input.get_mouse_pos() ) ) + get_node("Label_MousePosition").set_text(str("Mouse Position:\n", mousepos ) ) get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) ) @@ -126,6 +128,12 @@ func check_wm_api(): func _ready(): if( check_wm_api() ): set_fixed_process(true) + set_process_input(true) + + +func _input(ev): + if (ev.type==InputEvent.MOUSE_MOTION): + mousepos = ev.pos func _on_Button_MoveTo_pressed(): diff --git a/demos/misc/window_management/engine.cfg b/demos/misc/window_management/engine.cfg index c53bd45fb73..0a342316739 100644 --- a/demos/misc/window_management/engine.cfg +++ b/demos/misc/window_management/engine.cfg @@ -1,6 +1,6 @@ [application] -name="window_management" +name="Window Management" main_scene="res://window_management.scn" icon="icon.png" diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index c7d6260df62..8db43b6638b 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 905e9991257..901bfa1253a 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -19442,7 +19442,7 @@ - + @@ -19450,7 +19450,7 @@ - + diff --git a/drivers/SCsub b/drivers/SCsub index a1a2191cbc2..6ab09736252 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -1,91 +1,94 @@ -Import('env') - -env.drivers_sources=[] -#env.add_source_files(env.drivers_sources,"*.cpp") -env.Append(CPPPATH=["vorbis"]) -Export('env') - -SConscript('unix/SCsub'); -SConscript('alsa/SCsub'); -SConscript('pulseaudio/SCsub'); -SConscript('windows/SCsub'); -SConscript('gles2/SCsub'); -SConscript('gl_context/SCsub'); -SConscript('openssl/SCsub'); - -if (env["png"]=="yes"): - SConscript("png/SCsub"); -if (env["jpg"]=="yes"): - SConscript("jpg/SCsub"); -if (env["webp"]=="yes"): - SConscript("webp/SCsub"); -SConscript("dds/SCsub"); -SConscript("pvr/SCsub"); -SConscript("etc1/SCsub") -if (env["builtin_zlib"]=="yes"): - SConscript("builtin_zlib/SCsub"); -if (env["openssl"]=="builtin"): - SConscript("builtin_openssl2/SCsub"); - -SConscript("rtaudio/SCsub"); -SConscript("nedmalloc/SCsub"); -SConscript("trex/SCsub"); -SConscript("chibi/SCsub"); -if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"): - SConscript("ogg/SCsub"); -if (env["vorbis"]=="yes"): - SConscript("vorbis/SCsub"); -if (env["tools"]=="yes"): - SConscript("convex_decomp/SCsub"); - -if env["theora"]=="yes": - SConscript("theoraplayer/SCsub") -if (env["theora"]=="yes"): - SConscript("theora/SCsub"); -if (env['speex']=='yes'): - SConscript("speex/SCsub"); -if (env['musepack']=='yes'): - SConscript("mpc/SCsub"); -if (env["squish"]=="yes" and env["tools"]=="yes"): - SConscript("squish/SCsub"); - -num = 0 -cur_base = "" -total = len(env.drivers_sources) -max_src = 64 -list = [] -lib_list = [] - -import string - -for f in env.drivers_sources: - fname = "" - if type(f) == type(""): - fname = env.File(f).path - else: - fname = env.File(f)[0].path - #base = string.join(fname.split("/")[:-1], "/") - fname = fname.replace("\\", "/") - base = string.join(fname.split("/")[:2], "/") - if base != cur_base and len(list) > max_src: - lib = env.Library("drivers"+str(num), list) - lib_list.append(lib) - list = [] - num = num+1 - cur_base = base - list.append(f) - -if len(list) > 0: - lib = env.Library("drivers"+str(num), list) - lib_list.append(lib) - - -drivers_base=[] -env.add_source_files(drivers_base,"*.cpp") -lib_list.insert(0, env.Library("drivers", drivers_base)) - -env.Prepend(LIBS=lib_list) - -#lib = env.Library("drivers",env.drivers_sources) -#env.Prepend(LIBS=[lib]) - +Import('env') + +env.drivers_sources=[] +#env.add_source_files(env.drivers_sources,"*.cpp") +env.Append(CPPPATH=["vorbis"]) +Export('env') + +SConscript('unix/SCsub'); +SConscript('alsa/SCsub'); +SConscript('pulseaudio/SCsub'); +SConscript('windows/SCsub'); +SConscript('gles2/SCsub'); +SConscript('gl_context/SCsub'); +SConscript('openssl/SCsub'); + +if (env["png"]=="yes"): + SConscript("png/SCsub"); +if (env["jpg"]=="yes"): + SConscript("jpg/SCsub"); +if (env["webp"]=="yes"): + SConscript("webp/SCsub"); +SConscript("dds/SCsub"); +SConscript("pvr/SCsub"); +SConscript("etc1/SCsub") +if (env["builtin_zlib"]=="yes"): + SConscript("builtin_zlib/SCsub"); +if (env["openssl"]=="builtin"): + SConscript("builtin_openssl2/SCsub"); + +SConscript("rtaudio/SCsub"); +SConscript("nedmalloc/SCsub"); +SConscript("trex/SCsub"); +SConscript("chibi/SCsub"); +if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"): + SConscript("ogg/SCsub"); +if (env["vorbis"]=="yes"): + SConscript("vorbis/SCsub"); +if (env["tools"]=="yes"): + SConscript("convex_decomp/SCsub"); + +if env["theora"]=="yes": + SConscript("theoraplayer/SCsub") +if (env["theora"]=="yes"): + SConscript("theora/SCsub"); +if (env['speex']=='yes'): + SConscript("speex/SCsub"); +if (env['musepack']=='yes'): + SConscript("mpc/SCsub"); +if (env["squish"]=="yes" and env["tools"]=="yes"): + SConscript("squish/SCsub"); + +num = 0 +cur_base = "" +total = len(env.drivers_sources) +max_src = 64 +list = [] +lib_list = [] + +import string + +if env['vsproj']=="yes": + env.AddToVSProject(env.drivers_sources) + +for f in env.drivers_sources: + fname = "" + if type(f) == type(""): + fname = env.File(f).path + else: + fname = env.File(f)[0].path + #base = string.join(fname.split("/")[:-1], "/") + fname = fname.replace("\\", "/") + base = string.join(fname.split("/")[:2], "/") + if base != cur_base and len(list) > max_src: + lib = env.Library("drivers"+str(num), list) + lib_list.append(lib) + list = [] + num = num+1 + cur_base = base + list.append(f) + +if len(list) > 0: + lib = env.Library("drivers"+str(num), list) + lib_list.append(lib) + + +drivers_base=[] +env.add_source_files(drivers_base,"*.cpp") +lib_list.insert(0, env.Library("drivers", drivers_base)) + +env.Prepend(LIBS=lib_list) + +#lib = env.Library("drivers",env.drivers_sources) +#env.Prepend(LIBS=[lib]) + diff --git a/drivers/chibi/cp_player_data_control.cpp b/drivers/chibi/cp_player_data_control.cpp index 4d30c1a7038..d5ca648fff5 100644 --- a/drivers/chibi/cp_player_data_control.cpp +++ b/drivers/chibi/cp_player_data_control.cpp @@ -233,7 +233,7 @@ int CPPlayer::get_channel_voice(int p_channel) { const char* CPPlayer::get_voice_sample_name(int p_voice) { - const char *name; + const char *name = NULL; @@ -302,7 +302,7 @@ const char * CPPlayer::get_voice_instrument_name(int p_voice) { - const char *name; + const char *name = NULL; diff --git a/drivers/convex_decomp/b2Polygon.cpp b/drivers/convex_decomp/b2Polygon.cpp index 49a3e74c2aa..668313967e6 100644 --- a/drivers/convex_decomp/b2Polygon.cpp +++ b/drivers/convex_decomp/b2Polygon.cpp @@ -970,6 +970,7 @@ int32 DecomposeConvex(b2Polygon* p, b2Polygon* results, int32 maxPolys) { } if (nTri < 1) { //Still no luck? Oh well... + delete[] triangulated; return -1; } int32 nPolys = PolygonizeTriangles(triangulated, nTri, results, maxPolys); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 10da30acca7..157f2e398b5 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -431,6 +431,42 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a // code="get_texpos(gl_ProjectionMatrixInverse * texture2D( depth_texture, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy,vec2(0.0),vec2(1.0))*gl_LightSource[5].specular.zw+gl_LightSource[5].specular.xy)"; //code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb"; break; + } else if (custom_h && callfunc=="cosh_custom") { + + if (!cosh_used) { + global_code= "float cosh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float cosH = (tmp + 1.0 / tmp) / 2.0;\n"\ + " return cosH;\n"\ + "}\n"+global_code; + cosh_used=true; + } + code="cosh_custom("+dump_node_code(onode->arguments[1],p_level)+""; + } else if (custom_h && callfunc=="sinh_custom") { + + if (!sinh_used) { + global_code= "float sinh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float sinH = (tmp - 1.0 / tmp) / 2.0;\n"\ + " return sinH;\n"\ + "}\n"+global_code; + sinh_used=true; + } + code="sinh_custom("+dump_node_code(onode->arguments[1],p_level)+""; + } else if (custom_h && callfunc=="tanh_custom") { + + if (!tanh_used) { + global_code= "float tanh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float tanH = (tmp - 1.0 / tmp) / (tmp + 1.0 / tmp);\n"\ + " return tanH;\n"\ + "}\n"+global_code; + tanh_used=true; + } + code="tanh_custom("+dump_node_code(onode->arguments[1],p_level)+""; } else { @@ -634,6 +670,9 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.use_var2_interp=false; r_flags.uses_normalmap=false; r_flags.uses_normal=false; + sinh_used=false; + tanh_used=false; + cosh_used=false; String error; int errline,errcol; @@ -662,12 +701,18 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.uses_shadow_color=uses_shadow_color; r_code_line=code; r_globals_line=global_code; - return OK; } ShaderCompilerGLES2::ShaderCompilerGLES2() { +#ifdef GLEW_ENABLED + //use custom functions because they are not supported in GLSL120 + custom_h=true; +#else + custom_h=false; +#endif + replace_table["bool"]= "bool"; replace_table["float" ]= "float"; replace_table["vec2" ]= "vec2"; @@ -686,9 +731,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { replace_table["acos" ]= "acos"; replace_table["atan" ]= "atan"; replace_table["atan2"]= "atan"; - replace_table["sinh" ]= "sinh"; - replace_table["cosh" ]= "cosh"; - replace_table["tanh" ]= "tanh"; + + if (custom_h) { + replace_table["sinh" ]= "sinh_custom"; + replace_table["cosh" ]= "cosh_custom"; + replace_table["tanh" ]= "tanh_custom"; + } else { + replace_table["sinh" ]= "sinh"; + replace_table["cosh" ]= "cosh"; + replace_table["tanh" ]= "tanh"; + } + replace_table["pow" ]= "pow"; replace_table["exp" ]= "exp"; replace_table["log" ]= "log"; diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index 6dfc213994f..43902a75367 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -56,6 +56,13 @@ private: bool uses_worldvec; bool vertex_code_writes_vertex; bool uses_shadow_color; + + bool sinh_used; + bool tanh_used; + bool cosh_used; + + bool custom_h; + Flags *flags; StringName vname_discard; diff --git a/drivers/mpc/mpc_reader.c b/drivers/mpc/mpc_reader.c index e1d151fe502..550c5ecb542 100644 --- a/drivers/mpc/mpc_reader.c +++ b/drivers/mpc/mpc_reader.c @@ -36,6 +36,7 @@ #include #include "internal.h" #include +#include // memset() #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... typedef struct mpc_reader_stdio_t { diff --git a/drivers/pvr/ColorRgba.h b/drivers/pvr/ColorRgba.h index 6b46d65e3c9..07014205662 100644 --- a/drivers/pvr/ColorRgba.h +++ b/drivers/pvr/ColorRgba.h @@ -11,21 +11,21 @@ public: ColorRgb() - : r(0) + : b(0) , g(0) - , b(0) { + , r(0) { } ColorRgb(T red, T green, T blue) - : r(red) + : b(blue) , g(green) - , b(blue) { + , r(red) { } ColorRgb(const ColorRgb &x) - : r(x.r) + : b(x.b) , g(x.g) - , b(x.b) { + , r(x.r) { } ColorRgb operator *(int x) { diff --git a/drivers/rtaudio/RtAudio.cpp b/drivers/rtaudio/RtAudio.cpp index 04e7b4422e7..8876f72e21d 100644 --- a/drivers/rtaudio/RtAudio.cpp +++ b/drivers/rtaudio/RtAudio.cpp @@ -46,6 +46,7 @@ #include #include #include +#include // Static variable definitions. const unsigned int RtApi::MAX_SAMPLE_RATES = 14; @@ -63,6 +64,22 @@ const unsigned int RtApi::SAMPLE_RATES[] = { #define MUTEX_DESTROY(A) DeleteCriticalSection(A) #define MUTEX_LOCK(A) EnterCriticalSection(A) #define MUTEX_UNLOCK(A) LeaveCriticalSection(A) + + #include "tchar.h" + + static std::string convertCharPointerToStdString(const char *text) + { + return std::string(text); + } + + static std::string convertCharPointerToStdString(const wchar_t *text) + { + int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL); + std::string s( length-1, '\0' ); + WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL); + return s; + } + #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) // pthread API #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) @@ -184,7 +201,7 @@ RtAudio :: RtAudio( RtAudio::Api api ) getCompiledApi( apis ); for ( unsigned int i=0; igetDeviceCount() ) break; + if ( rtapi_ && rtapi_->getDeviceCount() ) break; } if ( rtapi_ ) return; @@ -766,9 +783,14 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device ) bool haveValueRange = false; info.sampleRates.clear(); for ( UInt32 i=0; i info.preferredSampleRate ) ) + info.preferredSampleRate = tmpSr; + + } else { haveValueRange = true; if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum; if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum; @@ -777,8 +799,12 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device ) if ( haveValueRange ) { for ( unsigned int k=0; k= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) + if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) { info.sampleRates.push_back( SAMPLE_RATES[k] ); + + if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) ) + info.preferredSampleRate = SAMPLE_RATES[k]; + } } } @@ -1385,6 +1411,18 @@ void RtApiCore :: closeStream( void ) CoreHandle *handle = (CoreHandle *) stream_.apiHandle; if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + if (handle) { + AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster }; + + property.mSelector = kAudioDeviceProcessorOverload; + property.mScope = kAudioObjectPropertyScopeGlobal; + if (AudioObjectRemovePropertyListener( handle->id[0], &property, xrunListener, (void *) handle ) != noErr) { + errorText_ = "RtApiCore::closeStream(): error removing property listener!"; + error( RtAudioError::WARNING ); + } + } if ( stream_.state == STREAM_RUNNING ) AudioDeviceStop( handle->id[0], callbackHandler ); #if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) @@ -1396,6 +1434,18 @@ void RtApiCore :: closeStream( void ) } if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) { + if (handle) { + AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster }; + + property.mSelector = kAudioDeviceProcessorOverload; + property.mScope = kAudioObjectPropertyScopeGlobal; + if (AudioObjectRemovePropertyListener( handle->id[1], &property, xrunListener, (void *) handle ) != noErr) { + errorText_ = "RtApiCore::closeStream(): error removing property listener!"; + error( RtAudioError::WARNING ); + } + } if ( stream_.state == STREAM_RUNNING ) AudioDeviceStop( handle->id[1], callbackHandler ); #if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) @@ -1989,7 +2039,9 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device ) // Get the current jack server sample rate. info.sampleRates.clear(); - info.sampleRates.push_back( jack_get_sample_rate( client ) ); + + info.preferredSampleRate = jack_get_sample_rate( client ); + info.sampleRates.push_back( info.preferredSampleRate ); // Count the available ports containing the client name as device // channels. Jack "input ports" equal RtAudio output channels. @@ -2769,8 +2821,12 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device ) info.sampleRates.clear(); for ( unsigned int i=0; i info.preferredSampleRate ) ) + info.preferredSampleRate = SAMPLE_RATES[i]; + } } // Determine supported data types ... just check first channel and assume rest are the same. @@ -2829,9 +2885,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ) -{ +{//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bool isDuplexInput = mode == INPUT && stream_.mode == OUTPUT; + // For ASIO, a duplex stream MUST use the same driver. - if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] != device ) { + if ( isDuplexInput && stream_.device[0] != device ) { errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!"; return FAILURE; } @@ -2845,7 +2904,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne } // Only load the driver once for duplex stream. - if ( mode != INPUT || stream_.mode != OUTPUT ) { + if ( !isDuplexInput ) { // The getDeviceInfo() function will not work when a stream is open // because ASIO does not allow multiple devices to run at the same // time. Thus, we'll probe the system before opening a stream and @@ -2866,22 +2925,26 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne } } + // keep them before any "goto error", they are used for error cleanup + goto device boundary checks + bool buffersAllocated = false; + AsioHandle *handle = (AsioHandle *) stream_.apiHandle; + unsigned int nChannels; + + // Check the device channel count. long inputChannels, outputChannels; result = ASIOGetChannels( &inputChannels, &outputChannels ); if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ")."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) || ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ")."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } stream_.nDeviceChannels[mode] = channels; stream_.nUserChannels[mode] = channels; @@ -2890,30 +2953,27 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne // Verify the sample rate is supported. result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate ); if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ")."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } // Get the current sample rate ASIOSampleRate currentRate; result = ASIOGetSampleRate( ¤tRate ); if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } // Set the sample rate only if necessary if ( currentRate != sampleRate ) { result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate ); if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } } @@ -2924,10 +2984,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne else channelInfo.isInput = true; result = ASIOGetChannelInfo( &channelInfo ); if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } // Assuming WINDOWS host is always little-endian. @@ -2956,10 +3015,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne } if ( stream_.deviceFormat[mode] == 0 ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } // Set the buffer size. For a duplex stream, this will end up @@ -2968,49 +3026,63 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne long minSize, maxSize, preferSize, granularity; result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity ); if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size."; errorText_ = errorStream_.str(); - return FAILURE; + goto error; } - if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; - else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; - else if ( granularity == -1 ) { - // Make sure bufferSize is a power of two. - int log2_of_min_size = 0; - int log2_of_max_size = 0; + if ( isDuplexInput ) { + // When this is the duplex input (output was opened before), then we have to use the same + // buffersize as the output, because it might use the preferred buffer size, which most + // likely wasn't passed as input to this. The buffer sizes have to be identically anyway, + // So instead of throwing an error, make them equal. The caller uses the reference + // to the "bufferSize" param as usual to set up processing buffers. - for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) { - if ( minSize & ((long)1 << i) ) log2_of_min_size = i; - if ( maxSize & ((long)1 << i) ) log2_of_max_size = i; - } + *bufferSize = stream_.bufferSize; - long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) ); - int min_delta_num = log2_of_min_size; - - for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) { - long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) ); - if (current_delta < min_delta) { - min_delta = current_delta; - min_delta_num = i; - } - } - - *bufferSize = ( (unsigned int)1 << min_delta_num ); - if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; + } else { + if ( *bufferSize == 0 ) *bufferSize = preferSize; + else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; - } - else if ( granularity != 0 ) { - // Set to an even multiple of granularity, rounding up. - *bufferSize = (*bufferSize + granularity-1) / granularity * granularity; + else if ( granularity == -1 ) { + // Make sure bufferSize is a power of two. + int log2_of_min_size = 0; + int log2_of_max_size = 0; + + for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) { + if ( minSize & ((long)1 << i) ) log2_of_min_size = i; + if ( maxSize & ((long)1 << i) ) log2_of_max_size = i; + } + + long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) ); + int min_delta_num = log2_of_min_size; + + for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) { + long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) ); + if (current_delta < min_delta) { + min_delta = current_delta; + min_delta_num = i; + } + } + + *bufferSize = ( (unsigned int)1 << min_delta_num ); + if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; + else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; + } + else if ( granularity != 0 ) { + // Set to an even multiple of granularity, rounding up. + *bufferSize = (*bufferSize + granularity-1) / granularity * granularity; + } } - if ( mode == INPUT && stream_.mode == OUTPUT && stream_.bufferSize != *bufferSize ) { - drivers.removeCurrentDriver(); + /* + // we don't use it anymore, see above! + // Just left it here for the case... + if ( isDuplexInput && stream_.bufferSize != *bufferSize ) { errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!"; - return FAILURE; + goto error; } + */ stream_.bufferSize = *bufferSize; stream_.nBuffers = 2; @@ -3022,16 +3094,13 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne stream_.deviceInterleaved[mode] = false; // Allocate, if necessary, our AsioHandle structure for the stream. - AsioHandle *handle = (AsioHandle *) stream_.apiHandle; if ( handle == 0 ) { try { handle = new AsioHandle; } catch ( std::bad_alloc& ) { - //if ( handle == NULL ) { - drivers.removeCurrentDriver(); errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory."; - return FAILURE; + goto error; } handle->bufferInfos = 0; @@ -3046,15 +3115,14 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne // Create the ASIO internal buffers. Since RtAudio sets up input // and output separately, we'll have to dispose of previously // created output buffers for a duplex stream. - long inputLatency, outputLatency; if ( mode == INPUT && stream_.mode == OUTPUT ) { ASIODisposeBuffers(); if ( handle->bufferInfos ) free( handle->bufferInfos ); } // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure. - bool buffersAllocated = false; - unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; + unsigned int i; + nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) ); if ( handle->bufferInfos == NULL ) { errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ")."; @@ -3075,18 +3143,37 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne infos->buffers[0] = infos->buffers[1] = 0; } + // prepare for callbacks + stream_.sampleRate = sampleRate; + stream_.device[mode] = device; + stream_.mode = isDuplexInput ? DUPLEX : mode; + + // store this class instance before registering callbacks, that are going to use it + asioCallbackInfo = &stream_.callbackInfo; + stream_.callbackInfo.object = (void *) this; + // Set up the ASIO callback structure and create the ASIO data buffers. asioCallbacks.bufferSwitch = &bufferSwitch; asioCallbacks.sampleRateDidChange = &sampleRateChanged; asioCallbacks.asioMessage = &asioMessages; asioCallbacks.bufferSwitchTimeInfo = NULL; result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks ); + if ( result != ASE_OK ) { + // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges + // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver + // in that case, let's be naïve and try that instead + *bufferSize = preferSize; + stream_.bufferSize = *bufferSize; + result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks ); + } + if ( result != ASE_OK ) { errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers."; errorText_ = errorStream_.str(); goto error; } - buffersAllocated = true; + buffersAllocated = true; + stream_.state = STREAM_STOPPED; // Set flags for buffer conversion. stream_.doConvertBuffer[mode] = false; @@ -3109,11 +3196,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne bool makeBuffer = true; bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( mode == INPUT ) { - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= bytesOut ) makeBuffer = false; - } + if ( isDuplexInput && stream_.deviceBuffer ) { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); + if ( bufferBytes <= bytesOut ) makeBuffer = false; } if ( makeBuffer ) { @@ -3127,18 +3212,8 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne } } - stream_.sampleRate = sampleRate; - stream_.device[mode] = device; - stream_.state = STREAM_STOPPED; - asioCallbackInfo = &stream_.callbackInfo; - stream_.callbackInfo.object = (void *) this; - if ( stream_.mode == OUTPUT && mode == INPUT ) - // We had already set up an output stream. - stream_.mode = DUPLEX; - else - stream_.mode = mode; - // Determine device latencies + long inputLatency, outputLatency; result = ASIOGetLatencies( &inputLatency, &outputLatency ); if ( result != ASE_OK ) { errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency."; @@ -3158,32 +3233,38 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne return SUCCESS; error: - if ( buffersAllocated ) - ASIODisposeBuffers(); - drivers.removeCurrentDriver(); + if ( !isDuplexInput ) { + // the cleanup for error in the duplex input, is done by RtApi::openStream + // So we clean up for single channel only - if ( handle ) { - CloseHandle( handle->condition ); - if ( handle->bufferInfos ) - free( handle->bufferInfos ); - delete handle; - stream_.apiHandle = 0; - } + if ( buffersAllocated ) + ASIODisposeBuffers(); - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; + drivers.removeCurrentDriver(); + + if ( handle ) { + CloseHandle( handle->condition ); + if ( handle->bufferInfos ) + free( handle->bufferInfos ); + + delete handle; + stream_.apiHandle = 0; + } + + + if ( stream_.userBuffer[mode] ) { + free( stream_.userBuffer[mode] ); + stream_.userBuffer[mode] = 0; + } + + if ( stream_.deviceBuffer ) { + free( stream_.deviceBuffer ); + stream_.deviceBuffer = 0; } } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } - return FAILURE; -} +}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RtApiAsio :: closeStream() { @@ -3635,12 +3716,12 @@ public: outIndex_( 0 ) {} ~WasapiBuffer() { - delete buffer_; + free( buffer_ ); } // sets the length of the internal ring buffer void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) { - delete buffer_; + free( buffer_ ); buffer_ = ( char* ) calloc( bufferSize, formatBytes ); @@ -3799,7 +3880,7 @@ void convertBufferWasapi( char* outBuffer, float sampleStep = 1.0f / sampleRatio; float inSampleFraction = 0.0f; - outSampleCount = ( unsigned int ) ( inSampleCount * sampleRatio ); + outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio ); // frame-by-frame, copy each relative input sample into it's corresponding output sample for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) @@ -3945,7 +4026,6 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) RtAudio::DeviceInfo info; unsigned int captureDeviceCount = 0; unsigned int renderDeviceCount = 0; - std::wstring deviceName; std::string defaultDeviceName; bool isCaptureDevice = false; @@ -4048,8 +4128,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) goto Exit; } - deviceName = defaultDeviceNameProp.pwszVal; - defaultDeviceName = std::string( deviceName.begin(), deviceName.end() ); + defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal); // name hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore ); @@ -4066,8 +4145,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) goto Exit; } - deviceName = deviceNameProp.pwszVal; - info.name = std::string( deviceName.begin(), deviceName.end() ); + info.name =convertCharPointerToStdString(deviceNameProp.pwszVal); // is default if ( isCaptureDevice ) { @@ -4110,6 +4188,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) { info.sampleRates.push_back( SAMPLE_RATES[i] ); } + info.preferredSampleRate = deviceFormat->nSamplesPerSec; // native format info.nativeFormats = 0; @@ -5245,14 +5324,11 @@ unsigned int RtApiDs :: getDeviceCount( void ) error( RtAudioError::WARNING ); } - // Clean out any devices that may have disappeared. - std::vector< int > indices; - for ( unsigned int i=0; i(dsDevices.size()); } @@ -5308,8 +5384,12 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device ) info.sampleRates.clear(); for ( unsigned int k=0; k= (unsigned int) outCaps.dwMinSecondarySampleRate && - SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) + SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) { info.sampleRates.push_back( SAMPLE_RATES[k] ); + + if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) ) + info.preferredSampleRate = SAMPLE_RATES[k]; + } } // Get format information. @@ -6264,6 +6344,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6271,6 +6352,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6279,6 +6361,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6286,6 +6369,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6307,6 +6391,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6399,6 +6484,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6412,6 +6498,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6448,6 +6535,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6509,6 +6597,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6523,6 +6612,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6544,6 +6634,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) { errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!"; errorText_ = errorStream_.str(); + MUTEX_UNLOCK( &stream_.mutex ); error( RtAudioError::SYSTEM_ERROR ); return; } @@ -6582,21 +6673,6 @@ static unsigned __stdcall callbackHandler( void *ptr ) return 0; } -#include "tchar.h" - -static std::string convertTChar( LPCTSTR name ) -{ -#if defined( UNICODE ) || defined( _UNICODE ) - int length = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL); - std::string s( length-1, '\0' ); - WideCharToMultiByte(CP_UTF8, 0, name, -1, &s[0], length, NULL, NULL); -#else - std::string s( name ); -#endif - - return s; -} - static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, LPCTSTR description, LPCTSTR /*module*/, @@ -6638,7 +6714,7 @@ static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, } // If good device, then save its name and guid. - std::string name = convertTChar( description ); + std::string name = convertCharPointerToStdString( description ); //if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" ) if ( lpguid == NULL ) name = "Default Device"; @@ -6820,6 +6896,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device ) // Count cards and devices card = -1; + subdevice = -1; snd_card_next( &card ); while ( card >= 0 ) { sprintf( name, "hw:%d", card ); @@ -7033,8 +7110,12 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device ) // Test our discrete set of sample rate values. info.sampleRates.clear(); for ( unsigned int i=0; i info.preferredSampleRate ) ) + info.preferredSampleRate = SAMPLE_RATES[i]; + } } if ( info.sampleRates.size() == 0 ) { snd_pcm_close( phandle ); @@ -7959,6 +8040,8 @@ void RtApiAlsa :: callbackEvent() errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << "."; errorText_ = errorStream_.str(); } + else + errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun."; } else { errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << "."; @@ -8067,6 +8150,7 @@ RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ ) for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) info.sampleRates.push_back( *sr ); + info.preferredSampleRate = 48000; info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32; return info; @@ -8429,7 +8513,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, pah = static_cast( stream_.apiHandle ); int error; - if ( !options->streamName.empty() ) streamName = options->streamName; + if ( options && !options->streamName.empty() ) streamName = options->streamName; switch ( mode ) { case INPUT: pa_buffer_attr buffer_attr; @@ -8635,6 +8719,10 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device ) for ( unsigned int k=0; k info.preferredSampleRate ) ) + info.preferredSampleRate = SAMPLE_RATES[k]; + break; } } @@ -8643,8 +8731,12 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device ) else { // Check min and max rate values; for ( unsigned int k=0; k= (int) SAMPLE_RATES[k] ) + if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] ) { info.sampleRates.push_back( SAMPLE_RATES[k] ); + + if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) ) + info.preferredSampleRate = SAMPLE_RATES[k]; + } } } diff --git a/drivers/rtaudio/RtAudio.h b/drivers/rtaudio/RtAudio.h index 1f1b63072c8..7d45d365297 100644 --- a/drivers/rtaudio/RtAudio.h +++ b/drivers/rtaudio/RtAudio.h @@ -310,12 +310,13 @@ class RtAudio bool isDefaultOutput; /*!< true if this is the default output device. */ bool isDefaultInput; /*!< true if this is the default input device. */ std::vector sampleRates; /*!< Supported sample rates (queried from list of standard rates). */ + unsigned int preferredSampleRate; /*!< Preferred sample rate, eg. for WASAPI the system sample rate. */ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */ // Default constructor. DeviceInfo() :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), - isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {} + isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {} }; //! The structure for specifying input or ouput stream parameters. diff --git a/drivers/theoraplayer/video_stream_theoraplayer.cpp b/drivers/theoraplayer/video_stream_theoraplayer.cpp index ecafda9d845..ef1f5651ab3 100644 --- a/drivers/theoraplayer/video_stream_theoraplayer.cpp +++ b/drivers/theoraplayer/video_stream_theoraplayer.cpp @@ -388,7 +388,7 @@ void VideoStreamTheoraplayer::pop_frame(Ref p_tex) { { DVector::Write wr = data.write(); uint8_t* ptr = wr.ptr(); - memcpy(ptr, f->getBuffer(), imgsize); + copymem(ptr, f->getBuffer(), imgsize); } /* for (int i=0; iadd_pack_source(zip_packed_data); #endif @@ -748,12 +755,12 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas if (file_access_network_client) memdelete(file_access_network_client); - if (packed_data) - memdelete( packed_data ); -#ifdef MINIZIP_ENABLED - if (zip_packed_data) - memdelete( zip_packed_data ); -#endif +// Note 1: *zip_packed_data live into *packed_data +// Note 2: PackedData::~PackedData destroy this. +//#ifdef MINIZIP_ENABLED +// if (zip_packed_data) +// memdelete( zip_packed_data ); +//#endif unregister_core_types(); diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index e0149213647..37ddb2bc411 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -88,6 +88,7 @@ const char *GDFunctions::get_func_name(Function p_func) { "str", "print", "printt", + "prints", "printerr", "printraw", "var2str", @@ -561,6 +562,22 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va r_ret=Variant(); + } break; + case TEXT_PRINT_SPACED: { + + String str; + for(int i=0;ioperator String(); + } + + //str+="\n"; + print_line(str); + r_ret=Variant(); + + } break; case TEXT_PRINTERR: { @@ -1251,6 +1268,13 @@ MethodInfo GDFunctions::get_info(Function p_func) { mi.return_val.type=Variant::NIL; return mi; + } break; + case TEXT_PRINT_SPACED: { + + MethodInfo mi("prints",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::NIL; + return mi; + } break; case TEXT_PRINTERR: { diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h index ecd7d158be0..ad35a628d54 100644 --- a/modules/gdscript/gd_functions.h +++ b/modules/gdscript/gd_functions.h @@ -84,6 +84,7 @@ public: TEXT_STR, TEXT_PRINT, TEXT_PRINT_TABBED, + TEXT_PRINT_SPACED, TEXT_PRINTERR, TEXT_PRINTRAW, VAR_TO_STR, diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index 56b283aa32c..0745baafe64 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -1036,7 +1036,7 @@ void GDTokenizerText::advance(int p_amount) { ////////////////////////////////////////////////////////////////////////////////////////////////////// -#define BYTECODE_VERSION 3 +#define BYTECODE_VERSION 4 Error GDTokenizerBuffer::set_code_buffer(const Vector & p_buffer) { diff --git a/platform/android/android_native_app_glue.h b/platform/android/android_native_app_glue.h index a902a3b4dac..f5ba27ae665 100644 --- a/platform/android/android_native_app_glue.h +++ b/platform/android/android_native_app_glue.h @@ -26,7 +26,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ - * Copyright (C) 2010 The Android Open Source Project +/* Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index d0e2dfbce19..d169ec51d5a 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -225,6 +225,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { static void _device_poll_thread(void *ud); + String get_package_name(); + String get_project_name() const; void _fix_manifest(Vector& p_manifest); void _fix_resources(Vector& p_manifest); @@ -756,7 +758,7 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector& p_manifest) { if (tname=="manifest" && attrname=="package") { print_line("FOUND PACKAGE"); - string_table[attr_value]=package; + string_table[attr_value]=get_package_name(); } //print_line("tname: "+tname); @@ -1169,7 +1171,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d if (apk_expansion) { - String apkfname="main."+itos(version_code)+"."+package+".obb"; + String apkfname="main."+itos(version_code)+"."+get_package_name()+".obb"; String fullpath=p_path.get_base_dir().plus_file(apkfname); FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE); if (!pf) { @@ -1514,7 +1516,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) { args.push_back("-s"); args.push_back(devices[p_device].id); args.push_back("uninstall"); - args.push_back(package); + args.push_back(get_package_name()); err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); #if 0 @@ -1552,7 +1554,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) { args.push_back("-a"); args.push_back("android.intent.action.MAIN"); args.push_back("-n"); - args.push_back(package+"/com.android.godot.Godot"); + args.push_back(get_package_name()+"/com.android.godot.Godot"); err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); if (err || rv!=0) { @@ -1564,12 +1566,37 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) { return OK; } +String EditorExportPlatformAndroid::get_package_name() { + + String pname = package; + String basename = Globals::get_singleton()->get("application/name"); + basename=basename.to_lower(); + + String name; + bool first=true; + for(int i=0;i='0' && c<='9' && first) { + continue; + } + if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9')) { + name+=String::chr(c); + first=false; + } + } + if (name=="") + name="noname"; + + pname=pname.replace("$genname",name); + return pname; + +} EditorExportPlatformAndroid::EditorExportPlatformAndroid() { version_code=1; version_name="1.0"; - package="com.android.noname"; + package="org.godotengine.$genname"; name=""; _signed=true; apk_expansion=false; diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png index 050a1cf930d..78757e90356 100644 Binary files a/platform/android/java/res/drawable/icon.png and b/platform/android/java/res/drawable/icon.png differ diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index dd19dbbff6f..eb2a12cdefa 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -966,8 +966,10 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi [NSApp activateIgnoringOtherApps:YES]; - [window_object makeKeyAndOrderFront:nil]; + [window_object makeKeyAndOrderFront:nil]; + if (p_desired.fullscreen) + zoomed = true; /*** END OSX INITIALIZATION ***/ /*** END OSX INITIALIZATION ***/ @@ -1310,14 +1312,22 @@ void OS_OSX::set_window_size(const Size2 p_size) { void OS_OSX::set_window_fullscreen(bool p_enabled) { - [window_object performZoom:nil]; + if (zoomed != p_enabled) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + [window_object toggleFullScreen:nil]; +#else + [window_object performZoom:nil]; +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + } zoomed = p_enabled; }; bool OS_OSX::is_window_fullscreen() const { +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 if ( [window_object respondsToSelector:@selector(isZoomed)] ) return [window_object isZoomed]; +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ return zoomed; }; @@ -1509,6 +1519,11 @@ void OS_OSX::run() { main_loop->init(); + if (zoomed) { + zoomed = false; + set_window_fullscreen(true); + } + // uint64_t last_ticks=get_ticks_usec(); // int frames=0; diff --git a/platform/windows/SCsub b/platform/windows/SCsub index a77428e9548..1ad32e79897 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -12,3 +12,9 @@ common_win=[ ] env.Program('#bin/godot',['godot_win.cpp']+common_win,PROGSUFFIX=env["PROGSUFFIX"]) + +# Microsoft Visual Studio Project Generation +if (env['vsproj'])=="yes": + env.vs_srcs = env.vs_srcs + ["platform/windows/godot_win.cpp"] + for x in common_win: + env.vs_srcs = env.vs_srcs + ["platform/windows/" + x] diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 9cdf04797c2..298fa3bc789 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -204,7 +204,7 @@ def configure(env): elif (env["target"]=="debug"): - env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED','/DD3D_DEBUG_INFO','/O1']) + env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED','/DD3D_DEBUG_INFO','/Od']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) env.Append(LINKFLAGS=['/DEBUG']) diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp index 0e74f63510a..81c90d9dd0e 100644 --- a/platform/windows/godot_win.cpp +++ b/platform/windows/godot_win.cpp @@ -115,29 +115,24 @@ PCHAR* return argv; } -char* mb_to_utf8(const char* mbs) { - - int wlen = MultiByteToWideChar(CP_ACP,0,mbs,-1,NULL,0); // returns 0 if failed - wchar_t *wbuf = new wchar_t[wlen + 1]; - MultiByteToWideChar(CP_ACP,0,mbs,-1,wbuf,wlen); - wbuf[wlen]=0; - - int ulen = WideCharToMultiByte(CP_UTF8,0,wbuf,-1,NULL,0,NULL,NULL); +char* wc_to_utf8(const wchar_t* wc) { + int ulen = WideCharToMultiByte(CP_UTF8,0,wc,-1,NULL,0,NULL,NULL); char * ubuf = new char[ulen + 1]; - WideCharToMultiByte(CP_UTF8,0,wbuf,-1,ubuf,ulen,NULL,NULL); + WideCharToMultiByte(CP_UTF8,0,wc,-1,ubuf,ulen,NULL,NULL); ubuf[ulen] = 0; return ubuf; } -int main(int argc, char** argv) { +int widechar_main(int argc, wchar_t** argv) { OS_Windows os(NULL); setlocale(LC_CTYPE, ""); char ** argv_utf8 = new char*[argc]; + for(int i=0; i 0 ) { + return wval; + } return ""; -}; +} String OS_Windows::get_stdin_string(bool p_block) { diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 67ec33f3a37..28427fa2f03 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -317,8 +317,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi /* set the name and class hints for the window manager to use */ classHint = XAllocClassHint(); if (classHint) { - classHint->res_name = "Godot"; - classHint->res_class = "Godot"; + classHint->res_name = (char *)"Godot"; + classHint->res_class = (char *)"Godot"; } XSetClassHint(x11_display, x11_window, classHint); XFree(classHint); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index a40b1fb3977..827256c2fa5 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -512,6 +512,29 @@ bool Area2D::overlaps_body(Node* p_body) const{ } +void Area2D::set_collision_mask(uint32_t p_mask) { + + collision_mask=p_mask; + Physics2DServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask); +} + +uint32_t Area2D::get_collision_mask() const { + + return collision_mask; +} + + +void Area2D::set_layer_mask(uint32_t p_mask) { + + layer_mask=p_mask; + Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask); +} + +uint32_t Area2D::get_layer_mask() const { + + return layer_mask; +} + void Area2D::_bind_methods() { @@ -542,6 +565,12 @@ void Area2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_priority); ObjectTypeDB::bind_method(_MD("get_priority"),&Area2D::get_priority); + ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area2D::set_collision_mask); + ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area2D::get_collision_mask); + + ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area2D::set_layer_mask); + ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area2D::get_layer_mask); + ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring); ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled); @@ -578,6 +607,8 @@ void Area2D::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask")); } @@ -593,9 +624,10 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea priority=0; monitoring=false; monitorable=false; + collision_mask=1; + layer_mask=1; set_enable_monitoring(true); set_monitorable(true); - } Area2D::~Area2D() { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 5964230a52f..0c064f54cd7 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -51,6 +51,8 @@ private: bool gravity_is_point; real_t linear_damp; real_t angular_damp; + uint32_t collision_mask; + uint32_t layer_mask; int priority; bool monitoring; bool monitorable; @@ -151,6 +153,12 @@ public: void set_monitorable(bool p_enable); bool is_monitorable() const; + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; + + void set_layer_mask(uint32_t p_mask); + uint32_t get_layer_mask() const; + Array get_overlapping_bodies() const; //function for script Array get_overlapping_areas() const; //function for script diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 27a512845c0..70b88a66117 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -132,8 +132,7 @@ Matrix32 Camera2D::get_camera_transform() { } - Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());; - screen_offset; + Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2()); float angle = get_global_transform().get_rotation(); if(rotating){ diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp index d427bf4bc32..5a02501816e 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation2d.cpp @@ -32,6 +32,7 @@ void Navigation2D::_navpoly_link(int p_id) { p.edges.resize(plen); Vector2 center; + float sum=0; for(int j=0;j=len) { + valid=false; + break; + } + + Vector2 epn = nm.xform.xform(r[idxn]); + + sum+=(epn.x-ep.x)*(epn.y+ep.y); + + } + p.clockwise=sum>0; + if (!valid) { nm.polygons.pop_back(); ERR_CONTINUE(!valid); @@ -493,17 +509,30 @@ Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vect left = _get_vertex(p->edges[prev].point); right = _get_vertex(p->edges[prev_n].point); - if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ + if (p->clockwise) { SWAP(left,right); } + /*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ + SWAP(left,right); + }*/ } bool skip=false; + /* print_line("-----\nAPEX: "+(apex_point-end_point)); + print_line("LEFT:"); + print_line("\tPortal: "+(portal_left-end_point)); + print_line("\tPoint: "+(left-end_point)); + print_line("\tFree: "+itos(CLOCK_TANGENT(apex_point,portal_left,left) >= 0)); + print_line("RIGHT:"); + print_line("\tPortal: "+(portal_right-end_point)); + print_line("\tPoint: "+(right-end_point)); + print_line("\tFree: "+itos(CLOCK_TANGENT(apex_point,portal_right,right) <= 0)); +*/ if (CLOCK_TANGENT(apex_point,portal_left,left) >= 0){ //process - if (portal_left==apex_point || CLOCK_TANGENT(apex_point,left,portal_right) > 0) { + if (portal_left.distance_squared_to(apex_point) 0) { left_poly=p; portal_left=left; } else { @@ -519,12 +548,13 @@ Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vect if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON) path.push_back(apex_point); skip=true; + //print_line("addpoint left"); } } if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){ //process - if (portal_right==apex_point || CLOCK_TANGENT(apex_point,right,portal_left) < 0) { + if (portal_right.distance_squared_to(apex_point) Navigation2D::get_simple_path(const Vector2& p_start, const Vect portal_left=apex_point; if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON) path.push_back(apex_point); + //print_line("addpoint right"); + } } diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h index 7a33105b770..829b0f544b8 100644 --- a/scene/2d/navigation2d.h +++ b/scene/2d/navigation2d.h @@ -60,6 +60,8 @@ class Navigation2D : public Node2D { float distance; int prev_edge; + bool clockwise; + NavMesh *owner; }; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index e7bc1996089..3d2917d8439 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -68,17 +68,34 @@ float PhysicsBody2D::get_one_way_collision_max_depth() const{ } +void PhysicsBody2D::_set_layers(uint32_t p_mask) { + + set_layer_mask(p_mask); + set_collision_mask(p_mask); +} + +uint32_t PhysicsBody2D::_get_layers() const{ + + return get_layer_mask(); +} + void PhysicsBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody2D::set_collision_mask); + ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody2D::get_collision_mask); + ObjectTypeDB::bind_method(_MD("_set_layers","mask"),&PhysicsBody2D::_set_layers); + ObjectTypeDB::bind_method(_MD("_get_layers"),&PhysicsBody2D::_get_layers); ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction); ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction); ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with); ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with); - ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS,"",0),_SCS("_set_layers"),_SCS("_get_layers")); //for backwards compat + ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask")); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction")); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth")); } @@ -94,9 +111,22 @@ uint32_t PhysicsBody2D::get_layer_mask() const { return mask; } +void PhysicsBody2D::set_collision_mask(uint32_t p_mask) { + + collision_mask=p_mask; + Physics2DServer::get_singleton()->body_set_collision_mask(get_rid(),p_mask); +} + +uint32_t PhysicsBody2D::get_collision_mask() const { + + return collision_mask; +} + + PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { mask=1; + collision_mask=1; set_one_way_collision_max_depth(0); set_pickable(false); @@ -909,6 +939,19 @@ Variant KinematicBody2D::_get_collider() const { return obj; } +void KinematicBody2D::revert_motion() { + + Matrix32 gt = get_global_transform(); + gt.elements[2]-=travel; + travel=Vector2(); + set_global_transform(gt); + +} + +Vector2 KinematicBody2D::get_travel() const { + + return travel; +} Vector2 KinematicBody2D::move(const Vector2& p_motion) { @@ -926,6 +969,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { Matrix32 gt = get_global_transform(); gt.elements[2]+=result.motion; set_global_transform(gt); + travel=result.motion; return result.remainder; #else @@ -1157,6 +1201,8 @@ void KinematicBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to); ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move); + ObjectTypeDB::bind_method(_MD("get_travel"),&KinematicBody2D::get_travel); + ObjectTypeDB::bind_method(_MD("revert_motion"),&KinematicBody2D::revert_motion); ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index b8cba6e5ba8..03f95959b67 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -39,8 +39,14 @@ class PhysicsBody2D : public CollisionObject2D { OBJ_TYPE(PhysicsBody2D,CollisionObject2D); uint32_t mask; + uint32_t collision_mask; Vector2 one_way_collision_direction; float one_way_collision_max_depth; + + + void _set_layers(uint32_t p_mask); + uint32_t _get_layers() const; + protected: void _notification(int p_what); @@ -52,6 +58,9 @@ public: void set_layer_mask(uint32_t p_mask); uint32_t get_layer_mask() const; + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; + void add_collision_exception_with(Node* p_node); //must be physicsbody void remove_collision_exception_with(Node* p_node); @@ -276,6 +285,7 @@ class KinematicBody2D : public PhysicsBody2D { ObjectID collider; int collider_shape; Variant collider_metadata; + Vector2 travel; Variant _get_collider() const; @@ -290,6 +300,10 @@ public: bool test_move(const Vector2& p_motion); bool is_colliding() const; + + Vector2 get_travel() const; + void revert_motion(); + Vector2 get_collision_pos() const; Vector2 get_collision_normal() const; Vector2 get_collider_velocity() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index bf1677ae63d..2fca1e67e86 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -519,6 +519,7 @@ Map::Element *TileMap::_create_quadrant(const q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID()); Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); + Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); @@ -790,7 +791,7 @@ Rect2 TileMap::get_item_rect() const { return rect_cache; } -void TileMap::set_collision_layer_mask(uint32_t p_layer) { +void TileMap::set_collision_layer(uint32_t p_layer) { collision_layer=p_layer; for (Map::Element *E=quadrant_map.front();E;E=E->next()) { @@ -800,6 +801,16 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) { } } +void TileMap::set_collision_mask(uint32_t p_mask) { + + collision_mask=p_mask; + for (Map::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask); + } +} + bool TileMap::get_collision_use_kinematic() const{ return use_kinematic; @@ -844,11 +855,16 @@ float TileMap::get_collision_bounce() const{ } -uint32_t TileMap::get_collision_layer_mask() const { +uint32_t TileMap::get_collision_layer() const { return collision_layer; } +uint32_t TileMap::get_collision_mask() const { + + return collision_mask; +} + void TileMap::set_mode(Mode p_mode) { _clear_quadrants(); @@ -1077,8 +1093,11 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic); ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic); - ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); - ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_layer","mask"),&TileMap::set_collision_layer); + ObjectTypeDB::bind_method(_MD("get_collision_layer"),&TileMap::get_collision_layer); + + ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&TileMap::set_collision_mask); + ObjectTypeDB::bind_method(_MD("get_collision_mask"),&TileMap::get_collision_mask); ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); @@ -1117,7 +1136,9 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer"),_SCS("get_collision_layer")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask")); + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); ADD_SIGNAL(MethodInfo("settings_changed")); @@ -1146,6 +1167,7 @@ TileMap::TileMap() { center_x=false; center_y=false; collision_layer=1; + collision_mask=1; friction=1; bounce=0; mode=MODE_SQUARE; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 233529f018b..84ca65da4f6 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -146,6 +146,8 @@ private: float friction; float bounce; uint32_t collision_layer; + uint32_t collision_mask; + TileOrigin tile_origin; void _fix_cell_transform(Matrix32& xform, const Cell& p_cell, const Vector2 &p_offset, const Size2 &p_sc); @@ -207,8 +209,11 @@ public: Rect2 get_item_rect() const; - void set_collision_layer_mask(uint32_t p_layer); - uint32_t get_collision_layer_mask() const; + void set_collision_layer(uint32_t p_layer); + uint32_t get_collision_layer() const; + + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; void set_collision_use_kinematic(bool p_use_kinematic); bool get_collision_use_kinematic() const; diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp index 8866a658012..48820706dd2 100644 --- a/scene/3d/navigation.cpp +++ b/scene/3d/navigation.cpp @@ -30,6 +30,7 @@ void Navigation::_navmesh_link(int p_id) { p.edges.resize(plen); Vector3 center; + float sum=0; for(int j=0;j=2) { + Vector3 epa = nm.xform.xform(r[indices[j-2]]); + Vector3 epb = nm.xform.xform(r[indices[j-1]]); + + sum+=up.dot((epb-epa).cross(ep-epa)); + + } + } + p.clockwise=sum>0; + if (!valid) { nm.polygons.pop_back(); ERR_CONTINUE(!valid); @@ -399,7 +411,8 @@ Vector Navigation::get_simple_path(const Vector3& p_start, const Vector left = _get_vertex(p->edges[prev].point); right = _get_vertex(p->edges[prev_n].point); - if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){ + //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){ + if (p->clockwise) { SWAP(left,right); } } diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index 54cec8f1f71..0f7f67571f1 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -59,6 +59,8 @@ class Navigation : public Spatial { float distance; int prev_edge; + bool clockwise; + NavMesh *owner; }; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 35f6523c6af..4952f742df6 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -292,7 +292,7 @@ SpriteBase3D::SpriteBase3D() { parent_sprite=NULL; pI=NULL; - for(int i=0;i<4;i++) + for(int i=0;iget(); + + cmd.key = p_key; + int& count = cmd.args; + if(p_arg10.get_type() != Variant::NIL) + count = 10; + else if(p_arg9.get_type() != Variant::NIL) + count = 9; + else if(p_arg8.get_type() != Variant::NIL) + count = 8; + else if(p_arg7.get_type() != Variant::NIL) + count = 7; + else if(p_arg6.get_type() != Variant::NIL) + count = 6; + else if(p_arg5.get_type() != Variant::NIL) + count = 5; + else if(p_arg4.get_type() != Variant::NIL) + count = 4; + else if(p_arg3.get_type() != Variant::NIL) + count = 3; + else if(p_arg2.get_type() != Variant::NIL) + count = 2; + else if(p_arg1.get_type() != Variant::NIL) + count = 1; + if(count > 0) + cmd.arg[0] = p_arg1; + if(count > 1) + cmd.arg[1] = p_arg2; + if(count > 2) + cmd.arg[2] = p_arg3; + if(count > 3) + cmd.arg[3] = p_arg4; + if(count > 4) + cmd.arg[4] = p_arg5; + if(count > 5) + cmd.arg[5] = p_arg6; + if(count > 6) + cmd.arg[6] = p_arg7; + if(count > 7) + cmd.arg[7] = p_arg8; + if(count > 8) + cmd.arg[8] = p_arg9; + if(count > 9) + cmd.arg[9] = p_arg10; +} + +void Tween::_process_pending_commands() { + + for(List::Element *E=pending_commands.front();E;E=E->next()) { + + PendingCommand& cmd = E->get(); + Variant::CallError err; + Variant *arg[10] = { + &cmd.arg[0], + &cmd.arg[1], + &cmd.arg[2], + &cmd.arg[3], + &cmd.arg[4], + &cmd.arg[5], + &cmd.arg[6], + &cmd.arg[7], + &cmd.arg[8], + &cmd.arg[9], + }; + this->call(cmd.key, (const Variant **) arg, cmd.args, err); + } + pending_commands.clear(); +} + bool Tween::_set(const StringName& p_name, const Variant& p_value) { String name=p_name; @@ -456,6 +531,8 @@ bool Tween::_apply_tween_value(InterpolateData& p_data, Variant& value) { void Tween::_tween_process(float p_delta) { + _process_pending_commands(); + if (speed_scale == 0) return; p_delta *= speed_scale; @@ -551,8 +628,12 @@ void Tween::_tween_process(float p_delta) { _apply_tween_value(data, result); - if(data.finish) + if (data.finish) { emit_signal("tween_complete",object,data.key); + // not repeat mode, remove completed action + if (!repeat) + call_deferred("remove", object, data.key); + } } pending_update --; } @@ -734,7 +815,10 @@ bool Tween::resume_all() { bool Tween::remove(Object *p_object, String p_key) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + call_deferred("remove", p_object, p_key); + return true; + } for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); @@ -751,7 +835,10 @@ bool Tween::remove(Object *p_object, String p_key) { bool Tween::remove_all() { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + call_deferred("remove_all"); + return true; + } set_active(false); _set_process(false); interpolates.clear(); @@ -940,7 +1027,19 @@ bool Tween::interpolate_property(Object *p_object , EaseType p_ease_type , real_t p_delay ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("interpolate_property" + , p_object + , p_property + , p_initial_val + , p_final_val + , p_times_in_sec + , p_trans_type + , p_ease_type + , p_delay + ); + return true; + } // convert INT to REAL is better for interpolaters if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); @@ -987,7 +1086,19 @@ bool Tween::interpolate_method(Object *p_object , EaseType p_ease_type , real_t p_delay ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("interpolate_method" + , p_object + , p_method + , p_initial_val + , p_final_val + , p_times_in_sec + , p_trans_type + , p_ease_type + , p_delay + ); + return true; + } // convert INT to REAL is better for interpolaters if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); @@ -999,6 +1110,7 @@ bool Tween::interpolate_method(Object *p_object ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); ERR_FAIL_COND_V(p_delay < 0, false); + ERR_EXPLAIN("Object has no method named: %s" + p_method); ERR_FAIL_COND_V(!p_object->has_method(p_method), false); InterpolateData data; @@ -1029,10 +1141,23 @@ bool Tween::interpolate_callback(Object *p_object , VARIANT_ARG_DECLARE ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("interpolate_callback" + , p_object + , p_times_in_sec + , p_callback + , p_arg1 + , p_arg2 + , p_arg3 + , p_arg4 + , p_arg5 + ); + return true; + } ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_times_in_sec < 0, false); + ERR_EXPLAIN("Object has no callback named: %s" + p_callback); ERR_FAIL_COND_V(!p_object->has_method(p_callback), false); InterpolateData data; @@ -1080,10 +1205,23 @@ bool Tween::interpolate_deferred_callback(Object *p_object , VARIANT_ARG_DECLARE ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("interpolate_deferred_callback" + , p_object + , p_times_in_sec + , p_callback + , p_arg1 + , p_arg2 + , p_arg3 + , p_arg4 + , p_arg5 + ); + return true; + } ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_times_in_sec < 0, false); + ERR_EXPLAIN("Object has no callback named: %s" + p_callback); ERR_FAIL_COND_V(!p_object->has_method(p_callback), false); InterpolateData data; @@ -1135,7 +1273,20 @@ bool Tween::follow_property(Object *p_object , EaseType p_ease_type , real_t p_delay ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("follow_property" + , p_object + , p_property + , p_initial_val + , p_target + , p_target_property + , p_times_in_sec + , p_trans_type + , p_ease_type + , p_delay + ); + return true; + } // convert INT to REAL is better for interpolaters if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); @@ -1188,7 +1339,20 @@ bool Tween::follow_method(Object *p_object , EaseType p_ease_type , real_t p_delay ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("follow_method" + , p_object + , p_method + , p_initial_val + , p_target + , p_target_method + , p_times_in_sec + , p_trans_type + , p_ease_type + , p_delay + ); + return true; + } // convert INT to REAL is better for interpolaters if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); @@ -1199,7 +1363,9 @@ bool Tween::follow_method(Object *p_object ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); ERR_FAIL_COND_V(p_delay < 0, false); + ERR_EXPLAIN("Object has no method named: %s" + p_method); ERR_FAIL_COND_V(!p_object->has_method(p_method), false); + ERR_EXPLAIN("Target has no method named: %s" + p_target_method); ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false); Variant::CallError error; @@ -1240,7 +1406,20 @@ bool Tween::targeting_property(Object *p_object , EaseType p_ease_type , real_t p_delay ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("targeting_property" + , p_object + , p_property + , p_initial + , p_initial_property + , p_final_val + , p_times_in_sec + , p_trans_type + , p_ease_type + , p_delay + ); + return true; + } // convert INT to REAL is better for interpolaters if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); @@ -1298,7 +1477,20 @@ bool Tween::targeting_method(Object *p_object , EaseType p_ease_type , real_t p_delay ) { - ERR_FAIL_COND_V(pending_update != 0, false); + if(pending_update != 0) { + _add_pending_command("targeting_method" + , p_object + , p_method + , p_initial + , p_initial_method + , p_final_val + , p_times_in_sec + , p_trans_type + , p_ease_type + , p_delay + ); + return true; + } // convert INT to REAL is better for interpolaters if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); @@ -1309,7 +1501,9 @@ bool Tween::targeting_method(Object *p_object ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); ERR_FAIL_COND_V(p_delay < 0, false); + ERR_EXPLAIN("Object has no method named: %s" + p_method); ERR_FAIL_COND_V(!p_object->has_method(p_method), false); + ERR_EXPLAIN("Initial Object has no method named: %s" + p_initial_method); ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false); Variant::CallError error; diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 76402bcd730..d504c63d8a1 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -110,6 +110,27 @@ private: List interpolates; + struct PendingCommand { + StringName key; + int args; + Variant arg[10]; + }; + List pending_commands; + + void _add_pending_command(StringName p_key + ,const Variant& p_arg1=Variant() + ,const Variant& p_arg2=Variant() + ,const Variant& p_arg3=Variant() + ,const Variant& p_arg4=Variant() + ,const Variant& p_arg5=Variant() + ,const Variant& p_arg6=Variant() + ,const Variant& p_arg7=Variant() + ,const Variant& p_arg8=Variant() + ,const Variant& p_arg9=Variant() + ,const Variant& p_arg10=Variant() + ); + void _process_pending_commands(); + typedef real_t (*interpolater)(real_t t, real_t b, real_t c, real_t d); static interpolater interpolaters[TRANS_COUNT][EASE_COUNT]; diff --git a/scene/animation/tween_interpolaters.cpp b/scene/animation/tween_interpolaters.cpp index c052d752f84..9128d220def 100644 --- a/scene/animation/tween_interpolaters.cpp +++ b/scene/animation/tween_interpolaters.cpp @@ -285,18 +285,18 @@ namespace cubic { namespace circ { static real_t in(real_t t, real_t b, real_t c, real_t d) { - return -c * (sqrt(1 - (t /= d) * t) - 1) + b; + return -c * (sqrt(1 - (t /= d) * t) - 1) + b; // TODO: ehrich: operation with t is undefined } static real_t out(real_t t, real_t b, real_t c, real_t d) { - return c * sqrt(1 - (t = t / d - 1) * t) + b; + return c * sqrt(1 - (t = t / d - 1) * t) + b; // TODO: ehrich: operation with t is undefined } static real_t in_out(real_t t, real_t b, real_t c, real_t d) { if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b; - return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; + return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; // TODO: ehrich: operation with t is undefined } static real_t out_in(real_t t, real_t b, real_t c, real_t d) @@ -364,15 +364,15 @@ namespace back { static real_t out(real_t t, real_t b, real_t c, real_t d) { float s = 1.70158f; - return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; + return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; // TODO: ehrich: operation with t is undefined } static real_t in_out(real_t t, real_t b, real_t c, real_t d) { float s = 1.70158f; - if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; + if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; // TODO: ehrich: operation with s is undefined float postFix = t -= 2; - return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; + return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; // TODO: ehrich: operation with s is undefined } static real_t out_in(real_t t, real_t b, real_t c, real_t d) diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 57dd29ad07e..5b837d699c5 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -115,6 +115,8 @@ void Button::_notification(int p_what) { text_ofs.y+=style->get_offset().y; } break; case ALIGN_CENTER: { + if (text_ofs.x<0) + text_ofs.x=0; text_ofs+=icon_ofs; text_ofs+=style->get_offset(); } break; diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 309152ba8ff..2aa82bc5f58 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -59,7 +59,7 @@ bool CheckBox::is_radio() Node* parent = this; do { parent = parent->get_parent(); - if (dynamic_cast< ButtonGroup* >(parent)) + if (parent->cast_to()) break; } while (parent); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 50ce657d2e0..13cf87ac2ba 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -92,7 +92,6 @@ void FileDialog::_file_entered(const String& p_file) { } void FileDialog::_save_confirm_pressed() { - String f=dir_access->get_current_dir().plus_file(file->get_text()); emit_signal("file_selected",f); hide(); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 6afff81fdee..dac21275dcd 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -99,7 +99,7 @@ void Label::_notification(int p_what) { int chars_total=0; int vbegin=0,vsep=0; - + if (lines_total && lines_total < lines_visible) { @@ -136,10 +136,9 @@ void Label::_notification(int p_what) { if (!wc) return; - + int c = 0; int line=0; while(wc) { - /* handle lines not meant to be drawn quickly */ if (line>line_to) break; @@ -170,8 +169,8 @@ void Label::_notification(int p_what) { while(to && to->char_pos>=0) { taken+=to->pixel_width; - if (to!=from) { - spaces++; + if (to!=from && to->space_count) { + spaces+=to->space_count; } to=to->next; } @@ -212,15 +211,15 @@ void Label::_notification(int p_what) { ERR_PRINT("BUG"); return; } - if (from!=wc) { + if (from->space_count) { /* spacing */ - x_ofs+=space_w; + x_ofs+=space_w*from->space_count; if (can_fill && align==ALIGN_FILL && spaces) { - + x_ofs+=int((size.width-(taken+space_w*spaces))/spaces); } - - + + } @@ -253,7 +252,7 @@ void Label::_notification(int p_what) { } for (int i=0;iword_len;i++) { - + if (visible_chars < 0 || chars_total font = get_font("font"); - + int current_word_size=0; int word_pos=0; int line_width=0; - int last_width=0; + int space_count=0; + int space_width=font->get_char_size(' ').width; line_count=1; total_char_cache=0; @@ -374,16 +374,17 @@ void Label::regenerate_word_cache() { for (int i=0;i=33 && (current < 65||current >90) && (current<97||current>122) && (current<48||current>57); bool insert_newline=false; - + int char_width; + if (current<33) { - + if (current_word_size>0) { - WordCache *wc = memnew( WordCache ); if (word_cache) { last->next=wc; @@ -391,14 +392,16 @@ void Label::regenerate_word_cache() { word_cache=wc; } last=wc; - + wc->pixel_width=current_word_size; wc->char_pos=word_pos; wc->word_len=i-word_pos; + wc->space_count = space_count; current_word_size=0; - + space_count=0; + } - + if (current=='\n') { insert_newline=true; @@ -408,26 +411,49 @@ void Label::regenerate_word_cache() { if (i 0 || last==NULL || last->char_pos!=WordCache::CHAR_WRAPLINE) { + space_count++; + line_width+=space_width; + }else { + space_count=0; + } } } else { - + // latin characters if (current_word_size==0) { - if (line_width>0) // add a space before the new word if a word existed before - line_width+=font->get_char_size(' ').width; word_pos=i; } - int char_width=font->get_char_size(current).width; + char_width=font->get_char_size(current).width; current_word_size+=char_width; line_width+=char_width; total_char_cache++; } - - if ((autowrap && line_width>=width && last_width= width) && ((last && last->char_pos >= 0) || not_latin)) || insert_newline) { + if (not_latin) { + if (current_word_size>0) { + WordCache *wc = memnew( WordCache ); + if (word_cache) { + last->next=wc; + } else { + word_cache=wc; + } + last=wc; + + wc->pixel_width=current_word_size-char_width; + wc->char_pos=word_pos; + wc->word_len=i-word_pos; + wc->space_count = space_count; + current_word_size=char_width; + space_count=0; + word_pos=i; + } + } + WordCache *wc = memnew( WordCache ); if (word_cache) { last->next=wc; @@ -435,18 +461,16 @@ void Label::regenerate_word_cache() { word_cache=wc; } last=wc; - + wc->pixel_width=0; wc->char_pos=insert_newline?WordCache::CHAR_NEWLINE:WordCache::CHAR_WRAPLINE; line_width=current_word_size; line_count++; + space_count=0; - } - last_width=line_width; - } //total_char_cache -= line_count + 1; // do not count new lines (including the first one) @@ -465,7 +489,7 @@ void Label::regenerate_word_cache() { set_max(line_count); word_cache_dirty=false; - + } diff --git a/scene/gui/label.h b/scene/gui/label.h index 3b0dddc1a3a..81e3ab5676c 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -75,8 +75,9 @@ private: int char_pos; // if -1, then newline int word_len; int pixel_width; + int space_count; WordCache *next; - WordCache() { char_pos=0; word_len=0; pixel_width=0; next=0; } + WordCache() { char_pos=0; word_len=0; pixel_width=0; next=0; space_count=0;} }; bool word_cache_dirty; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 14aa3da85ff..fec9e401f16 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -272,7 +272,7 @@ void LineEdit::_input_event(InputEvent p_event) { if (editable) { selection_delete(); - CharType ucodestr[2]={k.unicode,0}; + CharType ucodestr[2]={(CharType)k.unicode,0}; append_at_cursor(ucodestr); emit_signal("text_changed",text); _change_notify("text"); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4be53839bef..6b2e5aea787 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -235,6 +235,9 @@ if (m_height > line_height) {\ while (c[end]!=0 && !(end && c[end-1]==' ' && c[end]!=' ')) { int cw = font->get_char_size(c[end],c[end+1]).width; + if (c[end]=='\t') { + cw=tab_size*font->get_char_size(' ').width; + } w+=cw; if (c[end]==' ') { @@ -268,7 +271,9 @@ if (m_height > line_height) {\ } if (found_space) { - fw+=l.offset_caches[line]/l.space_caches[line]; + int ln = MIN(l.offset_caches.size()-1,line); + + fw+=l.offset_caches[ln]/l.space_caches[ln]; } } @@ -290,6 +295,9 @@ if (m_height > line_height) {\ int cw=font->get_char_size(c[i],c[i+1]).x; + if (c[i]=='\t') { + cw=tab_size*font->get_char_size(' ').width; + } if (p_click_pos.x-cw/2>pofs) { @@ -330,6 +338,10 @@ if (m_height > line_height) {\ cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color); } + if (c[i]=='\t') { + cw=tab_size*font->get_char_size(' ').width; + } + //print_line("draw char: "+String::chr(c[i])); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 1e82432165e..db8fbf7a63d 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -489,7 +489,7 @@ void TextEdit::_notification(int p_what) { CharType cc = text[i][j]; //ignore any brackets inside a string - if (cc== '"' | cc == '\'') { + if (cc== '"' || cc == '\'') { CharType quotation = cc; do { j++; @@ -560,7 +560,7 @@ void TextEdit::_notification(int p_what) { CharType cc = text[i][j]; //ignore any brackets inside a string - if (cc== '"' | cc == '\'') { + if (cc== '"' || cc == '\'') { CharType quotation = cc; do { j--; @@ -1249,7 +1249,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } - if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600) { + if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600 && cursor.line==prev_line) { //tripleclick select line select(cursor.line,0,cursor.line,text[cursor.line].length()); last_dblclk=0; @@ -1440,7 +1440,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } else { //different char, go back - const CharType chr[2] = {k.unicode, 0}; + const CharType chr[2] = {(CharType)k.unicode, 0}; if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { _consume_pair_symbol(chr[0]); } else { @@ -2062,7 +2062,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (readonly) break; - const CharType chr[2] = {k.unicode, 0}; + const CharType chr[2] = {(CharType)k.unicode, 0}; if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { _consume_pair_symbol(chr[0]); @@ -3494,6 +3494,9 @@ void TextEdit::set_line(int line, String new_text) return; _remove_text(line, 0, line, text[line].length()); _insert_text(line, 0, new_text); + if (cursor.line==line) { + cursor.column=MIN(cursor.column,new_text.length()); + } } void TextEdit::insert_at(const String &p_text, int at) diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e0181b92385..5c60b9fbff5 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1417,6 +1417,41 @@ void Node::_duplicate_and_reown(Node* p_new_parent, const Map& p_re } + +void Node::_duplicate_signals(const Node* p_original,Node* p_copy) const { + + if (this!=p_original && get_owner()!=p_original) + return; + + List conns; + get_all_signal_connections(&conns); + + for (List::Element *E=conns.front();E;E=E->next()) { + + if (E->get().flags&CONNECT_PERSIST) { + //user connected + NodePath p = p_original->get_path_to(this); + Node *copy = p_copy->get_node(p); + + Node *target = E->get().target->cast_to(); + if (!target) + continue; + NodePath ptarget = p_original->get_path_to(target); + Node *copytarget = p_copy->get_node(ptarget); + + if (copy && copytarget) { + copy->connect(E->get().signal,copytarget,E->get().method,E->get().binds,CONNECT_PERSIST); + } + } + } + + for(int i=0;i_duplicate_signals(p_original,p_copy); + } + +} + + Node *Node::duplicate_and_reown(const Map& p_reown_map) const { @@ -1455,6 +1490,7 @@ Node *Node::duplicate_and_reown(const Map& p_reown_map) const { get_child(i)->_duplicate_and_reown(node,p_reown_map); } + _duplicate_signals(this,node); return node; } diff --git a/scene/main/node.h b/scene/main/node.h index aeada3c5bb8..be32c4e7261 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -126,6 +126,7 @@ private: void _propagate_pause_owner(Node*p_owner); Array _get_node_and_resource(const NodePath& p_path); + void _duplicate_signals(const Node* p_original,Node* p_copy) const; void _duplicate_and_reown(Node* p_new_parent, const Map& p_reown_map) const; Array _get_children() const; Array _get_groups() const; @@ -170,6 +171,7 @@ public: NOTIFICATION_PROCESS = 17, NOTIFICATION_PARENTED=18, NOTIFICATION_UNPARENTED=19, + NOTIFICATION_INSTANCED=20, }; /* NODE/TREE */ diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 2e3e7db0ad2..3a80382a40e 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -45,14 +45,14 @@ void Timer::_notification(int p_what) { } } break; case NOTIFICATION_PROCESS: { - - if (!is_processing()) + if (timer_process_mode == TIMER_PROCESS_FIXED || !is_processing()) return; time_left -= get_process_delta_time(); if (time_left<0) { if (!one_shot) - time_left=wait_time+time_left; + //time_left=wait_time+time_left; + time_left = wait_time; else stop(); @@ -60,13 +60,27 @@ void Timer::_notification(int p_what) { } } break; + case NOTIFICATION_FIXED_PROCESS: { + if (timer_process_mode == TIMER_PROCESS_IDLE || !is_fixed_processing()) + return; + time_left -= get_fixed_process_delta_time(); + + if (time_left<0) { + if (!one_shot) + //time_left = wait_time + time_left; + time_left = wait_time; + else + stop(); + emit_signal("timeout"); + } + + } break; } } void Timer::set_wait_time(float p_time) { - ERR_EXPLAIN("time should be greater than zero."); ERR_FAIL_COND(p_time<=0); wait_time=p_time; @@ -96,14 +110,13 @@ bool Timer::has_autostart() const { } void Timer::start() { - time_left=wait_time; - set_process(true); + _set_process(true); } void Timer::stop() { time_left=-1; - set_process(false); + _set_process(false); autostart=false; } @@ -112,6 +125,41 @@ float Timer::get_time_left() const { return time_left >0 ? time_left : 0; } +void Timer::set_timer_process_mode(TimerProcessMode p_mode) { + + if (timer_process_mode == p_mode) + return; + + switch (timer_process_mode) { + case TIMER_PROCESS_FIXED: + if (is_fixed_processing()) { + set_fixed_process(false); + set_process(true); + } + break; + case TIMER_PROCESS_IDLE: + if (is_processing()) { + set_process(false); + set_fixed_process(true); + } + break; + } + timer_process_mode = p_mode; +} + +Timer::TimerProcessMode Timer::get_timer_process_mode() const{ + + return timer_process_mode; +} + + +void Timer::_set_process(bool p_process, bool p_force) +{ + switch (timer_process_mode) { + case TIMER_PROCESS_FIXED: set_fixed_process(p_process); break; + case TIMER_PROCESS_IDLE: set_process(p_process); break; + } +} void Timer::_bind_methods() { @@ -129,8 +177,12 @@ void Timer::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_time_left"),&Timer::get_time_left); + ObjectTypeDB::bind_method(_MD("set_timer_process_mode", "mode"), &Timer::set_timer_process_mode); + ObjectTypeDB::bind_method(_MD("get_timer_process_mode"), &Timer::get_timer_process_mode); + ADD_SIGNAL( MethodInfo("timeout") ); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_timer_process_mode"), _SCS("get_timer_process_mode")); ADD_PROPERTY( PropertyInfo(Variant::REAL, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.01,4096,0.01" ), _SCS("set_wait_time"), _SCS("get_wait_time") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL, "one_shot" ), _SCS("set_one_shot"), _SCS("is_one_shot") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL, "autostart" ), _SCS("set_autostart"), _SCS("has_autostart") ); @@ -138,8 +190,7 @@ void Timer::_bind_methods() { } Timer::Timer() { - - + timer_process_mode = TIMER_PROCESS_IDLE; autostart=false; wait_time=1; one_shot=false; diff --git a/scene/main/timer.h b/scene/main/timer.h index 021638ccfcb..4b9cecba84e 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -46,6 +46,11 @@ protected: static void _bind_methods(); public: + enum TimerProcessMode { + TIMER_PROCESS_FIXED, + TIMER_PROCESS_IDLE, + }; + void set_wait_time(float p_time); float get_wait_time() const; @@ -60,7 +65,16 @@ public: float get_time_left() const; + void set_timer_process_mode(TimerProcessMode p_mode); + TimerProcessMode get_timer_process_mode() const; Timer(); + +private: + TimerProcessMode timer_process_mode; + void _set_process(bool p_process, bool p_force = false); + }; +VARIANT_ENUM_CAST(Timer::TimerProcessMode); + #endif // TIMER_H diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 0f11a66703d..095406dad98 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1216,8 +1216,8 @@ T Animation::_interpolate( const Vector< TKey >& p_keys, float p_time, Inter if (p_ok) *p_ok=true; - - int next; + + int next=0; float c=0; // prepare for all cases of interpolation diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 9f36510739b..a1cb1205e5c 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -182,6 +182,8 @@ Node *PackedScene::instance(bool p_gen_edit_state) const { if (get_path()!="" && get_path().find("::")==-1) s->set_filename(get_path()); + + s->notification(Node::NOTIFICATION_INSTANCED); return ret_nodes[0]; } diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index 131b0e193fb..24d5978856c 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -2160,7 +2160,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; Vector3 dv=p_node->param2; - code +="uniform float "+name+"=vec3("+rtos(dv.x)+","+rtos(dv.y)+","+rtos(dv.z)+");\n"; + code +="uniform vec3 "+name+"=vec3("+rtos(dv.x)+","+rtos(dv.y)+","+rtos(dv.z)+");\n"; code += OUTNAME(p_node->id,0)+"="+name+";\n"; }break; case NODE_RGB_INPUT: { diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 8350bf8cc85..21bdb6c0ab9 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -105,6 +105,9 @@ bool Theme::_get(const StringName& p_name,Variant &r_ret) const { void Theme::_get_property_list( List *p_list) const { + + List list; + const StringName *key=NULL; while((key=icon_map.next(key))) { @@ -113,7 +116,7 @@ void Theme::_get_property_list( List *p_list) const { while((key2=icon_map[*key].next(key2))) { - p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) ); + list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) ); } } @@ -125,7 +128,7 @@ void Theme::_get_property_list( List *p_list) const { while((key2=style_map[*key].next(key2))) { - p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) ); + list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) ); } } @@ -138,7 +141,7 @@ void Theme::_get_property_list( List *p_list) const { while((key2=font_map[*key].next(key2))) { - p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) ); + list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) ); } } @@ -150,7 +153,7 @@ void Theme::_get_property_list( List *p_list) const { while((key2=color_map[*key].next(key2))) { - p_list->push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) ); + list.push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) ); } } @@ -162,9 +165,14 @@ void Theme::_get_property_list( List *p_list) const { while((key2=constant_map[*key].next(key2))) { - p_list->push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) ); + list.push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) ); } } + + list.sort(); + for(List::Element *E=list.front();E;E=E->next()) { + p_list->push_back(E->get()); + } } diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index 70fc3e8fcb5..c018ab62248 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -34,8 +34,10 @@ #include "self_list.h" #include "broad_phase_sw.h" -#define MAX_OBJECT_DISTANCE 10000000 +#ifdef DEBUG_ENABLED +#define MAX_OBJECT_DISTANCE 10000000.0 #define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE*MAX_OBJECT_DISTANCE) +#endif class SpaceSW; diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 2b4a137e118..03d5b7afa16 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -551,7 +551,7 @@ bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) ERR_FAIL_COND_V(!body,false); ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false); - body->is_shape_set_as_trigger(p_shape_idx); + return body->is_shape_set_as_trigger(p_shape_idx); } diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index f73fbb628b8..3b1705bd569 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -32,7 +32,7 @@ bool AreaPair2DSW::setup(float p_step) { - bool result = CollisionSolver2DSW::solve(body->get_shape(body_shape),body->get_transform() * body->get_shape_transform(body_shape),Vector2(),area->get_shape(area_shape),area->get_transform() * area->get_shape_transform(area_shape),Vector2(),NULL,this); + bool result = area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape),body->get_transform() * body->get_shape_transform(body_shape),Vector2(),area->get_shape(area_shape),area->get_transform() * area->get_shape_transform(area_shape),Vector2(),NULL,this); if (result!=colliding) { @@ -102,7 +102,7 @@ AreaPair2DSW::~AreaPair2DSW() { bool Area2Pair2DSW::setup(float p_step) { - bool result = CollisionSolver2DSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); + bool result = area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); if (result!=colliding) { diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 464b8183844..0ba661b4c41 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -657,6 +657,7 @@ Body2DSW::Body2DSW() : CollisionObject2DSW(TYPE_BODY), active_list(this), inerti area_linear_damp=0; contact_count=0; gravity_scale=1.0; + using_one_way_cache=false; one_way_collision_max_depth=0.1; still_time=0; diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index ca4d80a15bb..e34686f3acd 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -81,6 +81,7 @@ class Body2DSW : public CollisionObject2DSW { bool active; bool can_sleep; bool first_time_kinematic; + bool using_one_way_cache; void _update_inertia(); virtual void _shapes_changed(); Matrix32 new_transform; @@ -229,12 +230,17 @@ public: _FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode=p_mode; } _FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; } - void set_one_way_collision_direction(const Vector2& p_dir) { one_way_collision_direction=p_dir; } + void set_one_way_collision_direction(const Vector2& p_dir) { + one_way_collision_direction=p_dir; + using_one_way_cache=one_way_collision_direction!=Vector2(); + } Vector2 get_one_way_collision_direction() const { return one_way_collision_direction; } void set_one_way_collision_max_depth(float p_depth) { one_way_collision_max_depth=p_depth; } float get_one_way_collision_max_depth() const { return one_way_collision_max_depth; } + _FORCE_INLINE_ bool is_using_one_way_collision() const { return using_one_way_cache; } + void set_space(Space2DSW *p_space); void update_inertias(); diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index a2402d14734..6bfed134e61 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -234,7 +234,7 @@ bool BodyPair2DSW::setup(float p_step) { //cannot collide - if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { + if (!A->test_collision_mask(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { collided=false; return false; } @@ -265,6 +265,8 @@ bool BodyPair2DSW::setup(float p_step) { } //faster to set than to check.. + //bool prev_collided=collided; + collided = CollisionSolver2DSW::solve(shape_A_ptr,xform_A,motion_A,shape_B_ptr,xform_B,motion_B,_add_contact,this,&sep_axis); if (!collided) { @@ -280,11 +282,70 @@ bool BodyPair2DSW::setup(float p_step) { collided=true; } - if (!collided) + if (!collided) { + oneway_disabled=false; return false; + } } + if (oneway_disabled) + return false; + + //if (!prev_collided) { + { + + if (A->is_using_one_way_collision()) { + Vector2 direction = A->get_one_way_collision_direction(); + bool valid=false; + for(int i=0;iget_linear_velocity().dot(direction)<0) + continue; + + if (!c.reused) { + continue; + } + + valid=true; + } + + if (!valid) { + collided=false; + oneway_disabled=true; + return false; + } + } + + if (B->is_using_one_way_collision()) { + Vector2 direction = B->get_one_way_collision_direction(); + bool valid=false; + for(int i=0;iget_linear_velocity().dot(direction)<0) + continue; + + if (!c.reused) { + continue; + } + + valid=true; + } + if (!valid) { + collided=false; + oneway_disabled=true; + return false; + } + } + } + real_t max_penetration = space->get_contact_max_allowed_penetration(); float bias = 0.3f; @@ -472,6 +533,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A,Body2DSW *p_B, int p_sha B->add_constraint(this,1); contact_count=0; collided=false; + oneway_disabled=false; } diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/body_pair_2d_sw.h index 23655120361..a7fa287be47 100644 --- a/servers/physics_2d/body_pair_2d_sw.h +++ b/servers/physics_2d/body_pair_2d_sw.h @@ -76,6 +76,7 @@ class BodyPair2DSW : public Constraint2DSW { Contact contacts[MAX_CONTACTS]; int contact_count; bool collided; + bool oneway_disabled; int cc; diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 8160f22a311..7c8e223c57a 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -226,7 +226,7 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) { type=p_type; space=NULL; instance_id=0; - user_mask=0; + collision_mask=1; layer_mask=1; pickable=true; } diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 58dc3e9cd99..f3432060b93 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -65,7 +65,7 @@ private: Space2DSW *space; Matrix32 transform; Matrix32 inv_transform; - uint32_t user_mask; + uint32_t collision_mask; uint32_t layer_mask; bool _static; @@ -117,8 +117,8 @@ public: _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; } - void set_user_mask(uint32_t p_mask) {user_mask=p_mask;} - _FORCE_INLINE_ uint32_t get_user_mask() const { return user_mask; } + void set_collision_mask(uint32_t p_mask) {collision_mask=p_mask;} + _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; } void set_layer_mask(uint32_t p_mask) {layer_mask=p_mask;} _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; } @@ -133,6 +133,11 @@ public: void set_pickable(bool p_pickable) { pickable=p_pickable; } _FORCE_INLINE_ bool is_pickable() const { return pickable; } + _FORCE_INLINE_ bool test_collision_mask(CollisionObject2DSW* p_other) const { + + return layer_mask&p_other->collision_mask || p_other->layer_mask&collision_mask; + } + virtual ~CollisionObject2DSW() {} }; diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index d31606acfb3..08d871be69b 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -480,6 +480,22 @@ void Physics2DServerSW::area_set_monitorable(RID p_area,bool p_monitorable) { } +void Physics2DServerSW::area_set_collision_mask(RID p_area,uint32_t p_mask) { + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_mask(p_mask); +} + +void Physics2DServerSW::area_set_layer_mask(RID p_area,uint32_t p_mask) { + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_layer_mask(p_mask); +} + void Physics2DServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { @@ -726,20 +742,20 @@ uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body, uint32_t p_flags) co }; -void Physics2DServerSW::body_set_user_mask(RID p_body, uint32_t p_flags) { +void Physics2DServerSW::body_set_collision_mask(RID p_body, uint32_t p_flags) { Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); - body->set_user_mask(p_flags); + body->set_collision_mask(p_flags); }; -uint32_t Physics2DServerSW::body_get_user_mask(RID p_body, uint32_t p_flags) const { +uint32_t Physics2DServerSW::body_get_collision_mask(RID p_body, uint32_t p_flags) const { Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body,0); - return body->get_user_mask(); + return body->get_collision_mask(); }; void Physics2DServerSW::body_set_param(RID p_body, BodyParameter p_param, float p_value) { diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 50675cbd09f..341df2fdc91 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -134,6 +134,8 @@ public: virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const; virtual Matrix32 area_get_transform(RID p_area) const; virtual void area_set_monitorable(RID p_area,bool p_monitorable); + virtual void area_set_collision_mask(RID p_area,uint32_t p_mask); + virtual void area_set_layer_mask(RID p_area,uint32_t p_mask); virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); @@ -179,8 +181,8 @@ public: virtual void body_set_layer_mask(RID p_body, uint32_t p_mask); virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const; - virtual void body_set_user_mask(RID p_body, uint32_t p_mask); - virtual uint32_t body_get_user_mask(RID p_body, uint32_t p_mask) const; + virtual void body_set_collision_mask(RID p_body, uint32_t p_mask); + virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const; virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value); virtual float body_get_param(RID p_body, BodyParameter p_param) const; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 9a1b977bdad..9b69ab299d3 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -555,6 +555,42 @@ Physics2DDirectSpaceStateSW::Physics2DDirectSpaceStateSW() { +int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body,const Rect2& p_aabb) { + + + int amount = broadphase->cull_aabb(p_aabb,intersection_query_results,INTERSECTION_QUERY_MAX,intersection_query_subindex_results); + + for(int i=0;iget_type()==CollisionObject2DSW::TYPE_AREA) + keep=false; + else if ((static_cast(intersection_query_results[i])->test_collision_mask(p_body))==0) + keep=false; + else if (static_cast(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) + keep=false; + else if (static_cast(intersection_query_results[i])->is_shape_set_as_trigger(intersection_query_subindex_results[i])) + keep=false; + + if (!keep) { + + if (icull_aabb(body_aabb,intersection_query_results,INTERSECTION_QUERY_MAX,intersection_query_subindex_results); - - for(int i=0;iget_type()==CollisionObject2DSW::TYPE_AREA) - keep=false; - else if ((static_cast(intersection_query_results[i])->get_layer_mask()&p_body->get_layer_mask())==0) - keep=false; - else if (static_cast(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) - keep=false; - else if (static_cast(intersection_query_results[i])->is_shape_set_as_trigger(intersection_query_subindex_results[i])) - keep=false; - - if (!keep) { - - if (iget_transform(); @@ -642,6 +639,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p bool collided=false; + int amount = _cull_aabb_for_body(p_body,body_aabb); for(int j=0;jget_shape_count();j++) { if (p_body->is_shape_set_as_trigger(j)) @@ -657,7 +655,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { const Body2DSW *body=static_cast(col_obj); - cbk.valid_dir=body->get_one_way_collision_direction(); + + Vector2 cdir = body->get_one_way_collision_direction(); + if (cdir!=Vector2() && p_motion.dot(cdir)<0) + continue; + + cbk.valid_dir=cdir; cbk.valid_depth=body->get_one_way_collision_max_depth(); } else { cbk.valid_dir=Vector2(); @@ -694,6 +697,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p } body_transform.elements[2]+=recover_motion; + body_aabb.pos+=recover_motion; recover_attempts--; @@ -709,7 +713,11 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p { // STEP 2 ATTEMPT MOTION + Rect2 motion_aabb=body_aabb; + motion_aabb.pos+=p_motion; + motion_aabb=motion_aabb.merge(body_aabb); + int amount = _cull_aabb_for_body(p_body,motion_aabb); for(int j=0;jget_shape_count();j++) { @@ -847,6 +855,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p Matrix32 body_shape_xform = ugt * p_body->get_shape_transform(best_shape); Shape2DSW *body_shape = p_body->get_shape(best_shape); + body_aabb.pos+=p_motion*unsafe; + + int amount = _cull_aabb_for_body(p_body,body_aabb); + for(int i=0;i& p_exclude,uint32_t p_user_mask) { +Variant PhysicsDirectSpaceState::_intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max,const Vector& p_exclude,uint32_t p_collision_mask) { diff --git a/servers/physics_server.h b/servers/physics_server.h index 97a1d34e7b4..ffb462af22a 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -131,8 +131,8 @@ class PhysicsDirectSpaceState : public Object { OBJ_TYPE( PhysicsDirectSpaceState, Object ); -// Variant _intersect_ray(const Vector3& p_from, const Vector3& p_to,const Vector& p_exclude=Vector(),uint32_t p_user_mask=0); -// Variant _intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max=64,const Vector& p_exclude=Vector(),uint32_t p_user_mask=0); +// Variant _intersect_ray(const Vector3& p_from, const Vector3& p_to,const Vector& p_exclude=Vector(),uint32_t p_collision_mask=0); +// Variant _intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max=64,const Vector& p_exclude=Vector(),uint32_t p_collision_mask=0); public: enum ObjectTypeMask { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 81862fb3a6d..79365f7db6e 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -863,17 +863,17 @@ public: if (polygon->indices != NULL) { r.pos=polygon->points[polygon->indices[0]]; - for (int i=1; icount; i++) { + for (int i=1; ipoints[polygon->indices[i]]); - }; + } } else { r.pos=polygon->points[0]; - for (int i=1; icount; i++) { + for (int i=1; ipoints[i]); - }; - }; + } + } } break; case CanvasItem::Command::TYPE_CIRCLE: { diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 6556f8bc425..a547da9b61b 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -7281,7 +7281,7 @@ void VisualServerRaster::_draw_viewports() { if (r.size.width==0) r.size.width=window_w; if (r.size.height==0) - r.size.height=window_w; + r.size.height=window_h; _draw_viewport(vp,r.pos.x,r.pos.y,r.size.width,r.size.height); diff --git a/tools/docdump/doc_dump.cpp b/tools/docdump/doc_dump.cpp index d10f6c9ce34..17aff3dc740 100644 --- a/tools/docdump/doc_dump.cpp +++ b/tools/docdump/doc_dump.cpp @@ -65,7 +65,7 @@ static String _escape_string(const String& p_str) { ret=ret.replace(">","<"); ret=ret.replace("'","'"); ret=ret.replace("\"","""); - for (int i=1;i<32;i++) { + for (char i=1;i<32;i++) { char chr[2]={i,0}; ret=ret.replace(chr,"&#"+String::num(i)+";"); diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp index 39eec4e69b1..63ab186a38b 100644 --- a/tools/editor/animation_editor.cpp +++ b/tools/editor/animation_editor.cpp @@ -1375,7 +1375,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (p_input.is_action("ui_up")) selected_track--; if (v_scroll->is_visible() && p_input.is_action("ui_page_up")) - selected_track--;; + selected_track--; if (selected_track<0) selected_track=0; diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index 94e887c3e71..8e96123c36d 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -940,19 +940,19 @@ String EditorFileSystem::get_file_type(const String& p_file) const { EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { if (!filesystem || scanning) - return false; + return NULL; String f = Globals::get_singleton()->localize_path(p_path); if (!f.begins_with("res://")) - return false; + return NULL; f=f.substr(6,f.length()); f=f.replace("\\","/"); if (f==String()) - return filesystem; + return filesystem; if (f.ends_with("/")) f=f.substr(0,f.length()-1); @@ -960,7 +960,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { Vector path = f.split("/"); if (path.size()==0) - return false; + return NULL; EditorFileSystemDirectory *fs=filesystem; diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp index d76009a72a1..4e6435b22ee 100644 --- a/tools/editor/editor_import_export.cpp +++ b/tools/editor/editor_import_export.cpp @@ -47,6 +47,7 @@ String EditorImportPlugin::validate_source_path(const String& p_path) { String rp = Globals::get_singleton()->get_resource_path(); if (!rp.ends_with("/")) rp+="/"; + return rp.path_to_file(gp); } diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 5d55fed09bc..a6625d72043 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -3509,6 +3509,7 @@ EditorNode::EditorNode() { p=file_menu->get_popup(); p->add_item("New Scene",FILE_NEW_SCENE); p->add_item("Open Scene..",FILE_OPEN_SCENE,KEY_MASK_CMD+KEY_O); + p->add_separator(); p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S); p->add_item("Save Scene As..",FILE_SAVE_AS_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_S); p->add_separator(); diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 52eeb1fefd1..9a4505efedd 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -408,7 +408,7 @@ void EditorSettings::_load_defaults() { set("text_editor/idle_parse_delay",2); set("text_editor/create_signal_callbacks",true); - set("text_editor/autosave_interval_seconds",60); + set("text_editor/autosave_interval_secs",0); set("text_editor/font",""); hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt"); set("text_editor/auto_brace_complete", false); diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index b0ff6f6e744..375333ddf69 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -406,7 +406,10 @@ class EditorFontImportDialog : public ConfirmationDialog { imd->set_option(opt,v); } - imd->add_source(EditorImportPlugin::validate_source_path(source->get_line_edit()->get_text())); + String src_path = EditorImportPlugin::validate_source_path(source->get_line_edit()->get_text()); + //print_line("pre src path "+source->get_line_edit()->get_text()); + //print_line("src path "+src_path); + imd->add_source(src_path); imd->set_option("font/size",font_size->get_val()); return imd; @@ -1018,7 +1021,7 @@ Ref EditorFontImportPlugin::generate_font(const Refbitmap.rows; int p = slot->bitmap.pitch; - print_line("W: "+itos(w)+" P: "+itos(slot->bitmap.pitch)); + //print_line("W: "+itos(w)+" P: "+itos(slot->bitmap.pitch)); if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 64b5d5b3377..3add30d81e4 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -51,6 +51,7 @@ static const char *flag_names[]={ NULL }; +#if 0 // not used static const char *flag_short_names[]={ "Stream", "FixBorder", @@ -65,6 +66,7 @@ static const char *flag_short_names[]={ "Anisoropic", NULL }; +#endif void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) { diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 7deb856fa6c..edc5d460e74 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -130,6 +130,7 @@ void ScriptEditorQuickOpen::_bind_methods() { ObjectTypeDB::bind_method(_MD("_confirmed"),&ScriptEditorQuickOpen::_confirmed); ObjectTypeDB::bind_method(_MD("_sbox_input"),&ScriptEditorQuickOpen::_sbox_input); + ADD_SIGNAL(MethodInfo("goto_line",PropertyInfo(Variant::INT,"line"))); } @@ -815,11 +816,11 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; - int begin, end; - begin = tx->get_selection_from_line(); + if (tx->is_selection_active()) { - end = tx->get_selection_to_line(); + int begin = tx->get_selection_from_line(); + int end = tx->get_selection_to_line(); for (int i = begin; i <= end; i++) { String line_text = tx->get_line(i); @@ -839,7 +840,7 @@ void ScriptEditor::_menu_option(int p_option) { } else { - begin = tx->cursor_get_line(); + int begin = tx->cursor_get_line(); String line_text = tx->get_line(begin); // begins with tab if (line_text.begins_with("\t")) @@ -865,11 +866,10 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; - int begin, end; - begin = tx->get_selection_from_line(); if (tx->is_selection_active()) { - end = tx->get_selection_to_line(); + int begin = tx->get_selection_from_line(); + int end = tx->get_selection_to_line(); for (int i = begin; i <= end; i++) { String line_text = tx->get_line(i); @@ -879,7 +879,7 @@ void ScriptEditor::_menu_option(int p_option) { } else { - begin = tx->cursor_get_line(); + int begin = tx->cursor_get_line(); String line_text = tx->get_line(begin); line_text = '\t' + line_text; tx->set_line(begin, line_text); @@ -912,11 +912,12 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; - int begin, end; - begin = tx->get_selection_from_line(); + + if (tx->is_selection_active()) { - end = tx->get_selection_to_line(); + int begin = tx->get_selection_from_line(); + int end = tx->get_selection_to_line(); for (int i = begin; i <= end; i++) { String line_text = tx->get_line(i); @@ -930,7 +931,7 @@ void ScriptEditor::_menu_option(int p_option) { } else { - begin = tx->cursor_get_line(); + int begin = tx->cursor_get_line(); String line_text = tx->get_line(begin); if (line_text.begins_with("#")) @@ -1089,6 +1090,18 @@ void ScriptEditor::_notification(int p_what) { editor->connect("stop_pressed",this,"_editor_stop"); editor->connect("script_add_function_request",this,"_add_callback"); editor->connect("resource_saved",this,"_res_saved_callback"); + autosave_timer->connect("timeout",this,"_autosave_scripts"); + { + float autosave_time = EditorSettings::get_singleton()->get("text_editor/autosave_interval_secs"); + if (autosave_time>0) { + autosave_timer->set_wait_time(autosave_time); + autosave_timer->start(); + } else { + autosave_timer->stop(); + } + } + + EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); } @@ -1339,7 +1352,8 @@ void ScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_breaked",&ScriptEditor::_breaked); ObjectTypeDB::bind_method("_show_debugger",&ScriptEditor::_show_debugger); ObjectTypeDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip); - + ObjectTypeDB::bind_method("_autosave_scripts",&ScriptEditor::_autosave_scripts); + ObjectTypeDB::bind_method("_editor_settings_changed",&ScriptEditor::_editor_settings_changed); } @@ -1568,6 +1582,25 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const } +void ScriptEditor::_editor_settings_changed() { + + print_line("settings changed"); + float autosave_time = EditorSettings::get_singleton()->get("text_editor/autosave_interval_secs"); + if (autosave_time>0) { + autosave_timer->set_wait_time(autosave_time); + autosave_timer->start(); + } else { + autosave_timer->stop(); + } + +} + +void ScriptEditor::_autosave_scripts() { + + print_line("autosaving"); + save_external_data(); +} + ScriptEditor::ScriptEditor(EditorNode *p_editor) { editor=p_editor; @@ -1718,6 +1751,11 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { v_split->add_child(debugger); debugger->connect("breaked",this,"_breaked"); + + autosave_timer = memnew( Timer ); + autosave_timer->set_one_shot(false); + add_child(autosave_timer); + // debugger_gui->hide(); } diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 7526138112f..acfdd1e9668 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -154,6 +154,7 @@ class ScriptEditor : public VBoxContainer { MenuButton *window_menu; MenuButton *debug_menu; MenuButton *help_menu; + Timer *autosave_timer; uint64_t idle; TabContainer *tab_container; @@ -195,6 +196,9 @@ class ScriptEditor : public VBoxContainer { void _show_debugger(bool p_show); void _update_window_menu(); + void _editor_settings_changed(); + void _autosave_scripts(); + static ScriptEditor *script_editor; protected: void _notification(int p_what); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 1db901e56b0..03fcbffa24d 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -539,7 +539,6 @@ void GraphCurveMapEdit::_plot_curve(const Vector2& p_a,const Vector2& p_b,const if ((lastx != newx) || (lasty != newy)) { #if 0 - /* if(fix255) { /* use fixed array size (for the curve graph) */ diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index 4dae60399be..0b3f3e0626b 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -3172,11 +3172,11 @@ void SpatialEditor::_init_indicators() { int arrow_sides=6; - for(int i = 0; i < 7 ; i++) { + for(int k = 0; k < 7 ; k++) { - Matrix3 ma(ivec,Math_PI*2*float(i)/arrow_sides); - Matrix3 mb(ivec,Math_PI*2*float(i+1)/arrow_sides); + Matrix3 ma(ivec,Math_PI*2*float(k)/arrow_sides); + Matrix3 mb(ivec,Math_PI*2*float(k+1)/arrow_sides); for(int j=0;jset_icon( get_icon("ToolRotate","EditorIcons") ); tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon( get_icon("ToolScale","EditorIcons") ); instance_button->set_icon( get_icon("SpatialAdd","EditorIcons") ); + instance_button->hide(); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT),get_icon("Panels1","EditorIcons")); diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index c54e036a85a..00956919b73 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -940,7 +940,7 @@ ProjectManager::ProjectManager() { String cp; cp.push_back(0xA9); cp.push_back(0); - l->set_text(cp+" 2008-2014 Juan Linietsky, Ariel Manzur."); + l->set_text(cp+" 2008-2015 Juan Linietsky, Ariel Manzur."); l->set_align(Label::ALIGN_CENTER); vb->add_child(l); diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp index f9d92c8d81a..521a10bbd0a 100644 --- a/tools/editor/spatial_editor_gizmos.cpp +++ b/tools/editor/spatial_editor_gizmos.cpp @@ -1257,7 +1257,8 @@ void SkeletonSpatialGizmo::redraw() { //find closest axis int closest=-1; - float closest_d; + float closest_d = 0.0; + for(int j=0;j<3;j++) { float dp = Math::abs(grests[parent].basis[j].normalized().dot(d)); if (j==0 || dp>closest_d) diff --git a/tools/pck/pck_packer.cpp b/tools/pck/pck_packer.cpp index 09611b3a93c..d398fefb5f4 100644 --- a/tools/pck/pck_packer.cpp +++ b/tools/pck/pck_packer.cpp @@ -136,7 +136,7 @@ Error PCKPacker::flush(bool p_verbose) { count += 1; if (p_verbose) { if (count % 100 == 0) { - printf("%i/%i (%.2f\%)\r", count, files.size(), float(count) / files.size() * 100); + printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100); fflush(stdout); }; }; diff --git a/version.py b/version.py index 577bc73208c..03c76b704b8 100644 --- a/version.py +++ b/version.py @@ -2,6 +2,6 @@ short_name="godot" name="Godot Engine" major=1 minor=1 -status="rc1" +status="rc2"