diff options
33 files changed, 1595 insertions, 263 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index e3360a23d2..fd6a91d125 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -4,6 +4,7 @@ #include "io/marshalls.h" #include "io/base64.h" #include "core/globals.h" +#include "io/file_access_encrypted.h" _ResourceLoader *_ResourceLoader::singleton=NULL; @@ -812,6 +813,44 @@ _Geometry::_Geometry() { ///////////////////////// FILE + +Error _File::open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key) { + + Error err = open(p_path,p_mode_flags); + if (err) + return err; + + FileAccessEncrypted *fae = memnew( FileAccessEncrypted ); + err = fae->open_and_parse(f,p_key,(p_mode_flags==WRITE)?FileAccessEncrypted::MODE_WRITE_AES256:FileAccessEncrypted::MODE_READ); + if (err) { + memdelete(fae); + close(); + return err; + } + f=fae; + return OK; +} + +Error _File::open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass) { + + Error err = open(p_path,p_mode_flags); + if (err) + return err; + + FileAccessEncrypted *fae = memnew( FileAccessEncrypted ); + err = fae->open_and_parse_password(f,p_pass,(p_mode_flags==WRITE)?FileAccessEncrypted::MODE_WRITE_AES256:FileAccessEncrypted::MODE_READ); + if (err) { + memdelete(fae); + close(); + return err; + } + + f=fae; + return OK; + +} + + Error _File::open(const String& p_path, int p_mode_flags) { close(); @@ -1113,6 +1152,10 @@ Variant _File::get_var() const { void _File::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("open_encrypted","path","mode_flags","key"),&_File::open_encrypted); + ObjectTypeDB::bind_method(_MD("open_encrypted_with_pass","path","mode_flags","pass"),&_File::open_encrypted_pass); + ObjectTypeDB::bind_method(_MD("open","path","flags"),&_File::open); ObjectTypeDB::bind_method(_MD("close"),&_File::close); ObjectTypeDB::bind_method(_MD("is_open"),&_File::is_open); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 0084726547..f5c94dcf06 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -243,6 +243,10 @@ public: READ_WRITE=3, }; + Error open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key); + Error open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass); + + Error open(const String& p_path, int p_mode_flags); ///< open a file void close(); ///< close a file bool is_open() const; ///< true when file is open diff --git a/demos/2d/platformer/engine.cfg b/demos/2d/platformer/engine.cfg index 5fc2c3b2ba..a377bf8983 100644 --- a/demos/2d/platformer/engine.cfg +++ b/demos/2d/platformer/engine.cfg @@ -10,6 +10,8 @@ name_es="Plataformero" width=800 height=480 stretch_2d=true +stretch_mode="viewport" +stretch_aspect="keep" [input] diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 6e4d97c413..e5330925a9 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -50,6 +50,7 @@ <argument index="0" name="s" type="real"> </argument> <description> + Hyperbolic cosine. </description> </method> <method name="tanh" > @@ -281,13 +282,18 @@ <return type="Nil"> </return> <description> + Reset the seed of the random number generator with a + new, different one. </description> </method> - <method name="rand" > + <method name="randi" > <return type="int"> </return> <description> - Random value (integer). + Random 32 bits value (integer). To obtain a value + from 0 to N, you can use remainder, like (for random + from 0 to 19): randi() % + 20. </description> </method> <method name="randf" > @@ -305,7 +311,8 @@ <argument index="1" name="to" type="real"> </argument> <description> - Random range. + Random range, any floating point value between + 'from' and 'to' </description> </method> <method name="rand_seed" > @@ -314,7 +321,7 @@ <argument index="0" name="seed" type="real"> </argument> <description> - random from seed, pass a seed and an array with both number and new seed is returned. + Random from seed, pass a seed and an array with both number and new seed is returned. </description> </method> <method name="deg2rad" > @@ -406,6 +413,16 @@ Return a weak reference to an object. </description> </method> + <method name="funcref" > + <return type="Object"> + </return> + <argument index="0" name="instance" type="Object"> + </argument> + <argument index="1" name="funcname" type="String"> + </argument> + <description> + </description> + </method> <method name="convert" > <return type="Object"> </return> @@ -491,12 +508,24 @@ Return an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial,final-1,increment). </description> </method> + <method name="load" > + <return type="Object"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <description> + Load a resource from the filesystem, pass a valid + path as argument. + </description> + </method> <method name="inst2dict" > <return type="Dictionary"> </return> <argument index="0" name="inst" type="Object"> </argument> <description> + Convert a script class instance to a dictionary + (useful for serializing). </description> </method> <method name="dict2inst" > @@ -505,16 +534,24 @@ <argument index="0" name="dict" type="Dictionary"> </argument> <description> + Convert a previously converted instances to dictionary + back into an instance. Useful for deserializing. </description> </method> <method name="print_stack" > <return type="Nil"> </return> <description> + Print a stack track at code location, only works when + running with debugger turned on. </description> </method> </methods> <constants> + <constant name="PI" value="3.141593"> + Constant that represents how many times the diameter of a + circumference fits around it's perimeter. + </constant> </constants> </class> <class name="@Global Scope" category="Core"> @@ -531,54 +568,79 @@ <member name="Performance" type="Performance"> </member> <member name="Globals" type="Globals"> + The file engine.cfg is read into this singleton. </member> <member name="IP" type="IP"> + Global IP protocol functions (like hostname resolution). </member> <member name="Geometry" type="Geometry"> + Geometry helpers. </member> <member name="ResourceLoader" type="ResourceLoader"> + Singleton that loads resources (load() calls this) </member> <member name="ResourceSaver" type="ResourceSaver"> + Singleton that saves resources. </member> <member name="PathRemap" type="PathRemap"> + Uset to setup remaps for the filesystem. </member> <member name="OS" type="OS"> + Operating system functions. </member> <member name="Marshalls" type="Reference"> + Used to serialize and deserialize, helpers. </member> <member name="TranslationServer" type="TranslationServer"> + Server that takes care of translating between different + languages. </member> <member name="TS" type="TranslationServer"> + Short version for TranslationServer. </member> <member name="Input" type="Input"> + Global input variables and functions. </member> <member name="SceneIO" type="SceneIO"> + Deprecaed. </member> <member name="VisualServer" type="VisualServer"> + Server that handles anything visual at low level. </member> <member name="VS" type="VisualServer"> + Short for VisualServer. </member> <member name="AudioServer" type="AudioServer"> + Server that handles anything audio at low level. </member> <member name="AS" type="AudioServer"> + Short for AudioServer. </member> <member name="PhysicsServer" type="PhysicsServer"> + Server that handles anything 3D physics at low level. </member> <member name="PS" type="PhysicsServer"> + Short for PhysicsServer. </member> <member name="Physics2DServer" type="Physics2DServer"> + Server that handles anything 2D physics at low level. </member> <member name="PS2D" type="Physics2DServer"> + Short for Physics2DServer. </member> <member name="SpatialSoundServer" type="SpatialSound2DServer"> + Server that handles spatial audio positioning in 3D at low + level. </member> <member name="SS" type="SpatialSound2DServer"> + Short for SpatialSoundServer. </member> <member name="SpatialSound2DServer" type="SpatialSound2DServer"> + Server that handles spatial audio positioning in 2D at low + level. </member> <member name="SS2D" type="SpatialSound2DServer"> - </member> - <member name="Flurry" type="Flurry"> + Short for SpatialSound2DServer. </member> </members> <constants> @@ -1493,16 +1555,6 @@ </constant> </constants> </class> -<class name="@MultiScript" category="Core"> - <brief_description> - </brief_description> - <description> - </description> - <methods> - </methods> - <constants> - </constants> -</class> <class name="AABB" category="Built-In Types"> <brief_description> Axis-Aligned Bounding Box. @@ -1692,6 +1744,7 @@ <member name="size" type="Vector3"> </member> <member name="end" type="Vector3"> + Same as pos+size. </member> </members> <constants> @@ -1794,92 +1847,114 @@ </class> <class name="AnimatedSprite" inherits="Node2D" category="Core"> <brief_description> + Sprite node that can use multiple textures for animation. </brief_description> <description> + Sprite node that can use multiple textures for animation. </description> <methods> <method name="set_sprite_frames" > <argument index="0" name="sprite_frames" type="SpriteFrames"> </argument> <description> + Set the [SpriteFrames] resource, which contains all + frames. </description> </method> <method name="get_sprite_frames" qualifiers="const" > <return type="SpriteFrames"> </return> <description> + Get the [SpriteFrames] resource, which contains all + frames. </description> </method> <method name="set_centered" > <argument index="0" name="centered" type="bool"> </argument> <description> + When turned on, offset at (0,0) is the center of the + sprite, when off, the top-left corner is. </description> </method> <method name="is_centered" qualifiers="const" > <return type="bool"> </return> <description> + Return true when centered. See [set_centered]. </description> </method> <method name="set_offset" > <argument index="0" name="offset" type="Vector2"> </argument> <description> + Set the offset of the sprite in the node origin. + Position varies depending on whether it is centered + or not. </description> </method> <method name="get_offset" qualifiers="const" > <return type="Vector2"> </return> <description> + Return the offset of the sprite in the node origin. </description> </method> <method name="set_flip_h" > <argument index="0" name="flip_h" type="bool"> </argument> <description> + If true, sprite is flipped horizontally. </description> </method> <method name="is_flipped_h" qualifiers="const" > <return type="bool"> </return> <description> + Return true if sprite is flipped horizontally. </description> </method> <method name="set_flip_v" > <argument index="0" name="flip_v" type="bool"> </argument> <description> + If true, sprite is flipped vertically. </description> </method> <method name="is_flipped_v" qualifiers="const" > <return type="bool"> </return> <description> + Return true if sprite is flipped vertically. </description> </method> <method name="set_frame" > <argument index="0" name="frame" type="int"> </argument> <description> + Set the visible sprite frame index (from the list of + frames inside the [SpriteFrames] resource). </description> </method> <method name="get_frame" qualifiers="const" > <return type="int"> </return> <description> + Return the visible frame index. </description> </method> <method name="set_modulate" > <argument index="0" name="modulate" type="Color"> </argument> <description> + Change the color modulation (multiplication) for this sprite. </description> </method> <method name="get_modulate" qualifiers="const" > <return type="Color"> </return> <description> + Return the color modulation for this sprite. </description> </method> </methods> @@ -2361,22 +2436,27 @@ <argument index="3" name="from_end" type="bool" default="false"> </argument> <description> + Play a given animation by the animation name. Custom + speed and blend times can be set. If custom speed is + negative (-1), 'from_end' being true can play the + animation backwards. </description> </method> <method name="stop" > <description> + Stop the currently played animation. </description> </method> <method name="stop_all" > <description> - Stop playback on all animation channels. + Stop playback of animations (deprecated). </description> </method> <method name="is_playing" qualifiers="const" > <return type="bool"> </return> <description> - Return wether an animation chanel is playing (or channel 0 if none is provided). + Return wether an animation is playing. </description> </method> <method name="set_current_animation" > @@ -2390,7 +2470,7 @@ <return type="String"> </return> <description> - Return the name of the animation being played in a channel (or channel 0 if none is provided). + Return the name of the animation being played. </description> </method> <method name="queue" > @@ -2402,13 +2482,15 @@ </method> <method name="clear_queue" > <description> + If animations are queued to play, clear them. </description> </method> <method name="set_active" > <argument index="0" name="active" type="bool"> </argument> <description> - Set the player as active (playing) + Set the player as active (playing). If false, it + will do nothing. </description> </method> <method name="is_active" qualifiers="const" > @@ -2450,12 +2532,16 @@ <argument index="0" name="path" type="NodePath"> </argument> <description> + AnimationPlayer resolves animation track paths from + this node (which is relative to itself), by + default root is "..", but it can be changed.. </description> </method> <method name="get_root" qualifiers="const" > <return type="NodePath"> </return> <description> + Return path to root node (see [set_root]). </description> </method> <method name="seek" > @@ -2464,7 +2550,10 @@ <argument index="1" name="update" type="bool" default="false"> </argument> <description> - Seek the animation in an animation channel (or channel 0 if none is provided) to a specific position (in seconds). + Seek the animation to a given position in time (in + seconds). If 'update' + is true, the animation will be updated too, + otherwise it will be updated at process time. </description> </method> <method name="get_pos" qualifiers="const" > @@ -2506,12 +2595,16 @@ <return type="real"> </return> <description> + Get the position (in seconds) of the currently being + played animation. </description> </method> <method name="get_current_animation_length" qualifiers="const" > <return type="real"> </return> <description> + Get the length (in seconds) of the currently being + played animation. </description> </method> </methods> @@ -2522,24 +2615,35 @@ <argument index="1" name="new_name" type="String"> </argument> <description> + If the currently being played animation changes, + this signal will notify of such change. </description> </signal> <signal name="finished"> <description> + Notifies when an animation finished playing. </description> </signal> </signals> <constants> <constant name="ANIMATION_PROCESS_FIXED" value="0"> + Process animation on fixed process. This is specially useful + when animating kinematic bodies. </constant> <constant name="ANIMATION_PROCESS_IDLE" value="1"> + Process animation on idle process. </constant> </constants> </class> <class name="AnimationTreePlayer" inherits="Node" category="Core"> <brief_description> + Animation Player that uses a node graph for the blending. </brief_description> <description> + Animation Player that uses a node graph for the blending. This kind + of player is very useful when animating character or other skeleton + based rigs, because it can combine several animations to form a + desired pose. </description> <methods> <method name="add_node" > @@ -2548,6 +2652,8 @@ <argument index="1" name="id" type="String"> </argument> <description> + Add a node of a given type in the graph with given + id. </description> </method> <method name="node_exists" qualifiers="const" > @@ -2556,6 +2662,7 @@ <argument index="0" name="node" type="String"> </argument> <description> + Check if a node exists (by name). </description> </method> <method name="node_rename" > @@ -2566,6 +2673,7 @@ <argument index="1" name="new_name" type="String"> </argument> <description> + Rename a node in the graph. </description> </method> <method name="node_get_type" qualifiers="const" > @@ -2574,6 +2682,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Get the node type, will return from NODE_* enum. </description> </method> <method name="node_get_input_count" qualifiers="const" > @@ -2582,6 +2691,8 @@ <argument index="0" name="id" type="String"> </argument> <description> + Return the input count for a given node. Different + types of nodes have different amount of inputs. </description> </method> <method name="node_get_input_sourcre" qualifiers="const" > @@ -2592,6 +2703,7 @@ <argument index="1" name="idx" type="int"> </argument> <description> + Return the input source for a given node input. </description> </method> <method name="animation_node_set_animation" > @@ -2600,6 +2712,7 @@ <argument index="1" name="animation" type="Animation"> </argument> <description> + Set the animation for an animation node. </description> </method> <method name="animation_node_get_animation" qualifiers="const" > @@ -4887,6 +5000,18 @@ Return true if the camera is at the center of the screen (default: true). </description> </method> + <method name="set_rotating" > + <argument index="0" name="rotating" type="bool"> + </argument> + <description> + </description> + </method> + <method name="is_rotating" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> <method name="make_current" > <description> Make this the current 2D camera for the scene (viewport and layer), in case there's many cameras in the scene. @@ -5168,18 +5293,16 @@ Set canvas item self-opacity. This does not affect the opacity of children items. </description> </method> - <method name="set_on_top" > - <argument index="0" name="on_top" type="bool"> + <method name="set_draw_behind_parent" > + <argument index="0" name="enabe" type="bool"> </argument> <description> - Set canvas item as drawing over the parent canvas item (default: true). </description> </method> - <method name="is_on_top" qualifiers="const" > + <method name="is_draw_behind_parent_enabled" qualifiers="const" > <return type="bool"> </return> <description> - Return if the canvas item is drawing over the parent canvas item (default: true). </description> </method> <method name="draw_line" > @@ -8229,6 +8352,32 @@ <constants> </constants> </class> +<class name="EditorScript" inherits="Reference" category="Core"> + <brief_description> + </brief_description> + <description> + </description> + <methods> + <method name="_run" qualifiers="virtual" > + <description> + </description> + </method> + <method name="add_root_node" > + <argument index="0" name="node" type="Object"> + </argument> + <description> + </description> + </method> + <method name="get_scene" > + <return type="Object"> + </return> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> <class name="EmptyControl" inherits="Control" category="Core"> <brief_description> </brief_description> @@ -8809,6 +8958,18 @@ <description> </description> </method> + <method name="store_pascal_string" > + <argument index="0" name="string" type="String"> + </argument> + <description> + </description> + </method> + <method name="get_pascal_string" > + <return type="String"> + </return> + <description> + </description> + </method> <method name="file_exists" qualifiers="const" > <return type="bool"> </return> @@ -9124,38 +9285,6 @@ </constant> </constants> </class> -<class name="Flurry" inherits="Object" category="Core"> - <brief_description> - </brief_description> - <description> - </description> - <methods> - <method name="log_event" > - <argument index="0" name="name" type="String"> - </argument> - <argument index="1" name="params" type="Dictionary"> - </argument> - <description> - </description> - </method> - <method name="log_timed_event" > - <argument index="0" name="name" type="String"> - </argument> - <argument index="1" name="params" type="Dictionary"> - </argument> - <description> - </description> - </method> - <method name="end_timed_event" > - <argument index="0" name="name" type="String"> - </argument> - <description> - </description> - </method> - </methods> - <constants> - </constants> -</class> <class name="FollowCamera" inherits="Camera" category="Core"> <brief_description> </brief_description> @@ -9532,6 +9661,54 @@ <constants> </constants> </class> +<class name="FuncRef" inherits="Reference" category="Core"> + <brief_description> + </brief_description> + <description> + </description> + <methods> + <method name="call_func" > + <argument index="0" name="method" type="String"> + </argument> + <argument index="1" name="arg0" type="var" default="NULL"> + </argument> + <argument index="2" name="arg1" type="var" default="NULL"> + </argument> + <argument index="3" name="arg2" type="var" default="NULL"> + </argument> + <argument index="4" name="arg3" type="var" default="NULL"> + </argument> + <argument index="5" name="arg4" type="var" default="NULL"> + </argument> + <argument index="6" name="arg5" type="var" default="NULL"> + </argument> + <argument index="7" name="arg6" type="var" default="NULL"> + </argument> + <argument index="8" name="arg7" type="var" default="NULL"> + </argument> + <argument index="9" name="arg8" type="var" default="NULL"> + </argument> + <argument index="10" name="arg9" type="var" default="NULL"> + </argument> + <description> + </description> + </method> + <method name="set_instance" > + <argument index="0" name="instance" type="Object"> + </argument> + <description> + </description> + </method> + <method name="set_function" > + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> <class name="GDNativeClass" inherits="Reference" category="Core"> <brief_description> </brief_description> @@ -10827,7 +11004,13 @@ </constant> <constant name="FORMAT_ETC" value="18"> </constant> - <constant name="FORMAT_CUSTOM" value="19"> + <constant name="FORMAT_ATC" value="19"> + </constant> + <constant name="FORMAT_ATC_ALPHA_EXPLICIT" value="20"> + </constant> + <constant name="FORMAT_ATC_ALPHA_INTERPOLATED" value="21"> + </constant> + <constant name="FORMAT_CUSTOM" value="22"> </constant> </constants> </class> @@ -11038,6 +11221,12 @@ <description> </description> </method> + <method name="get_mouse_button_mask" qualifiers="const" > + <return type="int"> + </return> + <description> + </description> + </method> <method name="set_mouse_mode" > <argument index="0" name="mode" type="int"> </argument> @@ -11595,6 +11784,26 @@ </member> <member name="ID" type="int"> </member> + <member name="index" type="int"> + </member> + <member name="x" type="real"> + </member> + <member name="y" type="real"> + </member> + <member name="pos" type="Vector2"> + </member> + <member name="relative_x" type="real"> + </member> + <member name="relative_y" type="real"> + </member> + <member name="relative_pos" type="Vector2"> + </member> + <member name="speed_x" type="real"> + </member> + <member name="speed_y" type="real"> + </member> + <member name="speed" type="Vector2"> + </member> </members> <constants> <constant name="NONE" value="0"> @@ -11651,6 +11860,16 @@ </member> <member name="ID" type="int"> </member> + <member name="index" type="int"> + </member> + <member name="x" type="real"> + </member> + <member name="y" type="real"> + </member> + <member name="pos" type="Vector2"> + </member> + <member name="pressed" type="bool"> + </member> </members> <constants> <constant name="NONE" value="0"> @@ -11847,6 +12066,130 @@ <constants> </constants> </class> +<class name="KinematicBody2D" inherits="PhysicsBody2D" category="Core"> + <brief_description> + </brief_description> + <description> + </description> + <methods> + <method name="move" > + <return type="Vector2"> + </return> + <argument index="0" name="rel_vec" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="move_to" > + <return type="Vector2"> + </return> + <argument index="0" name="position" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="can_move_to" > + <return type="bool"> + </return> + <argument index="0" name="position" type="Vector2"> + </argument> + <argument index="1" name="arg1" type="bool"> + </argument> + <description> + </description> + </method> + <method name="is_colliding" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="get_collision_pos" qualifiers="const" > + <return type="Vector2"> + </return> + <description> + </description> + </method> + <method name="get_collision_normal" qualifiers="const" > + <return type="Vector2"> + </return> + <description> + </description> + </method> + <method name="get_collider_velocity" qualifiers="const" > + <return type="Vector2"> + </return> + <description> + </description> + </method> + <method name="get_collider" qualifiers="const" > + <description> + </description> + </method> + <method name="set_collide_with_static_bodies" > + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="can_collide_with_static_bodies" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_collide_with_kinematic_bodies" > + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="can_collide_with_kinematic_bodies" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_collide_with_rigid_bodies" > + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="can_collide_with_rigid_bodies" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_collide_with_character_bodies" > + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="can_collide_with_character_bodies" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_collision_margin" > + <argument index="0" name="pixels" type="real"> + </argument> + <description> + </description> + </method> + <method name="get_collision_margin" qualifiers="const" > + <return type="real"> + </return> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> <class name="Label" inherits="Range" category="Core"> <brief_description> Control that displays formatted text. @@ -13580,16 +13923,6 @@ <constants> </constants> </class> -<class name="MultiScript" inherits="Script" category="Core"> - <brief_description> - </brief_description> - <description> - </description> - <methods> - </methods> - <constants> - </constants> -</class> <class name="Mutex" inherits="Reference" category="Core"> <brief_description> </brief_description> @@ -14433,13 +14766,6 @@ -Command Line </description> <methods> - <method name="get_mouse_pos" qualifiers="const" > - <return type="Vector2"> - </return> - <description> - Return the mouse pos. - </description> - </method> <method name="set_clipboard" > <argument index="0" name="clipboard" type="String"> </argument> @@ -14706,11 +15032,10 @@ Return true if the engine was executed with -v (verbose stdout). </description> </method> - <method name="get_mouse_button_state" qualifiers="const" > - <return type="int"> + <method name="can_use_threads" qualifiers="const" > + <return type="bool"> </return> <description> - Return the state of the mouse buttons (each button in each bit). </description> </method> <method name="dump_memory_to_file" > @@ -14775,6 +15100,32 @@ <description> </description> </method> + <method name="print_all_textures_by_size" > + <description> + </description> + </method> + <method name="native_video_play" > + <return type="int"> + </return> + <argument index="0" name="arg0" type="String"> + </argument> + <description> + </description> + </method> + <method name="native_video_is_playing" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="native_video_stop" > + <description> + </description> + </method> + <method name="native_video_pause" > + <description> + </description> + </method> </methods> <constants> <constant name="DAY_SUNDAY" value="0"> @@ -16804,6 +17155,20 @@ Intersect a given shape (RID or [Shape2D]) against the space, the intersected shapes are returned in a special result object. </description> </method> + <method name="cast_motion" > + <argument index="0" name="shape" type="RID"> + </argument> + <argument index="1" name="xform" type="Matrix32"> + </argument> + <argument index="2" name="motion" type="int"> + </argument> + <argument index="3" name="exclude" type="Array" default="Array()"> + </argument> + <argument index="4" name="umask" type="int" default="0"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> @@ -17006,19 +17371,21 @@ <description> </description> </method> - <method name="area_set_param" qualifiers="const" > + <method name="area_set_param" > <argument index="0" name="area" type="RID"> </argument> <argument index="1" name="param" type="int"> </argument> + <argument index="2" name="value" type="var"> + </argument> <description> </description> </method> - <method name="area_set_transform" qualifiers="const" > - <return type="Matrix32"> - </return> + <method name="area_set_transform" > <argument index="0" name="area" type="RID"> </argument> + <argument index="1" name="transform" type="Matrix32"> + </argument> <description> </description> </method> @@ -17103,8 +17470,6 @@ </return> <argument index="0" name="body" type="RID"> </argument> - <argument index="1" name="arg1" type="int"> - </argument> <description> </description> </method> @@ -17216,16 +17581,16 @@ <description> </description> </method> - <method name="body_set_enable_continuous_collision_detection" > + <method name="body_set_continuous_collision_detection_mode" > <argument index="0" name="body" type="RID"> </argument> - <argument index="1" name="enable" type="bool"> + <argument index="1" name="mode" type="int"> </argument> <description> </description> </method> - <method name="body_is_continuous_collision_detection_enabled" qualifiers="const" > - <return type="bool"> + <method name="body_get_continuous_collision_detection_mode" qualifiers="const" > + <return type="int"> </return> <argument index="0" name="body" type="RID"> </argument> @@ -17252,14 +17617,6 @@ <description> </description> </method> - <method name="body_static_simulate_motion" > - <argument index="0" name="body" type="RID"> - </argument> - <argument index="1" name="new_xform" type="Matrix32"> - </argument> - <description> - </description> - </method> <method name="body_set_state" > <argument index="0" name="body" type="RID"> </argument> @@ -17532,6 +17889,12 @@ </constant> <constant name="DAMPED_STRING_DAMPING" value="2"> </constant> + <constant name="CCD_MODE_DISABLED" value="0"> + </constant> + <constant name="CCD_MODE_CAST_RAY" value="1"> + </constant> + <constant name="CCD_MODE_CAST_SHAPE" value="2"> + </constant> <constant name="AREA_BODY_ADDED" value="0"> </constant> <constant name="AREA_BODY_REMOVED" value="1"> @@ -21032,18 +21395,16 @@ Return wether contact monitoring is enabled. </description> </method> - <method name="set_use_continuous_collision_detection" > - <argument index="0" name="enable" type="bool"> + <method name="set_continuous_collision_detection_mode" > + <argument index="0" name="mode" type="int"> </argument> <description> - Enable continuos collision detection. This prevents very fast-moving bodies (such as bullets) to not go through objects. </description> </method> - <method name="is_using_continuous_collision_detection" qualifiers="const" > - <return type="bool"> + <method name="get_continuous_collision_detection_mode" qualifiers="const" > + <return type="int"> </return> <description> - Return true if continuous collision detection is in use. </description> </method> <method name="set_axis_velocity" > @@ -21157,6 +21518,12 @@ <constant name="MODE_CHARACTER" value="2"> Character body, can move but not rotate. </constant> + <constant name="CCD_MODE_DISABLED" value="0"> + </constant> + <constant name="CCD_MODE_CAST_RAY" value="1"> + </constant> + <constant name="CCD_MODE_CAST_SHAPE" value="2"> + </constant> </constants> </class> <class name="Room" inherits="VisualInstance" category="Core"> @@ -22610,6 +22977,54 @@ Return the custom solver bias. No need to change this unless you really know what you are doing. </description> </method> + <method name="collide" > + <return type="bool"> + </return> + <argument index="0" name="local_xform" type="Matrix32"> + </argument> + <argument index="1" name="with_shape" type="Shape2D"> + </argument> + <argument index="2" name="shape_xform" type="Matrix32"> + </argument> + <description> + </description> + </method> + <method name="collide_with_motion" > + <return type="bool"> + </return> + <argument index="0" name="local_xform" type="Matrix32"> + </argument> + <argument index="1" name="local_motion" type="Vector2"> + </argument> + <argument index="2" name="with_shape" type="Shape2D"> + </argument> + <argument index="3" name="shape_xform" type="Matrix32"> + </argument> + <argument index="4" name="shape_motion" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="collide_and_get_contacts" > + <argument index="0" name="local_xform" type="Matrix32"> + </argument> + <argument index="1" name="with_shape" type="Shape2D"> + </argument> + <argument index="2" name="shape_xform" type="Matrix32"> + </argument> + <description> + </description> + </method> + <method name="collide_with_motion_and_get_contacts" > + <argument index="0" name="local_xform" type="Matrix32"> + </argument> + <argument index="1" name="local_motion" type="Object"> + </argument> + <argument index="2" name="with_shape" type="Shape2D"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> @@ -23694,20 +24109,6 @@ Alternatively, a constant linear or angular velocity can be set for the static body, so even if it doesn't move, it affects other bodies as if it was moving (this is useful for simulating conveyor belts or conveyor wheels). </description> <methods> - <method name="set_simulate_motion" > - <argument index="0" name="enabled" type="bool"> - </argument> - <description> - Enable or disable simulated motion mode. - </description> - </method> - <method name="is_simulating_motion" qualifiers="const" > - <return type="bool"> - </return> - <description> - Return true if simulated motion mode is enabled. - </description> - </method> <method name="set_constant_linear_velocity" > <argument index="0" name="vel" type="Vector2"> </argument> @@ -25881,6 +26282,18 @@ <description> </description> </method> + <method name="set_default_font" > + <argument index="0" name="font" type="Object"> + </argument> + <description> + </description> + </method> + <method name="get_default_font" qualifiers="const" > + <return type="Object"> + </return> + <description> + </description> + </method> <method name="get_type_list" qualifiers="const" > <return type="StringArray"> </return> @@ -26133,22 +26546,36 @@ Return the texture of the tile. </description> </method> - <method name="tile_set_offset" > + <method name="tile_set_texture_offset" > + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="texture_offset" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="tile_get_texture_offset" qualifiers="const" > + <return type="Vector2"> + </return> <argument index="0" name="id" type="int"> </argument> - <argument index="1" name="offset" type="Vector2"> + <description> + </description> + </method> + <method name="tile_set_shape_offset" > + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="shape_offset" type="Vector2"> </argument> <description> - Set the offset to draw the tile. </description> </method> - <method name="tile_get_offset" qualifiers="const" > + <method name="tile_get_shape_offset" qualifiers="const" > <return type="Vector2"> </return> <argument index="0" name="id" type="int"> </argument> <description> - Return the offset to draw the tile. </description> </method> <method name="tile_set_region" > @@ -26231,6 +26658,12 @@ Find the first tile with the given name. </description> </method> + <method name="get_tiles_ids" qualifiers="const" > + <return type="Array"> + </return> + <description> + </description> + </method> </methods> <constants> </constants> @@ -27466,6 +27899,14 @@ Returns a normalized vector to unit length. </description> </method> + <method name="reflect" > + <return type="real"> + </return> + <argument index="0" name="vec" type="Vector2"> + </argument> + <description> + </description> + </method> <method name="rotated" > <return type="Vector2"> </return> @@ -27474,6 +27915,14 @@ <description> </description> </method> + <method name="slide" > + <return type="real"> + </return> + <argument index="0" name="vec" type="Vector2"> + </argument> + <description> + </description> + </method> <method name="snapped" > <return type="Vector2"> </return> @@ -28077,6 +28526,24 @@ <description> </description> </method> + <method name="set_render_target_update_mode" > + <argument index="0" name="mode" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_render_target_update_mode" qualifiers="const" > + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_render_target_texture" qualifiers="const" > + <return type="RenderTargetTexture"> + </return> + <description> + </description> + </method> <method name="get_viewport" qualifiers="const" > <return type="RID"> </return> @@ -28088,6 +28555,30 @@ <description> </description> </method> + <method name="set_as_audio_listener" > + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="is_audio_listener" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="set_as_audio_listener_2d" > + <argument index="0" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="is_audio_listener_2d" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> </methods> <signals> <signal name="size_changed"> @@ -28096,6 +28587,14 @@ </signal> </signals> <constants> + <constant name="RENDER_TARGET_UPDATE_DISABLED" value="0"> + </constant> + <constant name="RENDER_TARGET_UPDATE_ONCE" value="1"> + </constant> + <constant name="RENDER_TARGET_UPDATE_WHEN_VISIBLE" value="2"> + </constant> + <constant name="RENDER_TARGET_UPDATE_ALWAYS" value="3"> + </constant> </constants> </class> <class name="VisibilityEnabler" inherits="VisibilityNotifier" category="Core"> @@ -30133,7 +30632,15 @@ <method name="open" > <return type="int"> </return> - <argument index="0" name="arg0" type="String"> + <argument index="0" name="file" type="String"> + </argument> + <description> + </description> + </method> + <method name="open_buffer" > + <return type="int"> + </return> + <argument index="0" name="buffer" type="RawArray"> </argument> <description> </description> diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index f763a60abb..3ffebd4703 100644 --- a/drivers/gles1/rasterizer_gles1.cpp +++ b/drivers/gles1/rasterizer_gles1.cpp @@ -4602,6 +4602,12 @@ void RasterizerGLES1::canvas_begin() { } + +void RasterizerGLES1::canvas_disable_blending() { + + glDisable(GL_BLEND); +} + void RasterizerGLES1::canvas_set_opacity(float p_opacity) { canvas_opacity = p_opacity; diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h index a20477eced..e7e3200bbc 100644 --- a/drivers/gles1/rasterizer_gles1.h +++ b/drivers/gles1/rasterizer_gles1.h @@ -1126,6 +1126,7 @@ public: /* CANVAS API */ virtual void canvas_begin(); + virtual void canvas_disable_blending(); virtual void canvas_set_opacity(float p_opacity); virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode); virtual void canvas_begin_rect(const Matrix32& p_transform); diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 20505875ea..7d732f1968 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -6302,6 +6302,12 @@ void RasterizerGLES2::canvas_begin() { } + +void RasterizerGLES2::canvas_disable_blending() { + + glDisable(GL_BLEND); +} + void RasterizerGLES2::canvas_set_opacity(float p_opacity) { canvas_opacity = p_opacity; diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index ce6ba1770c..f18bdd1ff7 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1373,6 +1373,8 @@ public: /* CANVAS API */ virtual void canvas_begin(); + virtual void canvas_disable_blending(); + virtual void canvas_set_opacity(float p_opacity); virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode); virtual void canvas_begin_rect(const Matrix32& p_transform); diff --git a/drivers/openssl/stream_peer_ssl.cpp b/drivers/openssl/stream_peer_ssl.cpp index aaedd7dde9..19a17ea0cd 100644 --- a/drivers/openssl/stream_peer_ssl.cpp +++ b/drivers/openssl/stream_peer_ssl.cpp @@ -1,111 +1,97 @@ #include "stream_peer_ssl.h" -int StreamPeerSSL::bio_create( BIO *b ) { - b->init = 1; - b->num = 0; - b->ptr = NULL; - b->flags = 0; - return 1; -} - -int StreamPeerSSL::bio_destroy( BIO *b ) { - - if ( b == NULL ) return 0; - b->ptr = NULL; /* sb_tls_remove() will free it */ - b->init = 0; - b->flags = 0; - return 1; -} - -int StreamPeerSSL::bio_read( BIO *b, char *buf, int len ) { - - if ( buf == NULL || len <= 0 ) return 0; - - StreamPeerSSL * sp = (StreamPeerSSL*)b->ptr; +Error StreamPeerSSL::connect(const String &p_host,int p_port,int p_flags) { - if (sp->base.is_null()) - return 0; - - - - BIO_clear_retry_flags( b ); - - Error err; - int ret=0; - if (sp->block) { - err = sp->base->get_data((const uint8_t*)buf,len); - if (err==OK) - ret=len; - } else { - - err = sp->base->get_partial_data((const uint8_t*)buf,len,ret); - if (err==OK && ret!=len) { - BIO_set_retry_write( b ); - } + // Set up a SSL_CTX object, which will tell our BIO object how to do its work + ctx = SSL_CTX_new(SSLv23_client_method()); + // Create our BIO object for SSL connections. + BIO* bio = BIO_new_ssl_connect(ctx); + // Failure? + if (bio == NULL) { + // We need to free up the SSL_CTX before we leave. + ERR_FAIL_COND_V(bio==NULL,ERR_CANT_CREATE); + } + // Makes ssl point to bio's SSL object. + BIO_get_ssl(bio, &ssl); + // Set the SSL to automatically retry on failure. + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + // We're connection to google.com on port 443. + BIO_set_conn_hostname(bio, (p_host+":"+itos(p_port)).utf8().get_data()); + + // Same as before, try to connect. + if (BIO_do_connect(bio) <= 0) { + + ERR_EXPLAIN("Failed to connect to '"+p_host+"'' port "+itos(p_port)); + BIO_free_all(bio); + SSL_CTX_free(ctx); + ERR_FAIL_V(ERR_CANT_CONNECT); } - return ret; -} - -int StreamPeerSSL::bio_write( BIO *b, const char *buf, int len ) { - - if ( buf == NULL || len <= 0 ) return 0; - - StreamPeerSSL * sp = (StreamPeerSSL*)b->ptr; - - if (sp->base.is_null()) - return 0; - - BIO_clear_retry_flags( b ); + // Now we need to do the SSL handshake, so we can communicate. + if (BIO_do_handshake(bio) <= 0) { + ERR_EXPLAIN("Failed to handshake to '"+p_host+"'' port "+itos(p_port)); + BIO_free_all(bio); + SSL_CTX_free(ctx); + ERR_FAIL_V(ERR_CANT_CONNECT); + } - Error err; - int wrote=0; - if (sp->block) { - err = sp->base->put_data((const uint8_t*)buf,len); - if (err==OK) - wrote=len; - } else { - err = sp->base->put_partial_data((const uint8_t*)buf,len,wrote); - if (err==OK && wrote!=len) { - BIO_set_retry_write( b ); + // Create a buffer for grabbing information from the page. + char buf[1024]; + memset(buf, 0, sizeof(buf)); + // Create a buffer for the reqest we'll send to the server + char send[1024]; + memset(send, 0, sizeof(send)); + // Create our GET request. + strcat(send, "GET / HTTP/1.1\nHost:google.com\nUser Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\nConnection: Close\n\n"); + // BIO_puts sends a null-terminated string to the server. In this case it's our GET request. + BIO_puts(bio, send); + // Loop while there's information to be read. + while (1) { + // BIO_read() reads data from the server into a buffer. It returns the number of characters read in. + int x = BIO_read(bio, buf, sizeof(buf) - 1); + // If we haven't read in anything, assume there's nothing more to be sent since we used Connection: Close. + if (x == 0) { + break; + } + // If BIO_read() returns a negative number, there was an error + else if (x < 0) { + // BIO_should_retry lets us know if we should keep trying to read data or not. + if (!BIO_should_retry(bio)) { + printf("\nRead Failed!\n"); + BIO_free_all(bio); + SSL_CTX_free(ctx); + return; + } + } + // We actually got some data, without errors! + else { + // Null-terminate our buffer, just in case + buf[x] = 0; + // Echo what the server sent to the screen + printf("%s", buf); } - } + // Free up that BIO object we created. + BIO_free_all(bio); + // Remember, we also need to free up that SSL_CTX object! + SSL_CTX_free(ctx); + // Return. - return wrote; } -long StreamPeerSSL::bio_ctrl( BIO *b, int cmd, long num, void *ptr ) { - if ( cmd == BIO_CTRL_FLUSH ) { - /* The OpenSSL library needs this */ - return 1; - } - return 0; -} +void StreamPeerSSL::initialize_ssl() { -int StreamPeerSSL::bio_gets( BIO *b, char *buf, int len ) { - return -1; + CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use + SSL_library_init(); // Initialize OpenSSL's SSL libraries + SSL_load_error_strings(); // Load SSL error strings + ERR_load_BIO_strings(); // Load BIO error strings + OpenSSL_add_all_algorithms(); // Load all available encryption algorithms } -int StreamPeerSSL::bio_puts( BIO *b, const char *str ) { - return StreamPeerSSL::bio_write( b, str, strlen( str ) ); -} +void StreamPeerSSL::finalize_ssl(){ -BIO_METHOD StreamPeerSSL::bio_methods = -{ - ( 100 | 0x400 ), /* it's a source/sink BIO */ - "sockbuf glue", - StreamPeerSSL::bio_write, - StreamPeerSSL::bio_read, - StreamPeerSSL::bio_puts, - StreamPeerSSL::bio_gets, - StreamPeerSSL::bio_ctrl, - StreamPeerSSL::bio_create, - StreamPeerSSL::bio_destroy -}; -StreamPeerSSL::StreamPeerSSL() { } diff --git a/drivers/openssl/stream_peer_ssl.h b/drivers/openssl/stream_peer_ssl.h index a126f6122c..74866c2da4 100644 --- a/drivers/openssl/stream_peer_ssl.h +++ b/drivers/openssl/stream_peer_ssl.h @@ -1,26 +1,43 @@ #ifndef STREAM_PEER_SSL_H #define STREAM_PEER_SSL_H +#ifdef OPENSSL_ENABLED + #include "io/stream_peer.h" +#include <openssl/applink.c> // To prevent crashing (see the OpenSSL FAQ) +#include <openssl/bio.h> // BIO objects for I/O +#include <openssl/ssl.h> // SSL and SSL_CTX for SSL connections +#include <openssl/err.h> // Error reporting +#include <stdio.h> // If you don't know what this is for stop reading now. class StreamPeerSSL : public StreamPeer { OBJ_TYPE(StreamPeerSSL,StreamPeer); +public: + + enum ConnectFlags { + + CONNECT_FLAG_BUG_WORKAROUNDS=1, + CONNECT_FLAG_NO_SSLV2=2, + CONNECT_FLAG_NO_SSLV3=4, + CONNECT_FLAG_NO_TLSV1=8, + CONNECT_FLAG_NO_COMPRESSION=16, + }; - Ref<StreamPeer> base; - bool block; - static BIO_METHOD bio_methods; + SSL_CTX* ctx; + SSL* ssl; + BIO* bio; - static int bio_create( BIO *b ); - static int bio_destroy( BIO *b ); - static int bio_read( BIO *b, char *buf, int len ); - static int bio_write( BIO *b, const char *buf, int len ); - static long bio_ctrl( BIO *b, int cmd, long num, void *ptr ); - static int bio_gets( BIO *b, char *buf, int len ); - static int bio_puts( BIO *b, const char *str ); public: + + + Error connect(const String &p_host,int p_port); + static void initialize_ssl(); + static void finalize_ssl(); + StreamPeerSSL(); }; +#endif #endif // STREAM_PEER_SSL_H diff --git a/main/main.cpp b/main/main.cpp index 19dbbe5203..0d9e94346e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1008,11 +1008,25 @@ bool Main::start() { if (!editor) { //standard helpers that can be changed from main config - if (GLOBAL_DEF("display/stretch_2d",false).operator bool()) { - - sml->get_root()->set_size_override(true,Size2(Globals::get_singleton()->get("display/width"),Globals::get_singleton()->get("display/height"))); - sml->get_root()->set_size_override_stretch(true); - } + String stretch_mode = GLOBAL_DEF("display/stretch_mode","disabled"); + String stretch_aspect = GLOBAL_DEF("display/stretch_aspect","ignore"); + Size2i stretch_size = Size2(GLOBAL_DEF("display/width",0),GLOBAL_DEF("display/height",0)); + + SceneMainLoop::StretchMode sml_sm=SceneMainLoop::STRETCH_MODE_DISABLED; + if (stretch_mode=="2d") + sml_sm=SceneMainLoop::STRETCH_MODE_2D; + else if (stretch_mode=="viewport") + sml_sm=SceneMainLoop::STRETCH_MODE_VIEWPORT; + + SceneMainLoop::StretchAspect sml_aspect=SceneMainLoop::STRETCH_ASPECT_IGNORE; + if (stretch_aspect=="keep") + sml_aspect=SceneMainLoop::STRETCH_ASPECT_KEEP; + else if (stretch_aspect=="keep_width") + sml_aspect=SceneMainLoop::STRETCH_ASPECT_KEEP_WIDTH; + else if (stretch_aspect=="keep_height") + sml_aspect=SceneMainLoop::STRETCH_ASPECT_KEEP_HEIGHT; + + sml->set_screen_stretch(sml_sm,sml_aspect,stretch_size); sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true)); String appname = Globals::get_singleton()->get("application/name"); @@ -1021,7 +1035,10 @@ bool Main::start() { } else { - GLOBAL_DEF("display/stretch_2d",false); + GLOBAL_DEF("display/stretch_mode","disabled"); + Globals::get_singleton()->set_custom_property_info("display/stretch_mode",PropertyInfo(Variant::STRING,"display/stretch_mode",PROPERTY_HINT_ENUM,"disabled,2d,viewport")); + GLOBAL_DEF("display/stretch_aspect","ignore"); + Globals::get_singleton()->set_custom_property_info("display/stretch_aspect",PropertyInfo(Variant::STRING,"display/stretch_aspect",PROPERTY_HINT_ENUM,"ignore,keep,keep_width,keep_height")); sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true)); diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template index 99c3650efa..e723b693d8 100644 --- a/platform/android/AndroidManifest.xml.template +++ b/platform/android/AndroidManifest.xml.template @@ -5,6 +5,11 @@ android:versionName="1.0" android:installLocation="preferExternal" > +<supports-screens android:smallScreens="true" + android:normalScreens="true" + android:largeScreens="true" + android:xlargeScreens="true"/> + <application android:label="@string/godot_project_name_string" android:icon="@drawable/icon"> <activity android:name="com.android.godot.Godot" android:label="@string/godot_project_name_string" @@ -26,15 +31,173 @@ $$ADD_APPLICATION_CHUNKS$$ </application> <uses-feature android:glEsVersion="0x00020000"/> - <uses-permission android:name="android.permission.INTERNET"></uses-permission> - <uses-permission android:name="android.permission.READ_CONTACTS"/> - <uses-permission android:name="com.android.vending.BILLING" /> - <uses-permission android:name="android.permission.READ_PHONE_STATE"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission android:name="android.permission.RECEIVE_SMS"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - - <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="15"/> +<uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/> +<uses-permission android:name="godot.ACCESS_COARSE_LOCATION"/> +<uses-permission android:name="godot.ACCESS_FINE_LOCATION"/> +<uses-permission android:name="godot.ACCESS_LOCATION_EXTRA_COMMANDS"/> +<uses-permission android:name="godot.ACCESS_MOCK_LOCATION"/> +<uses-permission android:name="godot.ACCESS_NETWORK_STATE"/> +<uses-permission android:name="godot.ACCESS_SURFACE_FLINGER"/> +<uses-permission android:name="godot.ACCESS_WIFI_STATE"/> +<uses-permission android:name="godot.ACCOUNT_MANAGER"/> +<uses-permission android:name="godot.ADD_VOICEMAIL"/> +<uses-permission android:name="godot.AUTHENTICATE_ACCOUNTS"/> +<uses-permission android:name="godot.BATTERY_STATS"/> +<uses-permission android:name="godot.BIND_ACCESSIBILITY_SERVICE"/> +<uses-permission android:name="godot.BIND_APPWIDGET"/> +<uses-permission android:name="godot.BIND_DEVICE_ADMIN"/> +<uses-permission android:name="godot.BIND_INPUT_METHOD"/> +<uses-permission android:name="godot.BIND_NFC_SERVICE"/> +<uses-permission android:name="godot.BIND_NOTIFICATION_LISTENER_SERVICE"/> +<uses-permission android:name="godot.BIND_PRINT_SERVICE"/> +<uses-permission android:name="godot.BIND_REMOTEVIEWS"/> +<uses-permission android:name="godot.BIND_TEXT_SERVICE"/> +<uses-permission android:name="godot.BIND_VPN_SERVICE"/> +<uses-permission android:name="godot.BIND_WALLPAPER"/> +<uses-permission android:name="godot.BLUETOOTH"/> +<uses-permission android:name="godot.BLUETOOTH_ADMIN"/> +<uses-permission android:name="godot.BLUETOOTH_PRIVILEGED"/> +<uses-permission android:name="godot.BRICK"/> +<uses-permission android:name="godot.BROADCAST_PACKAGE_REMOVED"/> +<uses-permission android:name="godot.BROADCAST_SMS"/> +<uses-permission android:name="godot.BROADCAST_STICKY"/> +<uses-permission android:name="godot.BROADCAST_WAP_PUSH"/> +<uses-permission android:name="godot.CALL_PHONE"/> +<uses-permission android:name="godot.CALL_PRIVILEGED"/> +<uses-permission android:name="godot.CAMERA"/> +<uses-permission android:name="godot.CAPTURE_AUDIO_OUTPUT"/> +<uses-permission android:name="godot.CAPTURE_SECURE_VIDEO_OUTPUT"/> +<uses-permission android:name="godot.CAPTURE_VIDEO_OUTPUT"/> +<uses-permission android:name="godot.CHANGE_COMPONENT_ENABLED_STATE"/> +<uses-permission android:name="godot.CHANGE_CONFIGURATION"/> +<uses-permission android:name="godot.CHANGE_NETWORK_STATE"/> +<uses-permission android:name="godot.CHANGE_WIFI_MULTICAST_STATE"/> +<uses-permission android:name="godot.CHANGE_WIFI_STATE"/> +<uses-permission android:name="godot.CLEAR_APP_CACHE"/> +<uses-permission android:name="godot.CLEAR_APP_USER_DATA"/> +<uses-permission android:name="godot.CONTROL_LOCATION_UPDATES"/> +<uses-permission android:name="godot.DELETE_CACHE_FILES"/> +<uses-permission android:name="godot.DELETE_PACKAGES"/> +<uses-permission android:name="godot.DEVICE_POWER"/> +<uses-permission android:name="godot.DIAGNOSTIC"/> +<uses-permission android:name="godot.DISABLE_KEYGUARD"/> +<uses-permission android:name="godot.DUMP"/> +<uses-permission android:name="godot.EXPAND_STATUS_BAR"/> +<uses-permission android:name="godot.FACTORY_TEST"/> +<uses-permission android:name="godot.FLASHLIGHT"/> +<uses-permission android:name="godot.FORCE_BACK"/> +<uses-permission android:name="godot.GET_ACCOUNTS"/> +<uses-permission android:name="godot.GET_PACKAGE_SIZE"/> +<uses-permission android:name="godot.GET_TASKS"/> +<uses-permission android:name="godot.GET_TOP_ACTIVITY_INFO"/> +<uses-permission android:name="godot.GLOBAL_SEARCH"/> +<uses-permission android:name="godot.HARDWARE_TEST"/> +<uses-permission android:name="godot.INJECT_EVENTS"/> +<uses-permission android:name="godot.INSTALL_LOCATION_PROVIDER"/> +<uses-permission android:name="godot.INSTALL_PACKAGES"/> +<uses-permission android:name="godot.INSTALL_SHORTCUT"/> +<uses-permission android:name="godot.INTERNAL_SYSTEM_WINDOW"/> +<uses-permission android:name="godot.INTERNET"/> +<uses-permission android:name="godot.KILL_BACKGROUND_PROCESSES"/> +<uses-permission android:name="godot.LOCATION_HARDWARE"/> +<uses-permission android:name="godot.MANAGE_ACCOUNTS"/> +<uses-permission android:name="godot.MANAGE_APP_TOKENS"/> +<uses-permission android:name="godot.MANAGE_DOCUMENTS"/> +<uses-permission android:name="godot.MASTER_CLEAR"/> +<uses-permission android:name="godot.MEDIA_CONTENT_CONTROL"/> +<uses-permission android:name="godot.MODIFY_AUDIO_SETTINGS"/> +<uses-permission android:name="godot.MODIFY_PHONE_STATE"/> +<uses-permission android:name="godot.MOUNT_FORMAT_FILESYSTEMS"/> +<uses-permission android:name="godot.MOUNT_UNMOUNT_FILESYSTEMS"/> +<uses-permission android:name="godot.NFC"/> +<uses-permission android:name="godot.PERSISTENT_ACTIVITY"/> +<uses-permission android:name="godot.PROCESS_OUTGOING_CALLS"/> +<uses-permission android:name="godot.READ_CALENDAR"/> +<uses-permission android:name="godot.READ_CALL_LOG"/> +<uses-permission android:name="godot.READ_CONTACTS"/> +<uses-permission android:name="godot.READ_EXTERNAL_STORAGE"/> +<uses-permission android:name="godot.READ_FRAME_BUFFER"/> +<uses-permission android:name="godot.READ_HISTORY_BOOKMARKS"/> +<uses-permission android:name="godot.READ_INPUT_STATE"/> +<uses-permission android:name="godot.READ_LOGS"/> +<uses-permission android:name="godot.READ_PHONE_STATE"/> +<uses-permission android:name="godot.READ_PROFILE"/> +<uses-permission android:name="godot.READ_SMS"/> +<uses-permission android:name="godot.READ_SOCIAL_STREAM"/> +<uses-permission android:name="godot.READ_SYNC_SETTINGS"/> +<uses-permission android:name="godot.READ_SYNC_STATS"/> +<uses-permission android:name="godot.READ_USER_DICTIONARY"/> +<uses-permission android:name="godot.REBOOT"/> +<uses-permission android:name="godot.RECEIVE_BOOT_COMPLETED"/> +<uses-permission android:name="godot.RECEIVE_MMS"/> +<uses-permission android:name="godot.RECEIVE_SMS"/> +<uses-permission android:name="godot.RECEIVE_WAP_PUSH"/> +<uses-permission android:name="godot.RECORD_AUDIO"/> +<uses-permission android:name="godot.REORDER_TASKS"/> +<uses-permission android:name="godot.RESTART_PACKAGES"/> +<uses-permission android:name="godot.SEND_RESPOND_VIA_MESSAGE"/> +<uses-permission android:name="godot.SEND_SMS"/> +<uses-permission android:name="godot.SET_ACTIVITY_WATCHER"/> +<uses-permission android:name="godot.SET_ALARM"/> +<uses-permission android:name="godot.SET_ALWAYS_FINISH"/> +<uses-permission android:name="godot.SET_ANIMATION_SCALE"/> +<uses-permission android:name="godot.SET_DEBUG_APP"/> +<uses-permission android:name="godot.SET_ORIENTATION"/> +<uses-permission android:name="godot.SET_POINTER_SPEED"/> +<uses-permission android:name="godot.SET_PREFERRED_APPLICATIONS"/> +<uses-permission android:name="godot.SET_PROCESS_LIMIT"/> +<uses-permission android:name="godot.SET_TIME"/> +<uses-permission android:name="godot.SET_TIME_ZONE"/> +<uses-permission android:name="godot.SET_WALLPAPER"/> +<uses-permission android:name="godot.SET_WALLPAPER_HINTS"/> +<uses-permission android:name="godot.SIGNAL_PERSISTENT_PROCESSES"/> +<uses-permission android:name="godot.STATUS_BAR"/> +<uses-permission android:name="godot.SUBSCRIBED_FEEDS_READ"/> +<uses-permission android:name="godot.SUBSCRIBED_FEEDS_WRITE"/> +<uses-permission android:name="godot.SYSTEM_ALERT_WINDOW"/> +<uses-permission android:name="godot.TRANSMIT_IR"/> +<uses-permission android:name="godot.UNINSTALL_SHORTCUT"/> +<uses-permission android:name="godot.UPDATE_DEVICE_STATS"/> +<uses-permission android:name="godot.USE_CREDENTIALS"/> +<uses-permission android:name="godot.USE_SIP"/> +<uses-permission android:name="godot.VIBRATE"/> +<uses-permission android:name="godot.WAKE_LOCK"/> +<uses-permission android:name="godot.WRITE_APN_SETTINGS"/> +<uses-permission android:name="godot.WRITE_CALENDAR"/> +<uses-permission android:name="godot.WRITE_CALL_LOG"/> +<uses-permission android:name="godot.WRITE_CONTACTS"/> +<uses-permission android:name="godot.WRITE_EXTERNAL_STORAGE"/> +<uses-permission android:name="godot.WRITE_GSERVICES"/> +<uses-permission android:name="godot.WRITE_HISTORY_BOOKMARKS"/> +<uses-permission android:name="godot.WRITE_PROFILE"/> +<uses-permission android:name="godot.WRITE_SECURE_SETTINGS"/> +<uses-permission android:name="godot.WRITE_SETTINGS"/> +<uses-permission android:name="godot.WRITE_SMS"/> +<uses-permission android:name="godot.WRITE_SOCIAL_STREAM"/> +<uses-permission android:name="godot.WRITE_SYNC_SETTINGS"/> +<uses-permission android:name="godot.WRITE_USER_DICTIONARY"/> +<uses-permission android:name="godot.custom.0"/> +<uses-permission android:name="godot.custom.1"/> +<uses-permission android:name="godot.custom.2"/> +<uses-permission android:name="godot.custom.3"/> +<uses-permission android:name="godot.custom.4"/> +<uses-permission android:name="godot.custom.5"/> +<uses-permission android:name="godot.custom.6"/> +<uses-permission android:name="godot.custom.7"/> +<uses-permission android:name="godot.custom.8"/> +<uses-permission android:name="godot.custom.9"/> +<uses-permission android:name="godot.custom.0"/> +<uses-permission android:name="godot.custom.11"/> +<uses-permission android:name="godot.custom.12"/> +<uses-permission android:name="godot.custom.13"/> +<uses-permission android:name="godot.custom.14"/> +<uses-permission android:name="godot.custom.15"/> +<uses-permission android:name="godot.custom.16"/> +<uses-permission android:name="godot.custom.17"/> +<uses-permission android:name="godot.custom.18"/> +<uses-permission android:name="godot.custom.19"/> + +<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="15"/> </manifest> diff --git a/platform/android/detect.py b/platform/android/detect.py index 17e97fae0f..72a16ab59a 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -57,6 +57,7 @@ def configure(env): env['SPAWN'] = methods.win32_spawn env.android_source_modules.append("../libs/apk_expansion") + env.android_source_modules.append("../libs/google_play_services") ndk_platform="" ndk_platform="android-15" diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index a9b96a116b..51db77595b 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -10,10 +10,169 @@ #include "os/os.h" #include "platform/android/logo.h" + +static const char* android_perms[]={ +"ACCESS_CHECKIN_PROPERTIES", +"ACCESS_COARSE_LOCATION", +"ACCESS_FINE_LOCATION", +"ACCESS_LOCATION_EXTRA_COMMANDS", +"ACCESS_MOCK_LOCATION", +"ACCESS_NETWORK_STATE", +"ACCESS_SURFACE_FLINGER", +"ACCESS_WIFI_STATE", +"ACCOUNT_MANAGER", +"ADD_VOICEMAIL", +"AUTHENTICATE_ACCOUNTS", +"BATTERY_STATS", +"BIND_ACCESSIBILITY_SERVICE", +"BIND_APPWIDGET", +"BIND_DEVICE_ADMIN", +"BIND_INPUT_METHOD", +"BIND_NFC_SERVICE", +"BIND_NOTIFICATION_LISTENER_SERVICE", +"BIND_PRINT_SERVICE", +"BIND_REMOTEVIEWS", +"BIND_TEXT_SERVICE", +"BIND_VPN_SERVICE", +"BIND_WALLPAPER", +"BLUETOOTH", +"BLUETOOTH_ADMIN", +"BLUETOOTH_PRIVILEGED", +"BRICK", +"BROADCAST_PACKAGE_REMOVED", +"BROADCAST_SMS", +"BROADCAST_STICKY", +"BROADCAST_WAP_PUSH", +"CALL_PHONE", +"CALL_PRIVILEGED", +"CAMERA", +"CAPTURE_AUDIO_OUTPUT", +"CAPTURE_SECURE_VIDEO_OUTPUT", +"CAPTURE_VIDEO_OUTPUT", +"CHANGE_COMPONENT_ENABLED_STATE", +"CHANGE_CONFIGURATION", +"CHANGE_NETWORK_STATE", +"CHANGE_WIFI_MULTICAST_STATE", +"CHANGE_WIFI_STATE", +"CLEAR_APP_CACHE", +"CLEAR_APP_USER_DATA", +"CONTROL_LOCATION_UPDATES", +"DELETE_CACHE_FILES", +"DELETE_PACKAGES", +"DEVICE_POWER", +"DIAGNOSTIC", +"DISABLE_KEYGUARD", +"DUMP", +"EXPAND_STATUS_BAR", +"FACTORY_TEST", +"FLASHLIGHT", +"FORCE_BACK", +"GET_ACCOUNTS", +"GET_PACKAGE_SIZE", +"GET_TASKS", +"GET_TOP_ACTIVITY_INFO", +"GLOBAL_SEARCH", +"HARDWARE_TEST", +"INJECT_EVENTS", +"INSTALL_LOCATION_PROVIDER", +"INSTALL_PACKAGES", +"INSTALL_SHORTCUT", +"INTERNAL_SYSTEM_WINDOW", +"INTERNET", +"KILL_BACKGROUND_PROCESSES", +"LOCATION_HARDWARE", +"MANAGE_ACCOUNTS", +"MANAGE_APP_TOKENS", +"MANAGE_DOCUMENTS", +"MASTER_CLEAR", +"MEDIA_CONTENT_CONTROL", +"MODIFY_AUDIO_SETTINGS", +"MODIFY_PHONE_STATE", +"MOUNT_FORMAT_FILESYSTEMS", +"MOUNT_UNMOUNT_FILESYSTEMS", +"NFC", +"PERSISTENT_ACTIVITY", +"PROCESS_OUTGOING_CALLS", +"READ_CALENDAR", +"READ_CALL_LOG", +"READ_CONTACTS", +"READ_EXTERNAL_STORAGE", +"READ_FRAME_BUFFER", +"READ_HISTORY_BOOKMARKS", +"READ_INPUT_STATE", +"READ_LOGS", +"READ_PHONE_STATE", +"READ_PROFILE", +"READ_SMS", +"READ_SOCIAL_STREAM", +"READ_SYNC_SETTINGS", +"READ_SYNC_STATS", +"READ_USER_DICTIONARY", +"REBOOT", +"RECEIVE_BOOT_COMPLETED", +"RECEIVE_MMS", +"RECEIVE_SMS", +"RECEIVE_WAP_PUSH", +"RECORD_AUDIO", +"REORDER_TASKS", +"RESTART_PACKAGES", +"SEND_RESPOND_VIA_MESSAGE", +"SEND_SMS", +"SET_ACTIVITY_WATCHER", +"SET_ALARM", +"SET_ALWAYS_FINISH", +"SET_ANIMATION_SCALE", +"SET_DEBUG_APP", +"SET_ORIENTATION", +"SET_POINTER_SPEED", +"SET_PREFERRED_APPLICATIONS", +"SET_PROCESS_LIMIT", +"SET_TIME", +"SET_TIME_ZONE", +"SET_WALLPAPER", +"SET_WALLPAPER_HINTS", +"SIGNAL_PERSISTENT_PROCESSES", +"STATUS_BAR", +"SUBSCRIBED_FEEDS_READ", +"SUBSCRIBED_FEEDS_WRITE", +"SYSTEM_ALERT_WINDOW", +"TRANSMIT_IR", +"UNINSTALL_SHORTCUT", +"UPDATE_DEVICE_STATS", +"USE_CREDENTIALS", +"USE_SIP", +"VIBRATE", +"WAKE_LOCK", +"WRITE_APN_SETTINGS", +"WRITE_CALENDAR", +"WRITE_CALL_LOG", +"WRITE_CONTACTS", +"WRITE_EXTERNAL_STORAGE", +"WRITE_GSERVICES", +"WRITE_HISTORY_BOOKMARKS", +"WRITE_PROFILE", +"WRITE_SECURE_SETTINGS", +"WRITE_SETTINGS", +"WRITE_SMS", +"WRITE_SOCIAL_STREAM", +"WRITE_SYNC_SETTINGS", +"WRITE_USER_DICTIONARY", +NULL}; + class EditorExportPlatformAndroid : public EditorExportPlatform { OBJ_TYPE( EditorExportPlatformAndroid,EditorExportPlatform ); + + enum { + MAX_USER_PERMISSIONS=20, + SCREEN_SMALL=0, + SCREEN_NORMAL=1, + SCREEN_LARGE=2, + SCREEN_XLARGE=3, + SCREEN_MAX=4 + }; + String custom_release_package; String custom_debug_package; @@ -47,6 +206,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { Thread *device_thread; Ref<ImageTexture> logo; + Set<String> perms; + String user_perms[MAX_USER_PERMISSIONS]; + bool screen_support[SCREEN_MAX]; + volatile bool quit_request; @@ -104,11 +267,33 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& _signed=p_value; else if (n=="screen/orientation") orientation=p_value; + else if (n=="screen/support_small") + screen_support[SCREEN_SMALL]=p_value; + else if (n=="screen/support_normal") + screen_support[SCREEN_NORMAL]=p_value; + else if (n=="screen/support_large") + screen_support[SCREEN_LARGE]=p_value; + else if (n=="screen/support_xlarge") + screen_support[SCREEN_XLARGE]=p_value; else if (n=="keystore/release") release_keystore=p_value; else if (n=="keystore/release_user") release_username=p_value; - else + else if (n.begins_with("permissions/")) { + + String what = n.get_slice("/",1).to_upper(); + bool state = p_value; + if (state) + perms.insert(what); + else + perms.erase(what); + } else if (n.begins_with("user_permissions/")) { + + int which = n.get_slice("/",1).to_int(); + ERR_FAIL_INDEX_V(which,MAX_USER_PERMISSIONS,false); + user_perms[which]=p_value; + + } else return false; return true; @@ -132,15 +317,33 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) r_ret=_signed; else if (n=="screen/orientation") r_ret=orientation; + else if (n=="screen/support_small") + r_ret=screen_support[SCREEN_SMALL]; + else if (n=="screen/support_normal") + r_ret=screen_support[SCREEN_NORMAL]; + else if (n=="screen/support_large") + r_ret=screen_support[SCREEN_LARGE]; + else if (n=="screen/support_xlarge") + r_ret=screen_support[SCREEN_XLARGE]; else if (n=="keystore/release") r_ret=release_keystore; else if (n=="keystore/release_user") r_ret=release_username; - else + else if (n.begins_with("permissions/")) { + + String what = n.get_slice("/",1).to_upper(); + r_ret = perms.has(what); + } else if (n.begins_with("user_permissions/")) { + + int which = n.get_slice("/",1).to_int(); + ERR_FAIL_INDEX_V(which,MAX_USER_PERMISSIONS,false); + r_ret=user_perms[which]; + } else return false; return true; } + void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list) const{ p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_FILE,"apk")); @@ -152,9 +355,25 @@ void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") ); p_list->push_back( PropertyInfo( Variant::BOOL, "package/signed") ); p_list->push_back( PropertyInfo( Variant::INT, "screen/orientation",PROPERTY_HINT_ENUM,"Landscape,Portrait") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_small") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_normal") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_large") ); + p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_xlarge") ); p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release",PROPERTY_HINT_FILE,"keystore") ); p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release_user" ) ); + const char **perms = android_perms; + while(*perms) { + + p_list->push_back( PropertyInfo( Variant::BOOL, "permissions/"+String(*perms).to_lower())); + perms++; + } + + for(int i=0;i<MAX_USER_PERMISSIONS;i++) { + + p_list->push_back( PropertyInfo( Variant::STRING, "user_permissions/"+itos(i))); + } + //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)")); } @@ -536,6 +755,53 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) { } } + if (tname=="uses-permission" && /*nspace=="android" &&*/ attrname=="name") { + + if (value.begins_with("godot.custom")) { + + int which = value.get_slice(".",2).to_int(); + if (which>=0 && which<MAX_USER_PERMISSIONS && user_perms[which].strip_edges()!="") { + + string_table[attr_value]=user_perms[which].strip_edges(); + } + + } else if (value.begins_with("godot.")) { + String perm = value.get_slice(".",1); + if (perms.has(perm)) { + string_table[attr_value]="android.permission."+perm; + } + + } + } + + if (tname=="supports-screens" ) { + + if (attr_value==0xFFFFFFFF) { + WARN_PRINT("Screen res name in a resource, should be plaintext") + } else if (attrname=="smallScreens") { + + print_line("SMALLSCREEN"); + string_table[attr_value]=screen_support[SCREEN_SMALL]?"true":"false"; + + } else if (attrname=="mediumScreens") { + + print_line("MEDSCREEN"); + string_table[attr_value]=screen_support[SCREEN_NORMAL]?"true":"false"; + + } else if (attrname=="largeScreens") { + + print_line("LARGECREEN"); + string_table[attr_value]=screen_support[SCREEN_LARGE]?"true":"false"; + + } else if (attrname=="xlargeScreens") { + + print_line("XLARGECREEN"); + string_table[attr_value]=screen_support[SCREEN_XLARGE]?"true":"false"; + + } + } + + iofs+=20; } @@ -1144,6 +1410,9 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() { Image img( _android_logo ); logo = Ref<ImageTexture>( memnew( ImageTexture )); logo->create_from_image(img); + + for(int i=0;i<4;i++) + screen_support[i]=true; } bool EditorExportPlatformAndroid::can_export(String *r_error) const { diff --git a/platform/android/java/src/com/android/godot/GodotPaymentV3.java b/platform/android/java/src/com/android/godot/GodotPaymentV3.java index 9d2893cde6..23f5bf34d3 100644 --- a/platform/android/java/src/com/android/godot/GodotPaymentV3.java +++ b/platform/android/java/src/com/android/godot/GodotPaymentV3.java @@ -24,8 +24,12 @@ public class GodotPaymentV3 extends Godot.SingletonBase { } }); }; + +/* public string requestPurchasedTicket(){ + activity.getPaymentsManager() + } - +*/ static public Godot.SingletonBase initialize(Activity p_activity) { return new GodotPaymentV3(p_activity); @@ -40,8 +44,8 @@ public class GodotPaymentV3 extends Godot.SingletonBase { - public void callbackSuccess(){ - GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{}); + public void callbackSuccess(String ticket){ + GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket}); } public void callbackFail(){ diff --git a/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java b/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java index 08fc405183..531a786dc9 100644 --- a/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java @@ -61,7 +61,7 @@ abstract public class HandlePurchaseTask { pc.setConsumableFlag("block", productId, true); pc.setConsumableValue("token", productId, purchaseToken); - success(purchaseToken, productId); + success(purchaseData); return; } catch (JSONException e) { error(e.getMessage()); @@ -71,7 +71,7 @@ abstract public class HandlePurchaseTask { } } - abstract protected void success(String purchaseToken, String sku); + abstract protected void success(String ticket); abstract protected void error(String message); abstract protected void canceled(); diff --git a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java index 325e3a0751..983f655c35 100644 --- a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java @@ -84,8 +84,9 @@ public class PaymentsManager { new HandlePurchaseTask(activity){ @Override - protected void success(String purchaseToken, String sku) { - validatePurchase(purchaseToken, sku); + protected void success(String ticket) { + godotPaymentV3.callbackSuccess(ticket); + //validatePurchase(purchaseToken, sku); } @Override @@ -112,7 +113,7 @@ public class PaymentsManager { @Override protected void success() { - godotPaymentV3.callbackSuccess(); + godotPaymentV3.callbackSuccess(""); } @@ -145,7 +146,5 @@ public class PaymentsManager { this.godotPaymentV3 = godotPaymentV3; } - - } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 8eb5c9dfc8..b9cddfa572 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -821,6 +821,17 @@ void CanvasItem::_bind_methods() { } +Matrix32 CanvasItem::get_canvas_transform() const { + + ERR_FAIL_COND_V(!is_inside_scene(),Matrix32()); + + if (canvas_layer) + return canvas_layer->get_transform(); + else + return get_viewport()->get_canvas_transform(); + +} + Matrix32 CanvasItem::get_viewport_transform() const { ERR_FAIL_COND_V(!is_inside_scene(),Matrix32()); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 397b206677..1c104c5fc2 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -195,6 +195,8 @@ public: void set_block_transform_notify(bool p_enable); bool is_block_transform_notify_enabled() const; + + Matrix32 get_canvas_transform() const; Matrix32 get_viewport_transform() const; Rect2 get_viewport_rect() const; RID get_viewport_rid() const; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 9e0faac716..e0604b7cb8 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -955,7 +955,7 @@ void Control::_window_input_event(InputEvent p_event) { window->key_event_accepted=false; - Point2 mpos =(get_viewport_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y)); + Point2 mpos =(get_canvas_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y)); if (p_event.mouse_button.pressed) { @@ -1102,7 +1102,7 @@ void Control::_window_input_event(InputEvent p_event) { window->key_event_accepted=false; - Matrix32 localizer = (get_viewport_transform()).affine_inverse(); + Matrix32 localizer = (get_canvas_transform()).affine_inverse(); Size2 pos = localizer.xform(Size2(p_event.mouse_motion.x,p_event.mouse_motion.y)) - _window_get_pos(); Vector2 speed = localizer.basis_xform(Point2(p_event.mouse_motion.speed_x,p_event.mouse_motion.speed_y)); Vector2 rel = localizer.basis_xform(Point2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y)); diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 32bc4b3e16..5ec416fb47 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -516,7 +516,8 @@ bool SceneMainLoop::idle(float p_time){ last_screen_size=win_size; - root->set_rect(Rect2(Point2(),last_screen_size)); + _update_root_rect(); + emit_signal("screen_resized"); @@ -849,6 +850,120 @@ int SceneMainLoop::get_node_count() const { return node_count; } + +void SceneMainLoop::_update_root_rect() { + + + if (stretch_mode==STRETCH_MODE_DISABLED) { + root->set_rect(Rect2(Point2(),last_screen_size)); + return; //user will take care + } + + //actual screen video mode + Size2 video_mode = Size2(OS::get_singleton()->get_video_mode().width,OS::get_singleton()->get_video_mode().height); + Size2 desired_res = stretch_min; + + Size2 viewport_size; + Size2 screen_size; + + float viewport_aspect = desired_res.get_aspect(); + float video_mode_aspect = video_mode.get_aspect(); + + if (stretch_aspect==STRETCH_ASPECT_IGNORE || ABS(viewport_aspect - video_mode_aspect)<CMP_EPSILON) { + //same aspect or ignore aspect + viewport_size=desired_res; + screen_size=video_mode; + } else if (viewport_aspect < video_mode_aspect) { + // screen ratio is smaller vertically + + if (stretch_aspect==STRETCH_ASPECT_KEEP_HEIGHT) { + + //will stretch horizontally + viewport_size.x=desired_res.y*video_mode_aspect; + viewport_size.y=desired_res.y; + screen_size=video_mode; + + } else { + //will need black bars + viewport_size=desired_res; + screen_size.x = video_mode.y * viewport_aspect; + screen_size.y=video_mode.y; + } + } else { + //screen ratio is smaller horizontally + if (stretch_aspect==STRETCH_ASPECT_KEEP_WIDTH) { + + //will stretch horizontally + viewport_size.x=desired_res.x; + viewport_size.y=desired_res.x / video_mode_aspect; + screen_size=video_mode; + + } else { + //will need black bars + viewport_size=desired_res; + screen_size.x=video_mode.x; + screen_size.y = video_mode.x / viewport_aspect; + } + + } + + screen_size = screen_size.floor(); + viewport_size = viewport_size.floor(); + + Size2 margin; + Size2 offset; + //black bars and margin + if (screen_size.x < video_mode.x) { + margin.x = Math::round((video_mode.x - screen_size.x)/2.0); + VisualServer::get_singleton()->black_bars_set_margins(margin.x,0,margin.x,0); + offset.x = Math::round(margin.x * viewport_size.y / screen_size.y); + } else if (screen_size.y < video_mode.y) { + + margin.y = Math::round((video_mode.y - screen_size.y)/2.0); + VisualServer::get_singleton()->black_bars_set_margins(0,margin.y,0,margin.y); + offset.y = Math::round(margin.y * viewport_size.x / screen_size.x); + } else { + VisualServer::get_singleton()->black_bars_set_margins(0,0,0,0); + } + +// print_line("VP SIZE: "+viewport_size+" OFFSET: "+offset+" = "+(offset*2+viewport_size)); +// print_line("SS: "+video_mode); + switch (stretch_mode) { + case STRETCH_MODE_2D: { + +// root->set_rect(Rect2(Point2(),video_mode)); + root->set_as_render_target(false); + root->set_rect(Rect2(margin,screen_size)); + root->set_size_override_stretch(true); + root->set_size_override(true,viewport_size); + + } break; + case STRETCH_MODE_VIEWPORT: { + + print_line("VP SIZE: "+viewport_size); + root->set_rect(Rect2(Point2(),viewport_size)); + root->set_size_override_stretch(false); + root->set_size_override(false,Size2()); + root->set_as_render_target(true); + root->set_render_target_update_mode(Viewport::RENDER_TARGET_UPDATE_ALWAYS); + root->set_render_target_to_screen_rect(Rect2(margin,screen_size)); + + } break; + + + } + +} + +void SceneMainLoop::set_screen_stretch(StretchMode p_mode,StretchAspect p_aspect,const Size2 p_minsize) { + + stretch_mode=p_mode; + stretch_aspect=p_aspect; + stretch_min=p_minsize; + _update_root_rect(); +} + + void SceneMainLoop::_bind_methods() { @@ -874,6 +989,9 @@ void SceneMainLoop::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_frame"),&SceneMainLoop::get_frame); ObjectTypeDB::bind_method(_MD("quit"),&SceneMainLoop::quit); + ObjectTypeDB::bind_method(_MD("set_screen_stretch","mode","aspect","minsize"),&SceneMainLoop::set_screen_stretch); + + ObjectTypeDB::bind_method(_MD("queue_delete","obj"),&SceneMainLoop::queue_delete); @@ -899,6 +1017,14 @@ void SceneMainLoop::_bind_methods() { BIND_CONSTANT( GROUP_CALL_REALTIME ); BIND_CONSTANT( GROUP_CALL_UNIQUE ); + BIND_CONSTANT( STRETCH_MODE_DISABLED ); + BIND_CONSTANT( STRETCH_MODE_2D ); + BIND_CONSTANT( STRETCH_MODE_VIEWPORT ); + BIND_CONSTANT( STRETCH_ASPECT_IGNORE ); + BIND_CONSTANT( STRETCH_ASPECT_KEEP ); + BIND_CONSTANT( STRETCH_ASPECT_KEEP_WIDTH ); + BIND_CONSTANT( STRETCH_ASPECT_KEEP_HEIGHT ); + } SceneMainLoop::SceneMainLoop() { @@ -927,6 +1053,9 @@ SceneMainLoop::SceneMainLoop() { root->set_as_audio_listener(true); root->set_as_audio_listener_2d(true); + stretch_mode=STRETCH_MODE_DISABLED; + stretch_aspect=STRETCH_ASPECT_IGNORE; + last_screen_size=Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); root->set_rect(Rect2(Point2(),last_screen_size)); @@ -934,7 +1063,6 @@ SceneMainLoop::SceneMainLoop() { ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree,this); } - } diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 1c8e0c90ae..8b9ea0b585 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -50,6 +50,25 @@ class SceneMainLoop : public MainLoop { _THREAD_SAFE_CLASS_ OBJ_TYPE( SceneMainLoop, MainLoop ); +public: + + + enum StretchMode { + + STRETCH_MODE_DISABLED, + STRETCH_MODE_2D, + STRETCH_MODE_VIEWPORT, + }; + + enum StretchAspect { + + STRETCH_ASPECT_IGNORE, + STRETCH_ASPECT_KEEP, + STRETCH_ASPECT_KEEP_WIDTH, + STRETCH_ASPECT_KEEP_HEIGHT, + }; +private: + struct Group { @@ -95,6 +114,12 @@ class SceneMainLoop : public MainLoop { Set<Node*> call_skip; //skip erased nodes + StretchMode stretch_mode; + StretchAspect stretch_aspect; + Size2i stretch_min; + + void _update_root_rect(); + List<ObjectID> delete_queue; Map<UGCall,Vector<Variant> > unique_group_calls; @@ -152,7 +177,6 @@ public: GROUP_CALL_MULIILEVEL=8, }; - _FORCE_INLINE_ Viewport *get_root() const { return root; } uint32_t get_last_event_id() const; @@ -196,10 +220,18 @@ public: void get_nodes_in_group(const StringName& p_group,List<Node*> *p_list); + void set_screen_stretch(StretchMode p_mode,StretchAspect p_aspect,const Size2 p_minsize); + + SceneMainLoop(); ~SceneMainLoop(); }; +VARIANT_ENUM_CAST( SceneMainLoop::StretchMode ); +VARIANT_ENUM_CAST( SceneMainLoop::StretchAspect ); + + + #endif diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 56d0544abd..0e32fd006d 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -86,8 +86,9 @@ void Viewport::_update_stretch_transform() { if (size_override_stretch && size_override) { stretch_transform=Matrix32(); - stretch_transform.scale(rect.size/(size_override_size+size_override_margin*2)); - stretch_transform.elements[2]=size_override_margin; + Size2 scale = rect.size/(size_override_size+size_override_margin*2); + stretch_transform.scale(scale); + stretch_transform.elements[2]=size_override_margin*scale; } else { @@ -629,7 +630,9 @@ Ref<World> Viewport::get_world() const{ Ref<World> Viewport::find_world() const{ - if (world.is_valid()) + if (own_world.is_valid()) + return own_world; + else if (world.is_valid()) return world; else if (parent) return parent->find_world(); @@ -863,6 +866,60 @@ void Viewport::unhandled_input(const InputEvent& p_event) { } } +void Viewport::set_use_own_world(bool p_world) { + + if (p_world==own_world.is_valid()) + return; + + + if (is_inside_scene()) + _propagate_exit_world(this); + +#ifndef _3D_DISABLED + if (find_world().is_valid() && camera) + camera->notification(Camera::NOTIFICATION_LOST_CURRENT); +#endif + + if (!p_world) + own_world=Ref<World>(); + else + own_world=Ref<World>( memnew( World )); + + if (is_inside_scene()) + _propagate_enter_world(this); + +#ifndef _3D_DISABLED + if (find_world().is_valid() && camera) + camera->notification(Camera::NOTIFICATION_BECAME_CURRENT); +#endif + + //propagate exit + + if (is_inside_scene()) { + VisualServer::get_singleton()->viewport_set_scenario(viewport,find_world()->get_scenario()); + } + + _update_listener(); + + +} + +bool Viewport::is_using_own_world() const { + + return own_world.is_valid(); +} + +void Viewport::set_render_target_to_screen_rect(const Rect2& p_rect) { + + to_screen_rect=p_rect; + VisualServer::get_singleton()->viewport_set_render_target_to_screen_rect(viewport,to_screen_rect); +} + +Rect2 Viewport::get_render_target_to_screen_rect() const{ + + return to_screen_rect; +} + void Viewport::_bind_methods() { @@ -918,15 +975,20 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("update_worlds"), &Viewport::update_worlds); + ObjectTypeDB::bind_method(_MD("set_use_own_world","enable"), &Viewport::set_use_own_world); + ObjectTypeDB::bind_method(_MD("is_using_own_world"), &Viewport::is_using_own_world); + ObjectTypeDB::bind_method(_MD("set_as_audio_listener","enable"), &Viewport::set_as_audio_listener); ObjectTypeDB::bind_method(_MD("is_audio_listener","enable"), &Viewport::is_audio_listener); ObjectTypeDB::bind_method(_MD("set_as_audio_listener_2d","enable"), &Viewport::set_as_audio_listener_2d); ObjectTypeDB::bind_method(_MD("is_audio_listener_2d","enable"), &Viewport::is_audio_listener_2d); + ObjectTypeDB::bind_method(_MD("set_render_target_to_screen_rect"), &Viewport::set_render_target_to_screen_rect); ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") ); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world",PROPERTY_HINT_RESOURCE_TYPE,"World"), _SCS("set_world"), _SCS("get_world") ); // ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") ); @@ -969,6 +1031,7 @@ Viewport::Viewport() { render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) ); + String id=itos(get_instance_ID()); input_group = "_vp_input"+id; gui_input_group = "_vp_gui_input"+id; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 8ba84651f8..33e1f27b93 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -101,6 +101,7 @@ friend class RenderTargetTexture; Matrix32 stretch_transform; Rect2 rect; + Rect2 to_screen_rect; bool size_override; @@ -120,6 +121,7 @@ friend class RenderTargetTexture; Ref<World2D> world_2d; Ref<World> world; + Ref<World> own_world; StringName input_group; StringName gui_input_group; @@ -213,9 +215,15 @@ public: void queue_screen_capture(); Image get_screen_capture() const; + void set_use_own_world(bool p_world); + bool is_using_own_world() const; + void input(const InputEvent& p_event); void unhandled_input(const InputEvent& p_event); + void set_render_target_to_screen_rect(const Rect2& p_rect); + Rect2 get_render_target_to_screen_rect() const; + Viewport(); ~Viewport(); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index fd1ea579f0..ee29d3aeff 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -770,7 +770,7 @@ void Physics2DServerSW::body_remove_collision_exception(RID p_body, RID p_body_b Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); - body->remove_exception(p_body); + body->remove_exception(p_body_b); }; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 37a846ca72..0b54fec859 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -494,6 +494,7 @@ public: }; virtual void canvas_begin()=0; + virtual void canvas_disable_blending()=0; virtual void canvas_set_opacity(float p_opacity)=0; virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode)=0; virtual void canvas_begin_rect(const Matrix32& p_transform)=0;; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 4fc8f1da8f..bfb427f2e8 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1384,7 +1384,7 @@ void RasterizerDummy::set_viewport(const VS::ViewportRect& p_viewport) { } -void RasterizerDummy::set_render_target(RID p_render_target,bool p_transparent_bg) { +void RasterizerDummy::set_render_target(RID p_render_target, bool p_transparent_bg, bool p_vflip) { } @@ -1455,6 +1455,12 @@ void RasterizerDummy::canvas_begin() { } +void RasterizerDummy::canvas_disable_blending() { + + + +} + void RasterizerDummy::canvas_set_opacity(float p_opacity) { diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 07a78549f7..e1fa521284 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -627,7 +627,7 @@ public: virtual void begin_frame(); virtual void set_viewport(const VS::ViewportRect& p_viewport); - virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false); + virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false); virtual void clear_viewport(const Color& p_color); virtual void capture_viewport(Image* r_capture); @@ -652,6 +652,7 @@ public: /* CANVAS API */ virtual void canvas_begin(); + virtual void canvas_disable_blending(); virtual void canvas_set_opacity(float p_opacity); virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode); virtual void canvas_begin_rect(const Matrix32& p_transform); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index a189fff246..18fd4c9922 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1145,6 +1145,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_ } +void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->rt_to_screen_rect=p_rect; + +} + bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{ const Viewport *viewport = viewport_owner.get( p_viewport ); @@ -5458,6 +5467,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ void VisualServerRaster::_draw_viewports() { //draw viewports for render targets + + List<Viewport*> to_blit; List<Viewport*> to_disable; for(SelfList<Viewport> *E=viewport_update_list.first();E;E=E->next()) { @@ -5472,6 +5483,9 @@ void VisualServerRaster::_draw_viewports() { continue; } + if (vp->rt_to_screen_rect!=Rect2()) + to_blit.push_back(vp); + rasterizer->set_render_target(vp->render_target,vp->transparent_bg,vp->render_target_vflip); _draw_viewport(vp,0,0,vp->rect.width,vp->rect.height); @@ -5491,6 +5505,38 @@ void VisualServerRaster::_draw_viewports() { to_disable.pop_front(); } + + //draw RTs directly to screen when requested + + for (List<Viewport*>::Element *E=to_blit.front();E;E=E->next()) { + + int window_w = OS::get_singleton()->get_video_mode().width; + int window_h = OS::get_singleton()->get_video_mode().height; + + ViewportRect desired_rect; + desired_rect.x = desired_rect.y = 0; + desired_rect.width = window_w; + desired_rect.height = window_h; + + if ( viewport_rect.x != desired_rect.x || + viewport_rect.y != desired_rect.y || + viewport_rect.width != desired_rect.width || + viewport_rect.height != desired_rect.height ) { + + viewport_rect=desired_rect; + + rasterizer->set_viewport(viewport_rect); + } + + rasterizer->canvas_begin(); + rasterizer->canvas_disable_blending(); + rasterizer->canvas_begin_rect(Matrix32()); + rasterizer->canvas_draw_rect(E->get()->rt_to_screen_rect,0,Rect2(Point2(),E->get()->rt_to_screen_rect.size),E->get()->render_target_texture,Color(1,1,1)); + + } + + + //draw viewports attached to screen for(Map<RID,int>::Element *E=screen_viewports.front();E;E=E->next()) { diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index d8d72b63ea..d3d504a7c6 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -481,6 +481,8 @@ class VisualServerRaster : public VisualServer { RID render_target; RID render_target_texture; + Rect2 rt_to_screen_rect; + bool hide_scenario; bool hide_canvas; bool transparent_bg; @@ -913,6 +915,7 @@ public: virtual RID viewport_get_render_target_texture(RID p_viewport) const; virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable); virtual bool viewport_get_render_target_vflip(RID p_viewport) const; + virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect); virtual void viewport_queue_screen_capture(RID p_viewport); virtual Image viewport_get_screen_capture(RID p_viewport) const; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 4e1094a3a2..c8f00c3786 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -891,6 +891,7 @@ public: FUNC2(viewport_set_render_target_vflip,RID,bool); FUNC1RC(bool,viewport_get_render_target_vflip,RID); + FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&); FUNC1(viewport_queue_screen_capture,RID); FUNC1RC(Image,viewport_get_screen_capture,RID); diff --git a/servers/visual_server.h b/servers/visual_server.h index d2c2046e54..4cf0c96228 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -592,6 +592,7 @@ public: virtual void viewport_attach_to_screen(RID p_viewport,int p_screen=0)=0; virtual void viewport_detach(RID p_viewport)=0; + virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect)=0; enum RenderTargetUpdateMode { RENDER_TARGET_UPDATE_DISABLED, @@ -611,6 +612,8 @@ public: virtual void viewport_queue_screen_capture(RID p_viewport)=0; virtual Image viewport_get_screen_capture(RID p_viewport) const=0; + + struct ViewportRect { int x,y,width,height; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 9429c16182..e799c103d0 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -3927,7 +3927,7 @@ EditorNode::EditorNode() { file_templates->set_mode(FileDialog::MODE_OPEN_FILE); file_templates->set_access(FileDialog::ACCESS_FILESYSTEM); file_templates->clear_filters(); - file_templates->add_filter("*.zip ; Zip Template Package"); + file_templates->add_filter("*.tpz ; Template Package"); file = memnew( FileDialog ); |