summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/math/a_star.cpp4
-rw-r--r--doc/classes/AStar.xml4
-rw-r--r--doc/classes/ConcavePolygonShape2D.xml1
-rw-r--r--doc/classes/CubeMap.xml29
-rw-r--r--doc/classes/EditorResourceConversionPlugin.xml2
-rw-r--r--doc/classes/HTTPClient.xml106
-rw-r--r--doc/classes/HTTPRequest.xml23
-rw-r--r--doc/classes/IP.xml14
-rw-r--r--doc/classes/IP_Unix.xml2
-rw-r--r--doc/classes/Node.xml2
-rw-r--r--doc/classes/PopupMenu.xml32
-rw-r--r--doc/classes/TileMap.xml32
-rw-r--r--doc/classes/TileSet.xml4
-rw-r--r--drivers/unix/os_unix.cpp34
-rw-r--r--editor/editor_node.cpp3
-rw-r--r--editor/editor_run.cpp9
-rw-r--r--editor/editor_themes.cpp7
-rw-r--r--editor/icons/icon_GUI_visibility_hidden.svg55
-rw-r--r--editor/icons/icon_GUI_visibility_visible.svg63
-rw-r--r--editor/icons/icon_GUI_visibility_xray.svg61
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp47
-rw-r--r--editor/plugins/spatial_editor_plugin.h8
-rw-r--r--editor/property_editor.cpp4
-rw-r--r--editor/scene_tree_editor.cpp3
-rw-r--r--editor/spatial_editor_gizmos.cpp28
-rw-r--r--main/input_default.cpp81
-rw-r--r--main/splash_sponsors.pngbin0 -> 39571 bytes
-rw-r--r--modules/bullet/godot_result_callbacks.h9
-rw-r--r--modules/bullet/space_bullet.cpp2
-rw-r--r--platform/android/export/export.cpp11
-rw-r--r--platform/iphone/app_delegate.mm133
-rw-r--r--platform/iphone/in_app_store.mm8
-rw-r--r--platform/x11/os_x11.cpp33
-rw-r--r--scene/2d/tile_map.cpp33
-rw-r--r--scene/2d/tile_map.h6
-rw-r--r--scene/gui/button.cpp26
-rw-r--r--scene/gui/button.h2
-rw-r--r--scene/gui/check_box.cpp43
-rw-r--r--scene/gui/check_box.h2
-rw-r--r--scene/gui/check_button.cpp36
-rw-r--r--scene/gui/check_button.h1
-rw-r--r--scene/gui/control.cpp11
-rw-r--r--scene/gui/control.h5
-rw-r--r--scene/gui/menu_button.cpp1
-rw-r--r--scene/gui/option_button.cpp1
-rw-r--r--scene/gui/popup_menu.cpp95
-rw-r--r--scene/gui/popup_menu.h17
-rw-r--r--scene/gui/rich_text_label.cpp2
-rw-r--r--scene/gui/rich_text_label.h4
-rw-r--r--scene/main/viewport.cpp11
-rw-r--r--scene/resources/default_theme/default_theme.cpp10
-rw-r--r--scene/resources/sky_box.cpp4
-rw-r--r--scene/resources/tile_set.cpp4
54 files changed, 802 insertions, 367 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 7e26761abf..4498efeb41 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -473,8 +473,8 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path);
- BIND_VMETHOD(MethodInfo("_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo("_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::REAL, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::REAL, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
AStar::AStar() {
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index eefdf4d7a7..e0e3261edf 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -13,7 +13,7 @@
</demos>
<methods>
<method name="_compute_cost" qualifiers="virtual">
- <return type="void">
+ <return type="float">
</return>
<argument index="0" name="from_id" type="int">
</argument>
@@ -24,7 +24,7 @@
</description>
</method>
<method name="_estimate_cost" qualifiers="virtual">
- <return type="void">
+ <return type="float">
</return>
<argument index="0" name="from_id" type="int">
</argument>
diff --git a/doc/classes/ConcavePolygonShape2D.xml b/doc/classes/ConcavePolygonShape2D.xml
index 1910b1d62d..1d2aabd6ea 100644
--- a/doc/classes/ConcavePolygonShape2D.xml
+++ b/doc/classes/ConcavePolygonShape2D.xml
@@ -15,6 +15,7 @@
</methods>
<members>
<member name="segments" type="PoolVector2Array" setter="set_segments" getter="get_segments">
+ The array of points that make up the [code]ConcavePolygonShape2D[/code]'s line segments.
</member>
</members>
<constants>
diff --git a/doc/classes/CubeMap.xml b/doc/classes/CubeMap.xml
index a7857dba78..30022efd38 100644
--- a/doc/classes/CubeMap.xml
+++ b/doc/classes/CubeMap.xml
@@ -4,7 +4,7 @@
A CubeMap is a 6 sided 3D texture.
</brief_description>
<description>
- A CubeMap is a 6 sided 3D texture typically used for faking reflections. It can be used to make an object look as if it's reflecting its surroundings. This usually delivers much better performance than other reflection methods.
+ A 6-sided 3D texture typically used for faking reflections. It can be used to make an object look as if it's reflecting its surroundings. This usually delivers much better performance than other reflection methods.
</description>
<tutorials>
</tutorials>
@@ -15,13 +15,14 @@
<return type="int">
</return>
<description>
+ Returns the render flags for the [code]CubeMap[/code]. See the [code]FLAG_*[/code] constants for details.
</description>
</method>
<method name="get_height" qualifiers="const">
<return type="int">
</return>
<description>
- Returns the CubeMap's height.
+ Returns the [code]CubeMap[/code]'s height.
</description>
</method>
<method name="get_side" qualifiers="const">
@@ -30,14 +31,14 @@
<argument index="0" name="side" type="int" enum="CubeMap.Side">
</argument>
<description>
- Returns an [Image] for a side of the CubeMap using one of the [code]SIDE_*[/code] constants or an integer 0-5.
+ Returns an [Image] for a side of the [code]CubeMap[/code] using one of the [code]SIDE_*[/code] constants or an integer 0-5.
</description>
</method>
<method name="get_width" qualifiers="const">
<return type="int">
</return>
<description>
- Returns the CubeMap's width.
+ Returns the [code]CubeMap[/code]'s width.
</description>
</method>
<method name="set_flags">
@@ -46,6 +47,7 @@
<argument index="0" name="flags" type="int">
</argument>
<description>
+ Returns the render flags for the [code]CubeMap[/code]. See the [code]FLAG_*[/code] constants for details.
</description>
</method>
<method name="set_side">
@@ -56,44 +58,57 @@
<argument index="1" name="image" type="Image">
</argument>
<description>
- Sets an [Image] for a side of the CubeMap using one of the [code]SIDE_*[/code] constants or an integer 0-5.
+ Sets an [Image] for a side of the [code]CubeMap[/code] using one of the [code]SIDE_*[/code] constants or an integer 0-5.
</description>
</method>
</methods>
<members>
<member name="lossy_storage_quality" type="float" setter="set_lossy_storage_quality" getter="get_lossy_storage_quality">
- The lossy storage quality of the CubeMap if the storage mode is set to STORAGE_COMPRESS_LOSSY.
+ The lossy storage quality of the [code]CubeMap[/code] if the storage mode is set to STORAGE_COMPRESS_LOSSY.
</member>
<member name="storage_mode" type="int" setter="set_storage" getter="get_storage" enum="CubeMap.Storage">
- The CubeMap's storage mode. See [code]STORAGE_*[/code] constants.
+ The [code]CubeMap[/code]'s storage mode. See [code]STORAGE_*[/code] constants.
</member>
</members>
<constants>
<constant name="STORAGE_RAW" value="0" enum="Storage">
+ Store the [code]CubeMap[/code] without any compression.
</constant>
<constant name="STORAGE_COMPRESS_LOSSY" value="1" enum="Storage">
+ Store the [code]CubeMap[/code] with strong compression that reduces image quality.
</constant>
<constant name="STORAGE_COMPRESS_LOSSLESS" value="2" enum="Storage">
+ Store the [code]CubeMap[/code] with moderate compression that doesn't reduce image quality.
</constant>
<constant name="SIDE_LEFT" value="0" enum="Side">
+ Identifier for the left face of the [code]CubeMap[/code].
</constant>
<constant name="SIDE_RIGHT" value="1" enum="Side">
+ Identifier for the right face of the [code]CubeMap[/code].
</constant>
<constant name="SIDE_BOTTOM" value="2" enum="Side">
+ Identifier for the bottom face of the [code]CubeMap[/code].
</constant>
<constant name="SIDE_TOP" value="3" enum="Side">
+ Identifier for the top face of the [code]CubeMap[/code].
</constant>
<constant name="SIDE_FRONT" value="4" enum="Side">
+ Identifier for the front face of the [code]CubeMap[/code].
</constant>
<constant name="SIDE_BACK" value="5" enum="Side">
+ Identifier for the back face of the [code]CubeMap[/code].
</constant>
<constant name="FLAG_MIPMAPS" value="1" enum="Flags">
+ Generate mipmaps, to enable smooth zooming out of the texture.
</constant>
<constant name="FLAG_REPEAT" value="2" enum="Flags">
+ Repeat (instead of clamp to edge).
</constant>
<constant name="FLAG_FILTER" value="4" enum="Flags">
+ Turn on magnifying filter, to enable smooth zooming in of the texture.
</constant>
<constant name="FLAGS_DEFAULT" value="7" enum="Flags">
+ Default flags. Generate mipmaps, repeat, and filter are enabled.
</constant>
</constants>
</class>
diff --git a/doc/classes/EditorResourceConversionPlugin.xml b/doc/classes/EditorResourceConversionPlugin.xml
index b2bbe69061..8d6aa3a605 100644
--- a/doc/classes/EditorResourceConversionPlugin.xml
+++ b/doc/classes/EditorResourceConversionPlugin.xml
@@ -18,7 +18,7 @@
</description>
</method>
<method name="_converts_to" qualifiers="virtual">
- <return type="bool">
+ <return type="String">
</return>
<description>
</description>
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index b1526b64c5..fc87f49218 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -4,8 +4,10 @@
Hyper-text transfer protocol client.
</brief_description>
<description>
- Hyper-text transfer protocol client. Supports SSL and SSL server certificate verification.
- Can be reused to connect to different hosts and make many requests.
+ Hyper-text transfer protocol client (sometimes called "User Agent"). Used to make HTTP requests to download web content, upload files and other data or to communicate with various services, among other use cases.
+ Note that this client only needs to connect to a host once (see [method connect_to_host]) to send multiple requests. Because of this, methods that take URLs usually take just the part after the host instead of the full URL, as the client is already connected to a host. See [method request] for a full example and to get started.
+ A [code]HTTPClient[/code] should be reused between multiple requests or to connect to different hosts instead of creating one client per request. Supports SSL and SSL server certificate verification. HTTP status codes in the 2xx range indicate success, 3xx redirection (i.e. "try again, but over here"), 4xx something was wrong with the request, and 5xx something went wrong on the server's side.
+ For more information on HTTP, see https://developer.mozilla.org/en-US/docs/Web/HTTP (or read RFC 2616 to get it straight from the source: https://tools.ietf.org/html/rfc2616).
</description>
<tutorials>
</tutorials>
@@ -16,7 +18,7 @@
<return type="void">
</return>
<description>
- Cloces the current connection, allows for reusal of [code]HTTPClient[/code].
+ Closes the current connection, allowing reuse of this [code]HTTPClient[/code].
</description>
</method>
<method name="connect_to_host">
@@ -33,35 +35,35 @@
<description>
Connect to a host. This needs to be done before any requests are sent.
The host should not have http:// prepended but will strip the protocol identifier if provided.
- verify_host will check the SSL identity of the host if set to true.
+ [code]verify_host[/code] will check the SSL identity of the host if set to [code]true[/code].
</description>
</method>
<method name="get_connection" qualifiers="const">
<return type="StreamPeer">
</return>
<description>
- Return current connection.
+ Returns the current connection.
</description>
</method>
<method name="get_response_body_length" qualifiers="const">
<return type="int">
</return>
<description>
- Return the response's body length.
+ Returns the response's body length.
</description>
</method>
<method name="get_response_code" qualifiers="const">
<return type="int">
</return>
<description>
- Return the HTTP status code of the response.
+ Returns the response's HTTP status code.
</description>
</method>
<method name="get_response_headers">
<return type="PoolStringArray">
</return>
<description>
- Return the response headers.
+ Returns the response headers.
</description>
</method>
<method name="get_response_headers_as_dictionary">
@@ -84,21 +86,21 @@
<return type="bool">
</return>
<description>
- Return whether this [code]HTTPClient[/code] has a response available.
+ If [code]true[/code] this [code]HTTPClient[/code] has a response available.
</description>
</method>
<method name="is_blocking_mode_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether blocking mode is enabled.
+ If [code]true[/code] blocking mode is enabled.
</description>
</method>
<method name="is_response_chunked" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether this [code]HTTPClient[/code] has a response that is chunked.
+ If [code]true[/code] this [code]HTTPClient[/code] has a response that is chunked.
</description>
</method>
<method name="poll">
@@ -141,8 +143,8 @@
<argument index="3" name="body" type="String" default="&quot;&quot;">
</argument>
<description>
- Sends a request to the connected host. The url is what is normally behind the hostname, i.e. in [code]http://somehost.com/index.php[/code], url would be "index.php".
- Headers are HTTP request headers.
+ Sends a request to the connected host. The URL parameter is just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]index.php[/code].
+ Headers are HTTP request headers. For available HTTP methods, see [code]METHOD_*[/code].
To create a POST request with query strings to push to the server, do:
[codeblock]
var fields = {"username" : "user", "password" : "pass"}
@@ -164,9 +166,9 @@
<argument index="3" name="body" type="PoolByteArray">
</argument>
<description>
- Sends a raw request to the connected host. The url is what is normally behind the hostname, i.e. in [code]http://somehost.com/index.php[/code], url would be "index.php".
- Headers are HTTP request headers.
- Sends body raw, as a byte array, does not encode it in any way.
+ Sends a raw request to the connected host. The URL parameter is just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]index.php[/code].
+ Headers are HTTP request headers. For available HTTP methods, see [code]METHOD_*[/code].
+ Sends the body data raw, as a byte array and does not encode it in any way.
</description>
</method>
<method name="set_blocking_mode">
@@ -184,7 +186,7 @@
<argument index="0" name="connection" type="StreamPeer">
</argument>
<description>
- Set connection to use, for this client.
+ Sets connection to use for this client.
</description>
</method>
<method name="set_read_chunk_size">
@@ -199,140 +201,208 @@
</methods>
<constants>
<constant name="METHOD_GET" value="0" enum="Method">
+ HTTP GET method. The GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
</constant>
- <constant name="METHOD_HEAD" value="1" enum="Method">
+ <constant name="METHOD_HEAD" value="1" enum="Method">#
+ HTTP HEAD method. The HEAD method asks for a response identical to that of a GET request, but without the response body. This is useful to request metadata like HTTP headers or to check if a resource exists.
</constant>
<constant name="METHOD_POST" value="2" enum="Method">
+ HTTP POST method. The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server. This is often used for forms and submitting data or uploading files.
</constant>
<constant name="METHOD_PUT" value="3" enum="Method">
+ HTTP PUT method. The PUT method asks to replace all current representations of the target resource with the request payload. (You can think of [code]POST[/code] as "create or update" and [code]PUT[/code] as "update", although many services tend to not make a clear distinction or change their meaning).
</constant>
<constant name="METHOD_DELETE" value="4" enum="Method">
+ HTTP DELETE method. The DELETE method requests to delete the specified resource.
</constant>
<constant name="METHOD_OPTIONS" value="5" enum="Method">
+ HTTP OPTIONS method. The OPTIONS method asks for a description of the communication options for the target resource. Rarely used.
</constant>
<constant name="METHOD_TRACE" value="6" enum="Method">
+ HTTP TRACE method. The TRACE method performs a message loop-back test along the path to the target resource. Returns the entire HTTP request received in the response body. Rarely used.
</constant>
<constant name="METHOD_CONNECT" value="7" enum="Method">
+ HTTP CONNECT method. The CONNECT method establishes a tunnel to the server identified by the target resource. Rarely used.
</constant>
<constant name="METHOD_MAX" value="8" enum="Method">
+ Marker for end of [code]METHOD_*[/code] enum. Not used.
</constant>
<constant name="STATUS_DISCONNECTED" value="0" enum="Status">
+ Status: Disconnected from the server.
</constant>
<constant name="STATUS_RESOLVING" value="1" enum="Status">
+ Status: Currently resolving the hostname for the given URL into an IP.
</constant>
<constant name="STATUS_CANT_RESOLVE" value="2" enum="Status">
+ Status: DNS failure: Can't resolve the hostname for the given URL.
</constant>
<constant name="STATUS_CONNECTING" value="3" enum="Status">
+ Status: Currently connecting to server.
</constant>
<constant name="STATUS_CANT_CONNECT" value="4" enum="Status">
+ Status: Can't connect to the server.
</constant>
<constant name="STATUS_CONNECTED" value="5" enum="Status">
+ Status: Connection established.
</constant>
<constant name="STATUS_REQUESTING" value="6" enum="Status">
+ Status: Currently sending request.
</constant>
<constant name="STATUS_BODY" value="7" enum="Status">
+ Status: HTTP body received.
</constant>
<constant name="STATUS_CONNECTION_ERROR" value="8" enum="Status">
+ Status: Error in HTTP connection.
</constant>
<constant name="STATUS_SSL_HANDSHAKE_ERROR" value="9" enum="Status">
+ Status: Error in SSL handshake.
</constant>
<constant name="RESPONSE_CONTINUE" value="100" enum="ResponseCode">
+ HTTP status code [code]100 Continue[/code]. Interim response that indicates everything so far is OK and that the client should continue with the request (or ignore this status if already finished).
</constant>
<constant name="RESPONSE_SWITCHING_PROTOCOLS" value="101" enum="ResponseCode">
+ HTTP status code [code]101 Switching Protocol[/code]. Sent in response to an [code]Upgrade[/code] request header by the client. Indicates the protocol the server is switching to.
</constant>
<constant name="RESPONSE_PROCESSING" value="102" enum="ResponseCode">
+ HTTP status code [code]102 Processing[/code] (WebDAV). Indicates that the server has received and is processing the request, but no response is available yet.
</constant>
<constant name="RESPONSE_OK" value="200" enum="ResponseCode">
+ HTTP status code [code]200 OK[/code]. The request has succeeded. Default response for successful requests. Meaning varies depending on the request. GET: The resource has been fetched and is transmitted in the message body. HEAD: The entity headers are in the message body. POST: The resource describing the result of the action is transmitted in the message body. TRACE: The message body contains the request message as received by the server.
</constant>
<constant name="RESPONSE_CREATED" value="201" enum="ResponseCode">
+ HTTP status code [code]201 Created[/code]. The request has succeeded and a new resource has been created as a result of it. This is typically the response sent after a PUT request.
</constant>
<constant name="RESPONSE_ACCEPTED" value="202" enum="ResponseCode">
+ HTTP status code [code]202 Accepted[/code]. The request has been received but not yet acted upon. It is non-committal, meaning that there is no way in HTTP to later send an asynchronous response indicating the outcome of processing the request. It is intended for cases where another process or server handles the request, or for batch processing.
</constant>
<constant name="RESPONSE_NON_AUTHORITATIVE_INFORMATION" value="203" enum="ResponseCode">
+ HTTP status code [code]203 Non-Authoritative Information[/code]. This response code means returned meta-information set is not exact set as available from the origin server, but collected from a local or a third party copy. Except this condition, 200 OK response should be preferred instead of this response.
</constant>
<constant name="RESPONSE_NO_CONTENT" value="204" enum="ResponseCode">
+ HTTP status code [code]204 No Content[/code]. There is no content to send for this request, but the headers may be useful. The user-agent may update its cached headers for this resource with the new ones.
</constant>
<constant name="RESPONSE_RESET_CONTENT" value="205" enum="ResponseCode">
+ HTTP status code [code]205 Reset Content[/code]. The server has fulfilled the request and desires that the client resets the "document view" that caused the request to be sent to its original state as received from the origin server.
</constant>
<constant name="RESPONSE_PARTIAL_CONTENT" value="206" enum="ResponseCode">
+ HTTP status code [code]206 Partial Content[/code]. This response code is used because of a range header sent by the client to separate download into multiple streams.
</constant>
<constant name="RESPONSE_MULTI_STATUS" value="207" enum="ResponseCode">
+ HTTP status code [code]207 Multi-Status[/code] (WebDAV). A Multi-Status response conveys information about multiple resources in situations where multiple status codes might be appropriate.
</constant>
<constant name="RESPONSE_IM_USED" value="226" enum="ResponseCode">
+ HTTP status code [code]226 IM Used[/code] (WebDAV). The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
</constant>
<constant name="RESPONSE_MULTIPLE_CHOICES" value="300" enum="ResponseCode">
+ HTTP status code [code]300 Multiple Choice[/code]. The request has more than one possible responses and there is no standardized way to choose one of the responses. User-agent or user should choose one of them.
</constant>
<constant name="RESPONSE_MOVED_PERMANENTLY" value="301" enum="ResponseCode">
+ HTTP status code [code]301 Moved Permanently[/code]. Redirection. This response code means the URI of requested resource has been changed. The new URI is usually included in the response.
</constant>
<constant name="RESPONSE_FOUND" value="302" enum="ResponseCode">
+ HTTP status code [code]302 Found[/code]. Temporary redirection. This response code means the URI of requested resource has been changed temporarily. New changes in the URI might be made in the future. Therefore, this same URI should be used by the client in future requests.
</constant>
<constant name="RESPONSE_SEE_OTHER" value="303" enum="ResponseCode">
+ HTTP status code [code]303 See Other[/code]. The server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field, which is intended to provide an indirect response to the original request.
</constant>
<constant name="RESPONSE_NOT_MODIFIED" value="304" enum="ResponseCode">
+ HTTP status code [code]304 Not Modified[/code]. A conditional GET or HEAD request has been received and would have resulted in a 200 OK response if it were not for the fact that the condition evaluated to false.
</constant>
<constant name="RESPONSE_USE_PROXY" value="305" enum="ResponseCode">
+ HTTP status code [code]305 Use Proxy[/code]. Deprecated. Do not use.
</constant>
<constant name="RESPONSE_TEMPORARY_REDIRECT" value="307" enum="ResponseCode">
+ HTTP status code [code]307 Temporary Redirect[/code]. The target resource resides temporarily under a different URI and the user agent MUST NOT change the request method if it performs an automatic redirection to that URI.
</constant>
<constant name="RESPONSE_BAD_REQUEST" value="400" enum="ResponseCode">
+ HTTP status code [code]400 Bad Request[/code]. The request was invalid. The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, invalid request contents, or deceptive request routing).
</constant>
<constant name="RESPONSE_UNAUTHORIZED" value="401" enum="ResponseCode">
+ HTTP status code [code]401 Unauthorized[/code]. Credentials required. The request has not been applied because it lacks valid authentication credentials for the target resource.
</constant>
<constant name="RESPONSE_PAYMENT_REQUIRED" value="402" enum="ResponseCode">
+ HTTP status code [code]402 Payment Required[/code]. This response code is reserved for future use. Initial aim for creating this code was using it for digital payment systems, however this is not currently used.
</constant>
<constant name="RESPONSE_FORBIDDEN" value="403" enum="ResponseCode">
+ HTTP status code [code]403 Forbidden[/code]. The client does not have access rights to the content, i.e. they are unauthorized, so server is rejecting to give proper response. Unlike [code]401[/code], the client's identity is known to the server.
</constant>
<constant name="RESPONSE_NOT_FOUND" value="404" enum="ResponseCode">
+ HTTP status code [code]404 Not Found[/code]. The server can not find requested resource. Either the URL is not recognized or the endpoint is valid but the resource itself does not exist. May also be sent instead of 403 to hide existence of a resource if the client is not authorized.
</constant>
<constant name="RESPONSE_METHOD_NOT_ALLOWED" value="405" enum="ResponseCode">
+ HTTP status code [code]405 Method Not Allowed[/code]. The request's HTTP method is known by the server but has been disabled and cannot be used. For example, an API may forbid DELETE-ing a resource. The two mandatory methods, GET and HEAD, must never be disabled and should not return this error code.
</constant>
<constant name="RESPONSE_NOT_ACCEPTABLE" value="406" enum="ResponseCode">
+ HTTP status code [code]406 Not Acceptable[/code]. The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request. Used when negotiation content.
</constant>
<constant name="RESPONSE_PROXY_AUTHENTICATION_REQUIRED" value="407" enum="ResponseCode">
+ HTTP status code [code]407 Proxy Authentication Required[/code]. Similar to 401 Unauthorized, but it indicates that the client needs to authenticate itself in order to use a proxy.
</constant>
<constant name="RESPONSE_REQUEST_TIMEOUT" value="408" enum="ResponseCode">
+ HTTP status code [code]408 Request Timeout[/code]. The server did not receive a complete request message within the time that it was prepared to wait.
</constant>
<constant name="RESPONSE_CONFLICT" value="409" enum="ResponseCode">
+ HTTP status code [code]409 Conflict[/code]. The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request.
</constant>
<constant name="RESPONSE_GONE" value="410" enum="ResponseCode">
+ HTTP status code [code]410 Gone[/code]. The target resource is no longer available at the origin server and this condition is likely permanent.
</constant>
<constant name="RESPONSE_LENGTH_REQUIRED" value="411" enum="ResponseCode">
+ HTTP status code [code]411 Length Required[/code]. The server refuses to accept the request without a defined Content-Length header.
</constant>
<constant name="RESPONSE_PRECONDITION_FAILED" value="412" enum="ResponseCode">
+ HTTP status code [code]412 Precondition Failed[/code]. One or more conditions given in the request header fields evaluated to false when tested on the server.
</constant>
<constant name="RESPONSE_REQUEST_ENTITY_TOO_LARGE" value="413" enum="ResponseCode">
+ HTTP status code [code]413 Entity Too Large[/code]. The server is refusing to process a request because the request payload is larger than the server is willing or able to process.
</constant>
<constant name="RESPONSE_REQUEST_URI_TOO_LONG" value="414" enum="ResponseCode">
+ HTTP status code [code]414 Request-URI Too Long[/code]. The server is refusing to service the request because the request-target is longer than the server is willing to interpret.
</constant>
<constant name="RESPONSE_UNSUPPORTED_MEDIA_TYPE" value="415" enum="ResponseCode">
+ HTTP status code [code]415 Unsupported Media Type[/code]. The origin server is refusing to service the request because the payload is in a format not supported by this method on the target resource.
</constant>
<constant name="RESPONSE_REQUESTED_RANGE_NOT_SATISFIABLE" value="416" enum="ResponseCode">
+ HTTP status code [code]416 Requested Range Not Satisfiable[/code]. None of the ranges in the request's Range header field overlap the current extent of the selected resource or the set of ranges requested has been rejected due to invalid ranges or an excessive request of small or overlapping ranges.
</constant>
<constant name="RESPONSE_EXPECTATION_FAILED" value="417" enum="ResponseCode">
+ HTTP status code [code]417 Expectation Failed[/code]. The expectation given in the request's Expect header field could not be met by at least one of the inbound servers.
</constant>
<constant name="RESPONSE_UNPROCESSABLE_ENTITY" value="422" enum="ResponseCode">
+ HTTP status code [code]422 Unprocessable Entity[/code] (WebDAV). The server understands the content type of the request entity (hence a 415 Unsupported Media Type status code is inappropriate), and the syntax of the request entity is correct (thus a 400 Bad Request status code is inappropriate) but was unable to process the contained instructions.
</constant>
<constant name="RESPONSE_LOCKED" value="423" enum="ResponseCode">
+ HTTP status code [code]423 Locked[/code] (WebDAV). The source or destination resource of a method is locked.
</constant>
<constant name="RESPONSE_FAILED_DEPENDENCY" value="424" enum="ResponseCode">
+ HTTP status code [code]424 Failed Dependency[/code] (WebDAV). The method could not be performed on the resource because the requested action depended on another action and that action failed.
</constant>
<constant name="RESPONSE_UPGRADE_REQUIRED" value="426" enum="ResponseCode">
+ HTTP status code [code]426 Upgrade Required[/code]. The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.
</constant>
<constant name="RESPONSE_INTERNAL_SERVER_ERROR" value="500" enum="ResponseCode">
+ HTTP status code [code]500 Internal Server Error[/code]. The server encountered an unexpected condition that prevented it from fulfilling the request.
</constant>
<constant name="RESPONSE_NOT_IMPLEMENTED" value="501" enum="ResponseCode">
+ HTTP status code [code]501 Not Implemented[/code]. The server does not support the functionality required to fulfill the request.
</constant>
<constant name="RESPONSE_BAD_GATEWAY" value="502" enum="ResponseCode">
+ HTTP status code [code]502 Bad Gateway[/code]. The server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request. Usually returned by load balancers or proxies.
</constant>
<constant name="RESPONSE_SERVICE_UNAVAILABLE" value="503" enum="ResponseCode">
+ HTTP status code [code]503 Service Unavailable[/code]. The server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay. Try again later.
</constant>
<constant name="RESPONSE_GATEWAY_TIMEOUT" value="504" enum="ResponseCode">
+ HTTP status code [code]504 Gateway Timeout[/code]. The server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request. Usually returned by load balancers or proxies.
</constant>
<constant name="RESPONSE_HTTP_VERSION_NOT_SUPPORTED" value="505" enum="ResponseCode">
+ HTTP status code [code]505 HTTP Version Not Supported[/code]. The server does not support, or refuses to support, the major version of HTTP that was used in the request message.
</constant>
<constant name="RESPONSE_INSUFFICIENT_STORAGE" value="507" enum="ResponseCode">
+ HTTP status code [code]507 Insufficient Storage[/code]. The method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request.
</constant>
<constant name="RESPONSE_NOT_EXTENDED" value="510" enum="ResponseCode">
+ HTTP status code [code]510 Not Extended[/code]. The policy for accessing the resource has not been met in the request. The server should send back all the information necessary for the client to issue an extended request.
</constant>
</constants>
</class>
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index 7c37479295..985198c76f 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HTTPRequest" inherits="Node" category="Core" version="3.0-beta">
<brief_description>
- A Node with the ability to send HTTP requests.
+ A node with the ability to send HTTP requests.
</brief_description>
<description>
- A Node with the ability to send HTTP requests. Uses a [HTTPClient] internally, supports HTTPS.
- Can be used to make HTTP requests or download files via HTTP.
+ A node with the ability to send HTTP requests. Uses [HTTPClient] internally.
+ Can be used to make HTTP requests, i.e. download or upload files or web content via HTTP.
</description>
<tutorials>
</tutorials>
@@ -16,35 +16,35 @@
<return type="void">
</return>
<description>
- Cancel the current request.
+ Cancels the current request.
</description>
</method>
<method name="get_body_size" qualifiers="const">
<return type="int">
</return>
<description>
- Return the response body length.
+ Returns the response body length.
</description>
</method>
<method name="get_download_file" qualifiers="const">
<return type="String">
</return>
<description>
- Return the file this request will download into.
+ Returns the file this request will download into.
</description>
</method>
<method name="get_downloaded_bytes" qualifiers="const">
<return type="int">
</return>
<description>
- Return the amount of bytes this HTTPRequest downloaded.
+ Returns the amount of bytes this HTTPRequest downloaded.
</description>
</method>
<method name="get_http_client_status" qualifiers="const">
<return type="int" enum="HTTPClient.Status">
</return>
<description>
- Return the current status of the underlying [HTTPClient].
+ Returns the current status of the underlying [HTTPClient]. See [code]STATUS_*[/code] enum on [HTTPClient].
</description>
</method>
<method name="request">
@@ -69,16 +69,19 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Set the file to download into. Outputs the response body into the file.
+ Sets the file to download into. Outputs the response body into the file if set.
</description>
</method>
</methods>
<members>
<member name="body_size_limit" type="int" setter="set_body_size_limit" getter="get_body_size_limit">
+ Maximum allowed size for response bodies.
</member>
<member name="max_redirects" type="int" setter="set_max_redirects" getter="get_max_redirects">
+ Maximum number of allowed redirects.
</member>
<member name="use_threads" type="bool" setter="set_use_threads" getter="is_using_threads">
+ If [code]true[/code] multithreading is used to improve performance.
</member>
</members>
<signals>
@@ -121,7 +124,7 @@
Request exceeded its maximum size limit, see [method set_body_size_limit].
</constant>
<constant name="RESULT_REQUEST_FAILED" value="8" enum="Result">
- Request failed. (unused)
+ Request failed. (Unused)
</constant>
<constant name="RESULT_DOWNLOAD_FILE_CANT_OPEN" value="9" enum="Result">
HTTPRequest couldn't open the download file.
diff --git a/doc/classes/IP.xml b/doc/classes/IP.xml
index 09734e746c..cd669e3de1 100644
--- a/doc/classes/IP.xml
+++ b/doc/classes/IP.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="IP" inherits="Object" category="Core" version="3.0-beta">
<brief_description>
- IP Protocol support functions.
+ Internet protocol (IP) support functions like DNS resolution.
</brief_description>
<description>
- IP contains support functions for the IPv4 protocol. TCP/IP support is in different classes (see [StreamPeerTCP] and [TCP_Server]). IP provides hostname resolution support, both blocking and threaded.
+ IP contains support functions for the Internet Protocol (IP). TCP/IP support is in different classes (see [StreamPeerTCP] and [TCP_Server]). IP provides DNS hostname resolution support, both blocking and threaded.
</description>
<tutorials>
</tutorials>
@@ -79,24 +79,34 @@
</methods>
<constants>
<constant name="RESOLVER_STATUS_NONE" value="0" enum="ResolverStatus">
+ DNS hostname resolver status: No status.
</constant>
<constant name="RESOLVER_STATUS_WAITING" value="1" enum="ResolverStatus">
+ DNS hostname resolver status: Waiting.
</constant>
<constant name="RESOLVER_STATUS_DONE" value="2" enum="ResolverStatus">
+ DNS hostname resolver status: Done.
</constant>
<constant name="RESOLVER_STATUS_ERROR" value="3" enum="ResolverStatus">
+ DNS hostname resolver status: Error.
</constant>
<constant name="RESOLVER_MAX_QUERIES" value="32">
+ Maximum number of concurrent DNS resolver queries allowed, [code]RESOLVER_INVALID_ID[/code] is returned if exceeded.
</constant>
<constant name="RESOLVER_INVALID_ID" value="-1">
+ Invalid ID constant. Returned if [code]RESOLVER_MAX_QUERIES[/code] is exceeded.
</constant>
<constant name="TYPE_NONE" value="0" enum="Type">
+ Address type: None.
</constant>
<constant name="TYPE_IPV4" value="1" enum="Type">
+ Address type: Internet protocol version 4 (IPv4).
</constant>
<constant name="TYPE_IPV6" value="2" enum="Type">
+ Address type: Internet protocol version 6 (IPv6).
</constant>
<constant name="TYPE_ANY" value="3" enum="Type">
+ Address type: Any.
</constant>
</constants>
</class>
diff --git a/doc/classes/IP_Unix.xml b/doc/classes/IP_Unix.xml
index 28e8a3804b..1d376c7233 100644
--- a/doc/classes/IP_Unix.xml
+++ b/doc/classes/IP_Unix.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="IP_Unix" inherits="IP" category="Core" version="3.0-beta">
<brief_description>
+ Unix IP support. See [IP].
</brief_description>
<description>
+ Unix-specific implementation of IP support functions. See [IP].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index e2198c3e15..78591e2bf8 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -498,7 +498,7 @@
<return type="void">
</return>
<description>
- Removes a node and set all its children as children of the parent node (if exists). All even subscriptions that pass by the removed node will be unsubscribed.
+ Removes a node and set all its children as children of the parent node (if exists). All event subscriptions that pass by the removed node will be unsubscribed.
</description>
</method>
<method name="remove_child">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 7071d64f2e..42ed57e4af 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -233,6 +233,12 @@
<description>
</description>
</method>
+ <method name="is_hide_on_state_item_selection" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_item_checkable" qualifiers="const">
<return type="bool">
</return>
@@ -278,6 +284,14 @@
Removes the item at index "idx" from the menu. Note that the indexes of items after the removed item are going to be shifted by one.
</description>
</method>
+ <method name="set_hide_on_state_item_selection">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_item_accelerator">
<return type="void">
</return>
@@ -377,6 +391,16 @@
<description>
</description>
</method>
+ <method name="set_item_statable">
+ <return type="void">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <argument index="1" name="state" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_item_submenu">
<return type="void">
</return>
@@ -417,6 +441,14 @@
<description>
</description>
</method>
+ <method name="toggle_item_statable">
+ <return type="void">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="hide_on_checkable_item_selection" type="bool" setter="set_hide_on_checkable_item_selection" getter="is_hide_on_checkable_item_selection">
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index e58ab3dd25..72cd56dc55 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -38,20 +38,6 @@
Return the tile index of the cell referenced by a Vector2.
</description>
</method>
- <method name="get_center_x" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Return true if tiles are to be centered in x coordinate (by default this is false and they are drawn from upper left cell corner).
- </description>
- </method>
- <method name="get_center_y" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Return true if tiles are to be centered in y coordinate (by default this is false and they are drawn from upper left cell corner).
- </description>
- </method>
<method name="get_collision_layer_bit" qualifiers="const">
<return type="bool">
</return>
@@ -176,24 +162,6 @@
Optionally, the tile can also be flipped over the X and Y axes or transposed.
</description>
</method>
- <method name="set_center_x">
- <return type="void">
- </return>
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- Set tiles to be centered in x coordinate. (by default this is false and they are drawn from upper left cell corner).
- </description>
- </method>
- <method name="set_center_y">
- <return type="void">
- </return>
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- Set tiles to be centered in y coordinate. (by default this is false and they are drawn from upper left cell corner).
- </description>
- </method>
<method name="set_collision_layer_bit">
<return type="void">
</return>
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index 6a147a9646..3dbf172c5a 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -13,7 +13,7 @@
</demos>
<methods>
<method name="_forward_subtile_selection" qualifiers="virtual">
- <return type="void">
+ <return type="Vector2">
</return>
<argument index="0" name="autotile_id" type="int">
</argument>
@@ -27,7 +27,7 @@
</description>
</method>
<method name="_is_tile_bound" qualifiers="virtual">
- <return type="void">
+ <return type="bool">
</return>
<argument index="0" name="drawn_id" type="int">
</argument>
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 5a06a58b80..bc18707deb 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -141,42 +141,14 @@ void OS_Unix::alert(const String &p_alert, const String &p_title) {
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
}
-static int has_data(FILE *p_fd, int timeout_usec = 0) {
-
- fd_set readset;
- int fd = fileno(p_fd);
- FD_ZERO(&readset);
- FD_SET(fd, &readset);
- timeval time;
- time.tv_sec = 0;
- time.tv_usec = timeout_usec;
- int res = 0; //select(fd + 1, &readset, NULL, NULL, &time);
- return res > 0;
-};
-
String OS_Unix::get_stdin_string(bool p_block) {
- String ret;
if (p_block) {
char buff[1024];
- ret = stdin_buf + fgets(buff, 1024, stdin);
+ String ret = stdin_buf + fgets(buff, 1024, stdin);
stdin_buf = "";
return ret;
- };
-
- while (has_data(stdin)) {
-
- char ch;
- read(fileno(stdin), &ch, 1);
- if (ch == '\n') {
- ret = stdin_buf;
- stdin_buf = "";
- return ret;
- } else {
- char str[2] = { ch, 0 };
- stdin_buf += str;
- };
- };
+ }
return "";
}
@@ -194,8 +166,6 @@ uint64_t OS_Unix::get_unix_time() const {
uint64_t OS_Unix::get_system_time_secs() const {
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
- //localtime(&tv_now.tv_usec);
- //localtime((const long *)&tv_now.tv_usec);
return uint64_t(tv_now.tv_sec);
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 908bc468a0..27ed53bb42 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1884,7 +1884,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene_filename != "" ? scene_filename : "unsaved scene"));
save_confirmation->popup_centered_minsize();
break;
+ } else {
+ tab_closing = editor_data.get_edited_scene();
}
+
} // fallthrough
case SCENE_TAB_CLOSE:
case FILE_SAVE_SCENE: {
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 90cbabcc4f..09bfa0aff0 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -101,7 +101,14 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
args.push_back(itos(screen_rect.position.x) + "," + itos(screen_rect.position.y));
} break;
case 1: { // centered
- Vector2 pos = screen_rect.position + ((screen_rect.size - desired_size) / 2).floor();
+ int display_scale = 1;
+#ifdef OSX_ENABLED
+ if (OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000) {
+ display_scale = 2;
+ }
+#endif
+
+ Vector2 pos = screen_rect.position + ((screen_rect.size / display_scale - desired_size) / 2).floor();
args.push_back("--position");
args.push_back(itos(pos.x) + "," + itos(pos.y));
} break;
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 4661fcf668..152eda7d91 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -587,9 +587,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Checkbox
Ref<StyleBoxFlat> sb_checkbox = style_menu->duplicate();
- // HACK, in reality, the checkbox draws the text over the icon by default, so the margin compensates that.
- const int cb_w = theme->get_icon("GuiChecked", "EditorIcons")->get_width() + default_margin_size;
- sb_checkbox->set_default_margin(MARGIN_LEFT, cb_w * EDSCALE);
+ sb_checkbox->set_default_margin(MARGIN_LEFT, default_margin_size * EDSCALE);
sb_checkbox->set_default_margin(MARGIN_RIGHT, default_margin_size * EDSCALE);
sb_checkbox->set_default_margin(MARGIN_TOP, default_margin_size * EDSCALE);
sb_checkbox->set_default_margin(MARGIN_BOTTOM, default_margin_size * EDSCALE);
@@ -625,6 +623,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
theme->set_icon("submenu", "PopupMenu", theme->get_icon("ArrowRight", "EditorIcons"));
+ theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons"));
+ theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon("GuiVisibilityVisible", "EditorIcons"));
+ theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons"));
theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size) * EDSCALE);
// Tree & ItemList background
diff --git a/editor/icons/icon_GUI_visibility_hidden.svg b/editor/icons/icon_GUI_visibility_hidden.svg
new file mode 100644
index 0000000000..2add2e9eb8
--- /dev/null
+++ b/editor/icons/icon_GUI_visibility_hidden.svg
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon_GUI_visibility_hidden.svg">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1027"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="14.75"
+ inkscape:cx="18.882384"
+ inkscape:cy="7.2939487"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
+ d="M 8.3320312 2.1328125 C 8.1166713 2.129146 7.900423 2.1368613 7.6855469 2.1542969 C 4.8418629 2.3850399 2.1034153 4.4237115 1.0449219 7.5722656 C 0.98765482 7.7577705 0.9856205 7.9559357 1.0390625 8.1425781 C 1.2458895 8.8664725 1.5352035 9.5092453 1.8730469 10.089844 L 12.501953 3.7890625 C 11.256805 2.6845102 9.797893 2.1577685 8.3320312 2.1328125 z M 14.554688 3.3046875 L 0.7421875 11.507812 L 1.4453125 12.695312 L 15.257812 4.4921875 L 14.554688 3.3046875 z M 14.169922 5.8847656 L 3.6171875 12.140625 C 4.9944165 13.294116 6.6188565 13.867188 8 13.867188 C 10.5 13.867188 13.836536 12.077978 14.960938 8.1425781 C 15.012856 7.9619931 15.012856 7.7704285 14.960938 7.5898438 C 14.731965 6.9583712 14.46336 6.3981967 14.169922 5.8847656 z "
+ id="path6" />
+</svg>
diff --git a/editor/icons/icon_GUI_visibility_visible.svg b/editor/icons/icon_GUI_visibility_visible.svg
new file mode 100644
index 0000000000..11ae563779
--- /dev/null
+++ b/editor/icons/icon_GUI_visibility_visible.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon_visibility_visible.svg">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1027"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="14.75"
+ inkscape:cx="15.823281"
+ inkscape:cy="12.108563"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <g
+ transform="translate(0 -1036.4)"
+ id="g4"
+ style="fill:#e0e0e0;fill-opacity:1">
+ <path
+ transform="translate(0,1036.4)"
+ d="M 8,2 C 5.4433,2 2.2093,3.9477 1.0449,7.7051 c -0.0572671,0.1855049 -0.059303,0.3836676 -0.00586,0.57031 1.1244,3.9354 4.4609,5.7246 6.9609,5.7246 2.5000004,0 5.8365004,-1.7892 6.9609004,-5.7246 0.05192,-0.180585 0.05192,-0.372145 0,-0.55273 -1.1003,-3.7876 -4.4066,-5.7227 -6.9609004,-5.7227 z m 0,2 c 2.209139,0 4,1.790861 4,4 0,2.209139 -1.790861,4 -4,4 C 5.790861,12 4,10.209139 4,8 4,5.790861 5.790861,4 8,4 Z M 8,6 C 6.8954305,6 6,6.8954305 6,8 6,9.1045695 6.8954305,10 8,10 9.1045695,10 10,9.1045695 10,8 10,6.8954305 9.1045695,6 8,6 Z"
+ style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
+ id="path6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccsccccssssssssss" />
+ </g>
+</svg>
diff --git a/editor/icons/icon_GUI_visibility_xray.svg b/editor/icons/icon_GUI_visibility_xray.svg
new file mode 100644
index 0000000000..1fd9fcf1b5
--- /dev/null
+++ b/editor/icons/icon_GUI_visibility_xray.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon_GUI_visibility_xray.svg">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1027"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="7.375"
+ inkscape:cx="43.019438"
+ inkscape:cy="-8.9853027"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <g
+ transform="translate(0.20338214,-1036.671)"
+ id="g4"
+ style="fill:#e0e0e0;fill-opacity:1" />
+ <path
+ id="path4154"
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.42799997;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 5.0107427,7.1191578 c -0.084872,0.2859445 -0.1282828,0.5825859 -0.128907,0.8808593 8.579e-4,0.263009 0.034983,0.5248532 0.101563,0.7792969 l 6.0312493,0 C 11.081887,8.5249547 11.116668,8.2631092 11.118164,8.0000171 11.11754,7.7017437 11.074129,7.4051023 10.989257,7.1191578 Z M 7.9999096,2.000005 c -2.5567,0 -5.7907,1.9477 -6.9551,5.7051 -0.057267,0.1855049 -0.059303,0.3836676 -0.00586,0.57031 1.1244,3.9354 4.4609,5.7246 6.9609,5.7246 2.4999994,0 5.8364994,-1.7892 6.9608994,-5.7246 0.05192,-0.180585 0.05192,-0.372145 0,-0.55273 -1.1003,-3.7876 -4.4066,-5.7227 -6.9608994,-5.7227 z m 0,2 c 2.2091384,0 3.9999994,1.790861 3.9999994,4 0,2.209139 -1.790861,4 -3.9999994,4 -2.209139,0 -4,-1.790861 -4,-4 0,-2.209139 1.790861,-4 4,-4 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccsccccsssss" />
+</svg>
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 150c184e90..ad22c12372 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -4730,6 +4730,7 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p
list.push_back(root_node);
} else {
drop_pos = p_point;
+ target_node = NULL;
_show_resource_type_selector();
return;
}
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index b855d2d4c4..80638c6f1e 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -2624,7 +2624,6 @@ void SpatialEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
-
} break;
case VIEW_DISPLAY_WIREFRAME: {
@@ -3756,6 +3755,10 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
}
}
+int SpatialEditor::get_skeleton_visibility_state() const {
+ return view_menu->get_popup()->get_item_state(view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON));
+}
+
void SpatialEditor::update_transform_gizmo() {
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -3800,6 +3803,21 @@ void SpatialEditor::update_transform_gizmo() {
}
}
+void _update_all_gizmos(Node *p_node) {
+ for (int i = p_node->get_child_count() - 1; 0 <= i; --i) {
+ Spatial *spatial_node = Object::cast_to<Spatial>(p_node->get_child(i));
+ if (spatial_node) {
+ spatial_node->update_gizmo();
+ }
+
+ _update_all_gizmos(p_node->get_child(i));
+ }
+}
+
+void SpatialEditor::update_all_gizmos() {
+ _update_all_gizmos(SceneTree::get_singleton()->get_root());
+}
+
Object *SpatialEditor::_get_editor_data(Object *p_what) {
Spatial *sp = Object::cast_to<Spatial>(p_what);
@@ -4247,6 +4265,28 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
_refresh_menu_icons();
} break;
+ case MENU_VISIBILITY_SKELETON: {
+
+ const int idx = view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON);
+ view_menu->get_popup()->toggle_item_statable(idx);
+
+ // Change icon
+ const int state = view_menu->get_popup()->get_item_state(idx);
+ switch (state) {
+ case 0:
+ view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_hidden"));
+ break;
+ case 1:
+ view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_visible"));
+ break;
+ case 2:
+ view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_xray"));
+ break;
+ }
+
+ update_all_gizmos();
+
+ } break;
}
}
@@ -4699,6 +4739,7 @@ void SpatialEditor::_notification(int p_what) {
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), get_icon("Panels3", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_icon("Panels3Alt", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_icon("Panels4", "EditorIcons"));
+ view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON), view_menu->get_popup()->get_icon("visibility_visible"));
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
@@ -5035,6 +5076,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
+ p->add_separator();
+ p->add_statable_item(TTR("Skeleton Gizmo visibility"), 3, 1, MENU_VISIBILITY_SKELETON);
+ p->add_separator();
+
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 0c2571017b..8369a5de54 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -92,7 +92,7 @@ class SpatialEditorViewport : public Control {
VIEW_DISPLAY_NORMAL,
VIEW_DISPLAY_WIREFRAME,
VIEW_DISPLAY_OVERDRAW,
- VIEW_DISPLAY_SHADELESS,
+ VIEW_DISPLAY_SHADELESS
};
public:
@@ -488,7 +488,8 @@ private:
MENU_VIEW_GRID,
MENU_VIEW_CAMERA_SETTINGS,
MENU_LOCK_SELECTED,
- MENU_UNLOCK_SELECTED
+ MENU_UNLOCK_SELECTED,
+ MENU_VISIBILITY_SKELETON
};
Button *tool_button[TOOL_MAX];
@@ -591,7 +592,10 @@ public:
Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; }
Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; }
+ int get_skeleton_visibility_state() const;
+
void update_transform_gizmo();
+ void update_all_gizmos();
void select_gizmo_highlight_axis(int p_axis);
void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 14e3b7cfb7..b187a9ae9d 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -70,7 +70,7 @@ void EditorResourceConversionPlugin::_bind_methods() {
mi.name = "_handles";
mi.return_val = PropertyInfo(Variant::BOOL, "");
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_converts_to"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_converts_to"));
}
String EditorResourceConversionPlugin::converts_to() const {
@@ -1939,6 +1939,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
type_button->get_popup()->connect("id_pressed", this, "_type_create_selected");
menu = memnew(PopupMenu);
+ menu->set_pass_on_modal_close_click(false);
add_child(menu);
menu->connect("id_pressed", this, "_menu_option");
@@ -4276,6 +4277,7 @@ PropertyEditor::PropertyEditor() {
set_physics_process(true);
custom_editor = memnew(CustomPropertyEditor);
+ custom_editor->set_pass_on_modal_close_click(false);
add_child(custom_editor);
tree->connect("custom_popup_edited", this, "_custom_editor_request");
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 2c0981ca30..25924212fd 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -484,7 +484,8 @@ void SceneTreeEditor::_selected_changed() {
void SceneTreeEditor::_deselect_items() {
// Clear currently elected items in scene tree dock.
- editor_selection->clear();
+ if (editor_selection)
+ editor_selection->clear();
}
void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_selected) {
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 3ffc61cb45..43010ed985 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -1316,6 +1316,34 @@ void SkeletonSpatialGizmo::redraw() {
Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton");
Ref<Material> material = create_material("skeleton_material", gizmo_color);
+ SpatialMaterial *sm = Object::cast_to<SpatialMaterial>(material.ptr());
+
+ { // Reset
+ Color c(sm->get_albedo());
+ c.a = 1;
+ sm->set_albedo(c);
+ }
+ if (sm) {
+ switch (SpatialEditor::get_singleton()->get_skeleton_visibility_state()) {
+ case 0: {
+ // Hidden
+ Color c(sm->get_albedo());
+ c.a = 0;
+ sm->set_albedo(c);
+ sm->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ } break;
+ case 1:
+ // Visible
+ sm->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, false);
+ sm->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MIN);
+ sm->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, false);
+ break;
+ case 2:
+ // x-ray
+ sm->set_on_top_of_alpha();
+ break;
+ }
+ }
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 7cc7521686..8c91a1a5de 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -540,20 +540,62 @@ static const char *s_ControllerMappings[] = {
"00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"02200090000000000000504944564944,8Bitdo NES30 PRO USB,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
+ "03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
+ "0d0f1100000000000000504944564944,REAL ARCADE PRO.3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "0d0f2200000000000000504944564944,REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "0d0f2700000000000000504944564944,FIGHTING STICK V3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "0d0f4000000000000000504944564944,Hori Fighting Stick Mini 3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b5,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b4,righttrigger:b6,",
"0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "0d0f4d00000000000000504944564944,HORIPAD3 A,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "0d0f5e00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a4,righttrigger:a3,",
+ "0d0f5f00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "0d0f6a00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,",
+ "0d0f6b00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "0d0f7000000000000000504944564944,REAL ARCADE PRO.4 VLX,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "0d0f8400000000000000504944564944,Fighting Commander 5,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
+ "0d0f8500000000000000504944564944,Fighting Commander 2016 PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "0d0f8700000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "0d0f8800000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,x:b0,y:b3,back:b9,guide:b12,start:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "0d0f8a00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,",
+ "0d0f8b00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "10008200000000000000504944564944,PS360+ v1.66,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:h0.4,lefttrigger:b6,righttrigger:b7,",
"10080100000000000000504944564944,PS1 USB,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
"100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,",
"10080300000000000000504944564944,PS2 USB,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,",
"10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,",
+ "120cf60e000000000000504944564944,P4 Wired Gamepad,a:b1,b:b2,x:b0,y:b3,back:b12,guide:b8,start:b9,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:h0.0,lefttrigger:b7,righttrigger:b6,",
"20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
+ "222c0020000000000000504944564944,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:a3,righttrigger:a4,",
+ "222c0023000000000000504944564944,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,x:b0,y:b3,back:b13,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
+ "222c0223000000000000504944564944,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "25090017000000000000504944564944,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b5,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b6,",
+ "25090128000000000000504944564944,Mayflash Arcade Stick,a:b1,b:b2,x:b5,y:b6,back:b8,start:b9,leftshoulder:b0,rightshoulder:b3,leftx:a0,lefty:a1,rightx:h0.4,righty:h0.0,lefttrigger:b4,righttrigger:b7,",
"25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,",
"2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"28040140000000000000504944564944,GamePad Pro USB,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,",
+ "300f0011000000000000504944564944,QanBa Arcade JoyStick 1008,x:b0,a:b1,b:b2,y:b3,back:b8,start:b10,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,",
"300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,",
+ "300f1201000000000000504944564944,Saitek Dual Analog Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,",
+ "300f1210000000000000504944564944,QanBa Joystick Plus,a:b0,b:b1,x:b2,y:b3,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,",
+ "300f1611000000000000504944564944,QanBa Arcade JoyStick 4018,a:b1,b:b2,x:b0,y:b3,back:b10,guide:b9,start:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "341a0104000000000000504944564944,QanBa Joystick Q4RAF,a:b5,b:b6,x:b1,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b0,rightshoulder:b3,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b7,",
"341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,",
+ "38071888000000000000504944564944,MadCatz SFIV FightStick PS3,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b7,righttrigger:b6,",
+ "38073888000000000000504944564944,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "38075032000000000000504944564944,Mad Catz FightPad PRO PS3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "38075082000000000000504944564944,Mad Catz FightPad PRO PS4,x:b0,a:b1,b:b2,y:b3,back:b13,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,",
+ "38076652000000000000504944564944,UnKnown,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "38078034000000000000504944564944,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "38078084000000000000504944564944,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
+ "38078134000000000000504944564944,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b7,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b4,",
+ "38078184000000000000504944564944,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a4,righttrigger:b7,",
+ "38078433000000000000504944564944,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
+ "38078483000000000000504944564944,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:b6,",
+ "38078532000000000000504944564944,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "45130010000000000000504944564944,Generic USB Joystick,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,",
"4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,",
"4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
@@ -563,28 +605,37 @@ static const char *s_ControllerMappings[] = {
"4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
"4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
+ "5e048e02000000000000504944564944,Controller (XBOX 360 For Windows),x:b2,a:b0,b:b1,y:b3,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,righttrigger:a2,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"63252305000000000000504944564944,USB Vibration Joystick (BM),x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "66660488000000000000504944564944,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpdown:b14,dpleft:b15,dpright:b13,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,",
"6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
+ "6f0e2401000000000000504944564944,INJUSTICE FightStick for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2",
"79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
- "79000600000000000000504944564944,NGS Phantom,a:b2,b:b3,y:b1,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
+ "79001100000000000000504944564944,Sega Saturn Gamepad,a:b1,b:b2,x:b4,y:b5,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a4,lefttrigger:b3,righttrigger:b0,",
+ "79001b18000000000000504944564944,Venom Arcade Joystick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,",
"79004318000000000000504944564944,Mayflash GameCube Controller Adapter,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
- "79000600000000000000504944564944,Generic Speedlink,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
"83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
"88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,",
"8f0e0300000000000000504944564944,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
"8f0e0d31000000000000504944564944,Multilaser JS071 USB,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "8f0e1030000000000000504944564944,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,x:b3,y:b4,start:b9,leftshoulder:b6,rightshoulder:b2,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b5,righttrigger:b7,",
"8f0e1200000000000000504944564944,Acme,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
"9000318000000000000504944564944,Mayflash Wiimote PC Adapter,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1,",
+ "9b280500000000000000504944564944,Saturn_Adapter_2.0,a:b1,b:b2,x:b0,y:b3,start:b9,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b5,",
"a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "bd1215d0000000000000504944564944,Nintendo Retrolink USB Super SNES Classic Controller,y:b0,b:b1,a:b2,x:b3,leftshoulder:b4,rightshoulder:b5,start:b9,back:b8,leftx:a0,lefty:a1,",
"c0111352000000000000504944564944,Battalife Joystick,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1,",
"c911f055000000000000504944564944,GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "d8140862000000000000504944564944,HitBox Edition Cthulhu+,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b5,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b4,righttrigger:b6,",
+ "d81d0b00000000000000504944564944,BUFFALO BSGP1601 Series ,x:b4,a:b5,b:b3,y:b2,back:b12,start:b13,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b6,rightshoulder:b9,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "d81d0f00000000000000504944564944,iBUFFALO BSGP1204 Series,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "d81d1000000000000000504944564944,iBUFFALO BSGP1204P Series,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"ff113133000000000000504944564944,Gembird JPD-DualForce,a:b2,b:b3,x:b0,y:b1,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,leftstick:b10,rightstick:b11,",
- "ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,",
"ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
#endif
@@ -595,10 +646,12 @@ static const char *s_ControllerMappings[] = {
"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,",
"0d0f0000000000004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4,",
+ "10080000000000000100000000000000,Twin USB Joystick,a:b4,b:b2,x:b6,y:b0,back:b16,start:b18,leftstick:b20,rightstick:b22,leftshoulder:b12,rightshoulder:b14,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a2,rightx:a6,righty:a4,lefttrigger:b8,righttrigger:b10,",
"10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
+ "4c05000000000000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
"4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
"4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
@@ -607,9 +660,9 @@ static const char *s_ControllerMappings[] = {
"5e04000000000000dd02000000000000,Xbox One Wired Controller,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"5e04000000000000e002000000000000,Xbox Wireless Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"5e04000000000000ea02000000000000,Xbox Wireless Controller,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
- "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
+ "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
- "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
+ "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
"79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,",
"79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,",
@@ -618,6 +671,7 @@ static const char *s_ControllerMappings[] = {
"83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
"891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
"8f0e0000000000000300000000000000,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
"ad1b00000000000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
"b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
@@ -629,7 +683,7 @@ static const char *s_ControllerMappings[] = {
"0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"030000000d0f00000d00000000010000,hori,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,",
- "030000000d0f00001000000011010000,HORI CO.,LTD. FIGHTING STICK 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7",
+ "030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7",
"030000000d0f00002200000011010000,HORI CO.,LTD. REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,",
"030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,",
@@ -638,13 +692,16 @@ static const char *s_ControllerMappings[] = {
"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,",
"03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
"03000000280400000140000000010000,Gravis GamePad Pro USB ,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,",
+ "03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,x:b0,a:b2,b:b3,y:b1,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,",
"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
"030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
"030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
"030000004c050000c405000011810000,Sony Computer Entertainment Wireless Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:h0.1,rightshoulder:b5,rightx:a3,start:b9,righty:a4,dpleft:h0.8,lefttrigger:a2,x:b3,dpup:h0.1,back:b8,leftstick:b11,leftshoulder:b4,y:b2,a:b0,dpright:h0.2,righttrigger:a5,b:b1,",
"030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
+ "030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,y:b2,x:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,guide:b10,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
@@ -684,14 +741,15 @@ static const char *s_ControllerMappings[] = {
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "03000000780000000600000010010000,Microntek USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,",
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"03000000790000001100000010010000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
- "03000000790000001100000010010000,RetroLink Saturn Classic Controller,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
"030000008916000001fd000024010000,Razer Onza Classic Edition,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,x:b1,a:b0,b:b4,y:b5,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,",
"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,",
"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
@@ -701,7 +759,9 @@ static const char *s_ControllerMappings[] = {
"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5,",
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
- "03000000c9110000f055000011010000,HJC Game GAMEPAD,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b4,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,x:b13,y:b11,back:b4,start:b5,leftstick:b14,rightstick:b15,leftshoulder:b9,rightshoulder:b8,dpup:b0,dpdown:b2,dpleft:b3,dpright:b1,leftx:a1,lefty:a0,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,y:b0,x:b1,b:b3,a:b4,leftshoulder:b2,rightshoulder:b5,back:b6,start:b7,guide:b9,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftx:a0,lefty:a1,",
+ "03000000c9110000f055000011010000,HJC Game GAMEPAD,x:b2,a:b0,b:b1,y:b3,back:b4,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,",
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,",
"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,",
"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
@@ -709,6 +769,7 @@ static const char *s_ControllerMappings[] = {
"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,",
"03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,",
"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
"05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",
@@ -719,11 +780,15 @@ static const char *s_ControllerMappings[] = {
"050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
"050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
+ "050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,y:b2,x:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,guide:b10,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
+ "05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
+ "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,",
"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,",
"05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,",
"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
+ "06000000adde0000efbe000002010000,Hidromancer Game Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
#endif
#if defined(__ANDROID__)
diff --git a/main/splash_sponsors.png b/main/splash_sponsors.png
new file mode 100644
index 0000000000..d8677f1749
--- /dev/null
+++ b/main/splash_sponsors.png
Binary files differ
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 5750dc2acd..9d2fb1fce4 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -50,14 +50,21 @@ struct GodotFilterCallback : public btOverlapFilterCallback {
struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback {
const Set<RID> *m_exclude;
bool m_pickRay;
+ int m_shapeId;
public:
GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude) :
btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld),
m_exclude(p_exclude),
- m_pickRay(false) {}
+ m_pickRay(false),
+ m_shapeId(0) {}
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
+
+ virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) {
+ m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
+ }
};
// store all colliding object
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index c1f6e81734..3ce4b294db 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -97,7 +97,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V
B_TO_G(btResult.m_hitNormalWorld.normalize(), r_result.normal);
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btResult.m_collisionObject->getUserPointer());
if (gObj) {
- r_result.shape = 0;
+ r_result.shape = btResult.m_shapeId;
r_result.rid = gObj->get_self();
r_result.collider_id = gObj->get_instance_id();
r_result.collider = 0 == r_result.collider_id ? NULL : ObjectDB::get_instance(r_result.collider_id);
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 67e00f4952..255413bf2c 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1557,12 +1557,15 @@ public:
encode_uint32(cl.size(), &clf[0]);
for (int i = 0; i < cl.size(); i++) {
+ print_line(itos(i) + " param: " + cl[i]);
CharString txt = cl[i].utf8();
int base = clf.size();
- clf.resize(base + 4 + txt.length());
- encode_uint32(txt.length(), &clf[base]);
- copymem(&clf[base + 4], txt.ptr(), txt.length());
- print_line(itos(i) + " param: " + cl[i]);
+ int length = txt.length();
+ if (!length)
+ continue;
+ clf.resize(base + 4 + length);
+ encode_uint32(length, &clf[base]);
+ copymem(&clf[base + 4], txt.ptr(), length);
}
zip_fileinfo zipfi = get_zip_fileinfo();
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index b591f80aa7..111cdce2de 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -35,21 +35,6 @@
#include "main/main.h"
#include "os_iphone.h"
-#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
-#include "modules/FacebookScorer_ios/FacebookScorer.h"
-#endif
-
-#ifdef MODULE_GAME_ANALYTICS_ENABLED
-#import "modules/game_analytics/ios/MobileAppTracker.framework/Headers/MobileAppTracker.h"
-//#import "modules/game_analytics/ios/MobileAppTracker.h"
-#import <AdSupport/AdSupport.h>
-#endif
-
-#ifdef MODULE_PARSE_ENABLED
-#import "FBSDKCoreKit/FBSDKCoreKit.h"
-#import <Parse/Parse.h>
-#endif
-
#import "GameController/GameController.h"
#define kFilteringFactor 0.1
@@ -418,11 +403,7 @@ static int frame_count = 0;
OSIPhone::get_singleton()->set_unique_id(String::utf8([uuid UTF8String]));
}; break;
- /*
- case 1: {
- ++frame_count;
- }; break;
-*/
+
case 1: {
Main::setup2();
@@ -453,11 +434,7 @@ static int frame_count = 0;
}
}; break;
- /*
- case 3: {
- ++frame_count;
- }; break;
-*/
+
case 2: {
Main::start();
@@ -558,15 +535,11 @@ static int frame_count = 0;
};
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
-
- printf("****************** did receive memory warning!\n");
OS::get_singleton()->get_main_loop()->notification(
MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
};
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
-
- printf("**************** app delegate init\n");
CGRect rect = [[UIScreen mainScreen] bounds];
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
@@ -603,7 +576,7 @@ static int frame_count = 0;
if (err != 0) {
// bail, things did not go very well for us, should probably output a message on screen with our error code...
exit(0);
- return;
+ return FALSE;
};
view_controller = [[ViewController alloc] init];
@@ -641,43 +614,10 @@ static int frame_count = 0;
// prevent to stop music in another background app
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
-#ifdef MODULE_GAME_ANALYTICS_ENABLED
- printf("********************* didFinishLaunchingWithOptions\n");
- if (!ProjectSettings::get_singleton()->has("mobileapptracker/advertiser_id")) {
- return;
- }
- if (!ProjectSettings::get_singleton()->has("mobileapptracker/conversion_key")) {
- return;
- }
-
- String adid = GLOBAL_DEF("mobileapptracker/advertiser_id", "");
- String convkey = GLOBAL_DEF("mobileapptracker/conversion_key", "");
-
- NSString *advertiser_id =
- [NSString stringWithUTF8String:adid.utf8().get_data()];
- NSString *conversion_key =
- [NSString stringWithUTF8String:convkey.utf8().get_data()];
-
- // Account Configuration info - must be set
- [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id
- MATConversionKey:conversion_key];
-
- // Used to pass us the IFA, enables highly accurate 1-to-1 attribution.
- // Required for many advertising networks.
- [MobileAppTracker
- setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager]
- advertisingIdentifier]
- advertisingTrackingEnabled:[[ASIdentifierManager sharedManager]
- isAdvertisingTrackingEnabled]];
-
-#endif
return TRUE;
};
- (void)applicationWillTerminate:(UIApplication *)application {
-
- printf("********************* will terminate\n");
-
[self deinitGameControllers];
if (motionInitialised) {
@@ -692,7 +632,6 @@ static int frame_count = 0;
};
- (void)applicationDidEnterBackground:(UIApplication *)application {
- printf("********************* did enter background\n");
///@TODO maybe add pause motionManager? and where would we unpause it?
if (OS::get_singleton()->get_main_loop())
@@ -706,24 +645,17 @@ static int frame_count = 0;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
- printf("********************* did enter foreground\n");
// OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
[view_controller.view startAnimation];
}
- (void)applicationWillResignActive:(UIApplication *)application {
- printf("********************* will resign active\n");
// OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
[view_controller.view
stopAnimation]; // FIXME: pause seems to be recommended elsewhere
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
- printf("********************* did become active\n");
-#ifdef MODULE_GAME_ANALYTICS_ENABLED
- printf("********************* mobile app tracker found\n");
- [MobileAppTracker measureSession];
-#endif
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(
MainLoop::NOTIFICATION_WM_FOCUS_IN);
@@ -739,65 +671,6 @@ static int frame_count = 0;
AudioDriverCoreAudio::get_singleton()->start();
}
-- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
-#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
- return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
-#else
- return false;
-#endif
-}
-
-// For 4.2+ support
-- (BOOL)application:(UIApplication *)application
- openURL:(NSURL *)url
- sourceApplication:(NSString *)sourceApplication
- annotation:(id)annotation {
-#ifdef MODULE_PARSE_ENABLED
- NSLog(@"Handling application openURL");
- return
- [[FBSDKApplicationDelegate sharedInstance] application:application
- openURL:url
- sourceApplication:sourceApplication
- annotation:annotation];
-#endif
-
-#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
- return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
-#else
- return false;
-#endif
-}
-
-- (void)application:(UIApplication *)application
- didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
-#ifdef MODULE_PARSE_ENABLED
- // Store the deviceToken in the current installation and save it to Parse.
- PFInstallation *currentInstallation = [PFInstallation currentInstallation];
- // NSString* token = [[NSString alloc] initWithData:deviceToken
- // encoding:NSUTF8StringEncoding];
- NSLog(@"Device Token : %@ ", deviceToken);
- [currentInstallation setDeviceTokenFromData:deviceToken];
- [currentInstallation saveInBackground];
-#endif
-}
-
-- (void)application:(UIApplication *)application
- didReceiveRemoteNotification:(NSDictionary *)userInfo {
-#ifdef MODULE_PARSE_ENABLED
- [PFPush handlePush:userInfo];
- NSDictionary *aps =
- [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-
- NSLog(@"Push Notification Payload (app active) %@", aps);
- [defaults setObject:aps forKey:@"notificationInfo"];
- [defaults synchronize];
- if (application.applicationState == UIApplicationStateInactive) {
- [PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
- }
-#endif
-}
-
- (void)dealloc {
[window release];
[super dealloc];
diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm
index 25f4e1e166..31d3659802 100644
--- a/platform/iphone/in_app_store.mm
+++ b/platform/iphone/in_app_store.mm
@@ -31,10 +31,6 @@
#include "in_app_store.h"
-#ifdef MODULE_FUSEBOXX_ENABLED
-#import "modules/fuseboxx/ios/FuseSDK.h"
-#endif
-
extern "C" {
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
@@ -224,10 +220,6 @@ Error InAppStore::request_product_info(Variant p_params) {
[pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier];
}
-#ifdef MODULE_FUSEBOXX_ENABLED
- printf("Registering transaction on Fuseboxx!\n");
- [FuseSDK registerInAppPurchase:transaction];
-#endif
}; break;
case SKPaymentTransactionStateFailed: {
printf("status transaction failed!\n");
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 49a2f14bef..b59fab7088 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -195,14 +195,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
XIDeviceInfo *dev = &info[i];
if (!dev->enabled)
continue;
- /*if (dev->use != XIMasterPointer)
- continue;*/
+ if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave))
+ continue;
bool direct_touch = false;
for (int j = 0; j < dev->num_classes; j++) {
if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
direct_touch = true;
- printf("%d) %d %s\n", i, dev->attachment, dev->name);
break;
}
}
@@ -215,7 +214,7 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
XIFreeDeviceInfo(info);
if (!touch.devices.size()) {
- fprintf(stderr, "No suitable touch device found\n");
+ fprintf(stderr, "No touch devices found\n");
}
}
}
@@ -359,7 +358,7 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
// Must be alive after this block
static unsigned char mask_data[XIMaskLen(XI_LASTEVENT)] = {};
- touch.event_mask.deviceid = XIAllMasterDevices;
+ touch.event_mask.deviceid = XIAllDevices;
touch.event_mask.mask_len = sizeof(mask_data);
touch.event_mask.mask = mask_data;
@@ -370,12 +369,14 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
XISelectEvents(x11_display, x11_window, &touch.event_mask, 1);
- XIClearMask(touch.event_mask.mask, XI_TouchOwnership);
+ // Disabled by now since grabbing also blocks mouse events
+ // (they are received as extended events instead of standard events)
+ /*XIClearMask(touch.event_mask.mask, XI_TouchOwnership);
// Grab touch devices to avoid OS gesture interference
for (int i = 0; i < touch.devices.size(); ++i) {
XIGrabDevice(x11_display, touch.devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &touch.event_mask);
- }
+ }*/
}
#endif
@@ -1512,7 +1513,7 @@ void OS_X11::process_xevents() {
#ifdef TOUCH_ENABLED
if (XGetEventData(x11_display, &event.xcookie)) {
- if (event.xcookie.extension == touch.opcode) {
+ if (event.xcookie.type == GenericEvent && event.xcookie.extension == touch.opcode) {
XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
int index = event_data->detail;
@@ -1521,7 +1522,8 @@ void OS_X11::process_xevents() {
switch (event_data->evtype) {
case XI_TouchBegin: // Fall-through
- XIAllowTouchEvents(x11_display, event_data->deviceid, event_data->detail, x11_window, XIAcceptTouch);
+ // Disabled hand-in-hand with the grabbing
+ //XIAllowTouchEvents(x11_display, event_data->deviceid, event_data->detail, x11_window, XIAcceptTouch);
case XI_TouchEnd: {
@@ -1567,9 +1569,8 @@ void OS_X11::process_xevents() {
} break;
}
}
-
- XFreeEventData(x11_display, &event.xcookie);
}
+ XFreeEventData(x11_display, &event.xcookie);
#endif
switch (event.type) {
@@ -1615,10 +1616,10 @@ void OS_X11::process_xevents() {
GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime);
}
#ifdef TOUCH_ENABLED
- // Grab touch devices to avoid OS gesture interference
- for (int i = 0; i < touch.devices.size(); ++i) {
+ // Grab touch devices to avoid OS gesture interference
+ /*for (int i = 0; i < touch.devices.size(); ++i) {
XIGrabDevice(x11_display, touch.devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &touch.event_mask);
- }
+ }*/
#endif
if (xic) {
XSetICFocus(xic);
@@ -1638,9 +1639,9 @@ void OS_X11::process_xevents() {
}
#ifdef TOUCH_ENABLED
// Ungrab touch devices so input works as usual while we are unfocused
- for (int i = 0; i < touch.devices.size(); ++i) {
+ /*for (int i = 0; i < touch.devices.size(); ++i) {
XIUngrabDevice(x11_display, touch.devices[i], CurrentTime);
- }
+ }*/
// Release every pointer to avoid sticky points
for (Map<int, Vector2>::Element *E = touch.state.front(); E; E = E->next()) {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 5a32a3d0f0..1e34372d1e 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "tile_map.h"
+
#include "io/marshalls.h"
#include "method_bind_ext.gen.inc"
#include "os/os.h"
@@ -169,10 +170,12 @@ void TileMap::set_cell_size(Size2 p_size) {
_recreate_quadrants();
emit_signal("settings_changed");
}
+
Size2 TileMap::get_cell_size() const {
return cell_size;
}
+
void TileMap::set_quadrant_size(int p_size) {
ERR_FAIL_COND(p_size < 1);
@@ -182,32 +185,12 @@ void TileMap::set_quadrant_size(int p_size) {
_recreate_quadrants();
emit_signal("settings_changed");
}
+
int TileMap::get_quadrant_size() const {
return quadrant_size;
}
-void TileMap::set_center_x(bool p_enable) {
-
- center_x = p_enable;
- _recreate_quadrants();
- emit_signal("settings_changed");
-}
-bool TileMap::get_center_x() const {
-
- return center_x;
-}
-void TileMap::set_center_y(bool p_enable) {
-
- center_y = p_enable;
- _recreate_quadrants();
- emit_signal("settings_changed");
-}
-bool TileMap::get_center_y() const {
-
- return center_y;
-}
-
void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) {
Size2 s = p_sc;
@@ -1473,12 +1456,6 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tile_origin", "origin"), &TileMap::set_tile_origin);
ClassDB::bind_method(D_METHOD("get_tile_origin"), &TileMap::get_tile_origin);
- ClassDB::bind_method(D_METHOD("set_center_x", "enable"), &TileMap::set_center_x);
- ClassDB::bind_method(D_METHOD("get_center_x"), &TileMap::get_center_x);
-
- ClassDB::bind_method(D_METHOD("set_center_y", "enable"), &TileMap::set_center_y);
- ClassDB::bind_method(D_METHOD("get_center_y"), &TileMap::get_center_y);
-
ClassDB::bind_method(D_METHOD("set_clip_uv", "enable"), &TileMap::set_clip_uv);
ClassDB::bind_method(D_METHOD("get_clip_uv"), &TileMap::get_clip_uv);
@@ -1580,8 +1557,6 @@ TileMap::TileMap() {
quadrant_order_dirty = false;
quadrant_size = 16;
cell_size = Size2(64, 64);
- center_x = false;
- center_y = false;
collision_layer = 1;
collision_mask = 1;
friction = 1;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 11d9915cb6..e5608884c4 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -68,7 +68,6 @@ private:
Ref<TileSet> tile_set;
Size2i cell_size;
int quadrant_size;
- bool center_x, center_y;
Mode mode;
Transform2D custom_transform;
HalfOffset half_offset;
@@ -231,11 +230,6 @@ public:
void set_quadrant_size(int p_size);
int get_quadrant_size() const;
- void set_center_x(bool p_enable);
- bool get_center_x() const;
- void set_center_y(bool p_enable);
- bool get_center_y() const;
-
void set_cell(int p_x, int p_y, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false, Vector2 p_autotile_coord = Vector2());
int get_cell(int p_x, int p_y) const;
bool is_cell_x_flipped(int p_x, int p_y) const;
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 1fa03f81f4..47977f0283 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -55,6 +55,10 @@ Size2 Button::get_minimum_size() const {
return get_stylebox("normal")->get_minimum_size() + minsize;
}
+void Button::_set_internal_margin(Margin p_margin, float p_value) {
+ _internal_margin[p_margin] = p_value;
+}
+
void Button::_notification(int p_what) {
if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
@@ -136,11 +140,11 @@ void Button::_notification(int p_what) {
Point2 icon_ofs = (!_icon.is_null()) ? Point2(_icon->get_width() + get_constant("hseparation"), 0) : Point2();
int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width;
- Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size(xl_text)) / 2.0;
+ Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size(xl_text) - Point2(_internal_margin[MARGIN_RIGHT] - _internal_margin[MARGIN_LEFT], 0)) / 2.0;
switch (align) {
case ALIGN_LEFT: {
- text_ofs.x = style->get_margin(MARGIN_LEFT) + icon_ofs.x;
+ text_ofs.x = style->get_margin(MARGIN_LEFT) + icon_ofs.x + _internal_margin[MARGIN_LEFT] + get_constant("hseparation");
text_ofs.y += style->get_offset().y;
} break;
case ALIGN_CENTER: {
@@ -150,7 +154,11 @@ void Button::_notification(int p_what) {
text_ofs += style->get_offset();
} break;
case ALIGN_RIGHT: {
- text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x;
+ if (_internal_margin[MARGIN_RIGHT] > 0) {
+ text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x - _internal_margin[MARGIN_RIGHT] - get_constant("hseparation");
+ } else {
+ text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x;
+ }
text_ofs.y += style->get_offset().y;
} break;
}
@@ -162,7 +170,11 @@ void Button::_notification(int p_what) {
int valign = size.height - style->get_minimum_size().y;
if (is_disabled())
color_icon.a = 0.4;
- _icon->draw(ci, style->get_offset() + Point2(0, Math::floor((valign - _icon->get_height()) / 2.0)), color_icon);
+ if (_internal_margin[MARGIN_LEFT] > 0) {
+ _icon->draw(ci, style->get_offset() + Point2(_internal_margin[MARGIN_LEFT] + get_constant("hseparation"), Math::floor((valign - _icon->get_height()) / 2.0)), color_icon);
+ } else {
+ _icon->draw(ci, style->get_offset() + Point2(0, Math::floor((valign - _icon->get_height()) / 2.0)), color_icon);
+ }
}
}
}
@@ -253,7 +265,7 @@ void Button::_bind_methods() {
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_button_icon", "get_button_icon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text");
- ADD_PROPERTYNO(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align");
}
Button::Button(const String &p_text) {
@@ -263,6 +275,10 @@ Button::Button(const String &p_text) {
set_mouse_filter(MOUSE_FILTER_STOP);
set_text(p_text);
align = ALIGN_CENTER;
+
+ for (int i = 0; i < 4; i++) {
+ _internal_margin[i] = 0;
+ }
}
Button::~Button() {
diff --git a/scene/gui/button.h b/scene/gui/button.h
index dd6e730b86..35488582de 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -53,9 +53,11 @@ private:
Ref<Texture> icon;
bool clip_text;
TextAlign align;
+ float _internal_margin[4];
protected:
virtual Size2 get_minimum_size() const;
+ void _set_internal_margin(Margin p_margin, float p_value);
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 00f6153062..bf8156b92b 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -31,18 +31,54 @@
#include "servers/visual_server.h"
+Size2 CheckBox::get_icon_size() const {
+ Ref<Texture> checked = Control::get_icon("checked");
+ Ref<Texture> unchecked = Control::get_icon("unchecked");
+ Ref<Texture> radio_checked = Control::get_icon("radio_checked");
+ Ref<Texture> radio_unchecked = Control::get_icon("radio_unchecked");
+
+ Size2 tex_size = Size2(0, 0);
+ if (!checked.is_null())
+ tex_size = Size2(checked->get_width(), checked->get_height());
+ if (!unchecked.is_null())
+ tex_size = Size2(MAX(tex_size.width, unchecked->get_width()), MAX(tex_size.height, unchecked->get_height()));
+ if (!radio_checked.is_null())
+ tex_size = Size2(MAX(tex_size.width, radio_checked->get_width()), MAX(tex_size.height, radio_checked->get_height()));
+ if (!radio_unchecked.is_null())
+ tex_size = Size2(MAX(tex_size.width, radio_unchecked->get_width()), MAX(tex_size.height, radio_unchecked->get_height()));
+ return tex_size;
+}
+
+Size2 CheckBox::get_minimum_size() const {
+
+ Size2 minsize = Button::get_minimum_size();
+ Size2 tex_size = get_icon_size();
+ minsize.width += tex_size.width;
+ if (get_text().length() > 0) {
+ minsize.width += get_constant("hseparation");
+ }
+ Ref<StyleBox> sb = get_stylebox("normal");
+ minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(MARGIN_TOP) + sb->get_margin(MARGIN_BOTTOM));
+
+ return minsize;
+}
+
void CheckBox::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
+ if (p_what == NOTIFICATION_THEME_CHANGED) {
+
+ _set_internal_margin(MARGIN_LEFT, get_icon_size().width);
+ } else if (p_what == NOTIFICATION_DRAW) {
RID ci = get_canvas_item();
Ref<Texture> on = Control::get_icon(is_radio() ? "radio_checked" : "checked");
Ref<Texture> off = Control::get_icon(is_radio() ? "radio_unchecked" : "unchecked");
+ Ref<StyleBox> sb = get_stylebox("normal");
Vector2 ofs;
- ofs.x = 0;
- ofs.y = int((get_size().height - on->get_height()) / 2);
+ ofs.x = sb->get_margin(MARGIN_LEFT);
+ ofs.y = int((get_size().height - get_icon_size().height) / 2);
if (is_pressed())
on->draw(ci, ofs);
@@ -60,6 +96,7 @@ CheckBox::CheckBox(const String &p_text) :
Button(p_text) {
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
+ _set_internal_margin(MARGIN_LEFT, get_icon_size().width);
}
CheckBox::~CheckBox() {
diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h
index 4da06be8d1..3d3f170e8c 100644
--- a/scene/gui/check_box.h
+++ b/scene/gui/check_box.h
@@ -39,6 +39,8 @@ class CheckBox : public Button {
GDCLASS(CheckBox, Button);
protected:
+ Size2 get_icon_size() const;
+ Size2 get_minimum_size() const;
void _notification(int p_what);
bool is_radio();
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index 77fdedd5e5..641d2d4f01 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -32,10 +32,7 @@
#include "print_string.h"
#include "servers/visual_server.h"
-Size2 CheckButton::get_minimum_size() const {
-
- Size2 minsize = Button::get_minimum_size();
-
+Size2 CheckButton::get_icon_size() const {
Ref<Texture> on = Control::get_icon("on");
Ref<Texture> off = Control::get_icon("off");
Size2 tex_size = Size2(0, 0);
@@ -43,15 +40,29 @@ Size2 CheckButton::get_minimum_size() const {
tex_size = Size2(on->get_width(), on->get_height());
if (!off.is_null())
tex_size = Size2(MAX(tex_size.width, off->get_width()), MAX(tex_size.height, off->get_height()));
- minsize += Size2(tex_size.width + get_constant("hseparation"), 0);
- minsize.height = MAX(minsize.height, tex_size.height);
+ return tex_size;
+}
+
+Size2 CheckButton::get_minimum_size() const {
- return get_stylebox("normal")->get_minimum_size() + minsize;
+ Size2 minsize = Button::get_minimum_size();
+ Size2 tex_size = get_icon_size();
+ minsize.width += tex_size.width;
+ if (get_text().length() > 0) {
+ minsize.width += get_constant("hseparation");
+ }
+ Ref<StyleBox> sb = get_stylebox("normal");
+ minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(MARGIN_TOP) + sb->get_margin(MARGIN_BOTTOM));
+
+ return minsize;
}
void CheckButton::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
+ if (p_what == NOTIFICATION_THEME_CHANGED) {
+
+ _set_internal_margin(MARGIN_RIGHT, get_icon_size().width);
+ } else if (p_what == NOTIFICATION_DRAW) {
RID ci = get_canvas_item();
@@ -59,10 +70,11 @@ void CheckButton::_notification(int p_what) {
Ref<Texture> off = Control::get_icon("off");
Ref<StyleBox> sb = get_stylebox("normal");
- Size2 sb_ofs = Size2(sb->get_margin(MARGIN_RIGHT), sb->get_margin(MARGIN_TOP));
Vector2 ofs;
- ofs.x = get_minimum_size().width - (on->get_width() + sb_ofs.width);
- ofs.y = sb_ofs.height;
+ Size2 tex_size = get_icon_size();
+
+ ofs.x = get_size().width - (tex_size.width + sb->get_margin(MARGIN_RIGHT));
+ ofs.y = (get_size().height - tex_size.height) / 2;
if (is_pressed())
on->draw(ci, ofs);
@@ -75,6 +87,8 @@ CheckButton::CheckButton() {
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
+
+ _set_internal_margin(MARGIN_RIGHT, get_icon_size().width);
}
CheckButton::~CheckButton() {
diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h
index eb68943fe7..3103a40d3c 100644
--- a/scene/gui/check_button.h
+++ b/scene/gui/check_button.h
@@ -39,6 +39,7 @@ class CheckButton : public Button {
GDCLASS(CheckButton, Button);
protected:
+ Size2 get_icon_size() const;
virtual Size2 get_minimum_size() const;
void _notification(int p_what);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index adca78d1d4..81d2b6731f 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2470,6 +2470,16 @@ Control::MouseFilter Control::get_mouse_filter() const {
return data.mouse_filter;
}
+void Control::set_pass_on_modal_close_click(bool p_pass_on) {
+
+ data.pass_on_modal_close_click = p_pass_on;
+}
+
+bool Control::pass_on_modal_close_click() const {
+
+ return data.pass_on_modal_close_click;
+}
+
Control *Control::get_focus_owner() const {
ERR_FAIL_COND_V(!is_inside_tree(), NULL);
@@ -2934,6 +2944,7 @@ Control::Control() {
data.parent = NULL;
data.mouse_filter = MOUSE_FILTER_STOP;
+ data.pass_on_modal_close_click = true;
data.SI = NULL;
data.MI = NULL;
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 92d1c969fc..9ac0eb0be3 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -165,6 +165,8 @@ private:
bool pending_min_size_update;
Point2 custom_minimum_size;
+ bool pass_on_modal_close_click;
+
MouseFilter mouse_filter;
bool clip_contents;
@@ -401,6 +403,9 @@ public:
void set_mouse_filter(MouseFilter p_filter);
MouseFilter get_mouse_filter() const;
+ void set_pass_on_modal_close_click(bool p_pass_on);
+ bool pass_on_modal_close_click() const;
+
/* SKINNING */
void add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon);
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index ac450616d6..d850553957 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -111,6 +111,7 @@ MenuButton::MenuButton() {
popup->hide();
add_child(popup);
popup->set_as_toplevel(true);
+ popup->set_pass_on_modal_close_click(false);
connect("button_up", popup, "call_deferred", make_binds("grab_click_focus"));
set_process_unhandled_key_input(true);
set_action_mode(ACTION_MODE_BUTTON_PRESS);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index b4d0799945..70f3d9ca83 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -323,6 +323,7 @@ OptionButton::OptionButton() {
popup = memnew(PopupMenu);
popup->hide();
popup->set_as_toplevel(true);
+ popup->set_pass_on_modal_close_click(false);
add_child(popup);
popup->connect("id_pressed", this, "_selected");
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 4ee6f93c9a..e37cdd5cc9 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -624,6 +624,20 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bo
update();
}
+void PopupMenu::add_statable_item(const String &p_label, int p_max_states, int p_default_state, int p_ID, uint32_t p_accel) {
+
+ Item item;
+ item.text = p_label;
+ item.xl_text = tr(p_label);
+ item.accel = p_accel;
+ item.ID = p_ID;
+ item.checkable = false;
+ item.max_states = p_max_states;
+ item.state = p_default_state;
+ items.push_back(item);
+ update();
+}
+
void PopupMenu::set_item_text(int p_idx, const String &p_text) {
ERR_FAIL_INDEX(p_idx, items.size());
@@ -772,6 +786,11 @@ Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const {
return items[p_idx].shortcut;
}
+int PopupMenu::get_item_state(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, items.size(), -1);
+ return items[p_idx].state;
+}
+
void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {
ERR_FAIL_INDEX(p_idx, items.size());
@@ -820,6 +839,27 @@ void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
update();
}
+void PopupMenu::set_item_statable(int p_idx, int p_state) {
+
+ ERR_FAIL_INDEX(p_idx, items.size());
+ items[p_idx].state = p_state;
+ update();
+}
+
+void PopupMenu::toggle_item_statable(int p_idx) {
+
+ ERR_FAIL_INDEX(p_idx, items.size());
+ if (0 >= items[p_idx].max_states) {
+ return;
+ }
+
+ ++items[p_idx].state;
+ if (items[p_idx].max_states <= items[p_idx].state)
+ items[p_idx].state = 0;
+
+ update();
+}
+
bool PopupMenu::is_item_checkable(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].checkable;
@@ -895,21 +935,34 @@ void PopupMenu::activate_item(int p_item) {
while (pop) {
// We close all parents that are chained together,
// with hide_on_item_selection enabled
- if ((items[p_item].checkable && hide_on_checkable_item_selection && pop->is_hide_on_checkable_item_selection()) || (!items[p_item].checkable && hide_on_item_selection && pop->is_hide_on_item_selection())) {
- pop->hide();
- next = next->get_parent();
- pop = Object::cast_to<PopupMenu>(next);
- } else {
- // Break out of loop when the next parent has
- // hide_on_item_selection disabled
+
+ if (items[p_item].checkable) {
+ if (!hide_on_checkable_item_selection || !pop->is_hide_on_checkable_item_selection())
+ break;
+ } else if (0 < items[p_item].max_states) {
+ if (!hide_on_statable_item_selection || !pop->is_hide_on_statable_item_selection())
+ break;
+ } else if (!hide_on_item_selection || !pop->is_hide_on_item_selection())
break;
- }
+
+ pop->hide();
+ next = next->get_parent();
+ pop = Object::cast_to<PopupMenu>(next);
}
+
// Hides popup by default; unless otherwise specified
// by using set_hide_on_item_selection and set_hide_on_checkable_item_selection
- if ((items[p_item].checkable && hide_on_checkable_item_selection) || (!items[p_item].checkable && hide_on_item_selection)) {
- hide();
- }
+
+ if (items[p_item].checkable) {
+ if (!hide_on_checkable_item_selection)
+ return;
+ } else if (0 < items[p_item].max_states) {
+ if (!hide_on_statable_item_selection)
+ return;
+ } else if (!hide_on_item_selection)
+ return;
+
+ hide();
}
void PopupMenu::remove_item(int p_idx) {
@@ -1025,7 +1078,7 @@ void PopupMenu::set_hide_on_item_selection(bool p_enabled) {
hide_on_item_selection = p_enabled;
}
-bool PopupMenu::is_hide_on_item_selection() {
+bool PopupMenu::is_hide_on_item_selection() const {
return hide_on_item_selection;
}
@@ -1035,11 +1088,21 @@ void PopupMenu::set_hide_on_checkable_item_selection(bool p_enabled) {
hide_on_checkable_item_selection = p_enabled;
}
-bool PopupMenu::is_hide_on_checkable_item_selection() {
+bool PopupMenu::is_hide_on_checkable_item_selection() const {
return hide_on_checkable_item_selection;
}
+void PopupMenu::set_hide_on_statable_item_selection(bool p_enabled) {
+
+ hide_on_statable_item_selection = p_enabled;
+}
+
+bool PopupMenu::is_hide_on_statable_item_selection() const {
+
+ return hide_on_statable_item_selection;
+}
+
String PopupMenu::get_tooltip(const Point2 &p_pos) const {
int over = _get_mouse_over(p_pos);
@@ -1098,8 +1161,10 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_item_as_checkable", "idx", "enable"), &PopupMenu::set_item_as_checkable);
ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &PopupMenu::set_item_tooltip);
ClassDB::bind_method(D_METHOD("set_item_shortcut", "idx", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("set_item_statable", "idx", "state"), &PopupMenu::set_item_statable);
ClassDB::bind_method(D_METHOD("toggle_item_checked", "idx"), &PopupMenu::toggle_item_checked);
+ ClassDB::bind_method(D_METHOD("toggle_item_statable", "idx"), &PopupMenu::toggle_item_statable);
ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &PopupMenu::get_item_text);
ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &PopupMenu::get_item_icon);
@@ -1131,6 +1196,9 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hide_on_checkable_item_selection", "enable"), &PopupMenu::set_hide_on_checkable_item_selection);
ClassDB::bind_method(D_METHOD("is_hide_on_checkable_item_selection"), &PopupMenu::is_hide_on_checkable_item_selection);
+ ClassDB::bind_method(D_METHOD("set_hide_on_state_item_selection", "enable"), &PopupMenu::set_hide_on_statable_item_selection);
+ ClassDB::bind_method(D_METHOD("is_hide_on_state_item_selection"), &PopupMenu::is_hide_on_statable_item_selection);
+
ClassDB::bind_method(D_METHOD("_submenu_timeout"), &PopupMenu::_submenu_timeout);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_items", "_get_items");
@@ -1154,6 +1222,7 @@ PopupMenu::PopupMenu() {
set_as_toplevel(true);
set_hide_on_item_selection(true);
set_hide_on_checkable_item_selection(true);
+ set_hide_on_statable_item_selection(false);
submenu_timer = memnew(Timer);
submenu_timer->set_wait_time(0.3);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index c9e9c8e311..5a10bf0765 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -46,6 +46,8 @@ class PopupMenu : public Popup {
String xl_text;
bool checked;
bool checkable;
+ int max_states;
+ int state;
bool separator;
bool disabled;
int ID;
@@ -62,6 +64,8 @@ class PopupMenu : public Popup {
checked = false;
checkable = false;
separator = false;
+ max_states = 0;
+ state = 0;
accel = 0;
disabled = false;
_ofs_cache = 0;
@@ -86,6 +90,7 @@ class PopupMenu : public Popup {
bool invalidated_click;
bool hide_on_item_selection;
bool hide_on_checkable_item_selection;
+ bool hide_on_statable_item_selection;
Vector2 moved;
Array _get_items() const;
@@ -115,6 +120,8 @@ public:
void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false);
void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false);
+ void add_statable_item(const String &p_label, int p_max_states, int p_default_state, int p_ID = -1, uint32_t p_accel = 0);
+
void set_item_text(int p_idx, const String &p_text);
void set_item_icon(int p_idx, const Ref<Texture> &p_icon);
void set_item_checked(int p_idx, bool p_checked);
@@ -128,6 +135,8 @@ public:
void set_item_tooltip(int p_idx, const String &p_tooltip);
void set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global = false);
void set_item_h_offset(int p_idx, int p_offset);
+ void set_item_statable(int p_idx, int p_state);
+ void toggle_item_statable(int p_idx);
void toggle_item_checked(int p_idx);
@@ -145,6 +154,7 @@ public:
bool is_item_checkable(int p_idx) const;
String get_item_tooltip(int p_idx) const;
Ref<ShortCut> get_item_shortcut(int p_idx) const;
+ int get_item_state(int p_idx) const;
int get_item_count() const;
@@ -168,10 +178,13 @@ public:
void set_invalidate_click_until_motion();
void set_hide_on_item_selection(bool p_enabled);
- bool is_hide_on_item_selection();
+ bool is_hide_on_item_selection() const;
void set_hide_on_checkable_item_selection(bool p_enabled);
- bool is_hide_on_checkable_item_selection();
+ bool is_hide_on_checkable_item_selection() const;
+
+ void set_hide_on_statable_item_selection(bool p_enabled);
+ bool is_hide_on_statable_item_selection() const;
PopupMenu();
~PopupMenu();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 9cf4c105b4..45188c3a52 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1822,7 +1822,7 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection) {
void RichTextLabel::selection_copy() {
- if (!selection.enabled)
+ if (!selection.active || !selection.enabled)
return;
String text;
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 1096e3f650..b9a719dd10 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -256,8 +256,8 @@ private:
Item *to;
int to_char;
- bool active;
- bool enabled;
+ bool active; // anything selected? i.e. from, to, etc. valid?
+ bool enabled; // allow selections?
};
Selection selection;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index ea8adc58cd..4635de81e8 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1646,6 +1646,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
} else {
+ bool is_handled = false;
+
_gui_sort_modal_stack();
while (!gui.modal_stack.empty()) {
@@ -1663,11 +1665,20 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
top->notification(Control::NOTIFICATION_MODAL_CLOSE);
top->_modal_stack_remove();
top->hide();
+
+ if (!top->pass_on_modal_close_click()) {
+ is_handled = true;
+ }
} else {
break;
}
}
+ if (is_handled) {
+ get_tree()->set_input_as_handled();
+ return;
+ }
+
//Matrix32 parent_xform;
/*
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index bb2c8750e3..f4e6c5e247 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -350,15 +350,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// CheckBox
Ref<StyleBox> cbx_empty = memnew(StyleBoxEmpty);
- cbx_empty->set_default_margin(MARGIN_LEFT, 22 * scale);
+ cbx_empty->set_default_margin(MARGIN_LEFT, 4 * scale);
cbx_empty->set_default_margin(MARGIN_RIGHT, 4 * scale);
cbx_empty->set_default_margin(MARGIN_TOP, 4 * scale);
- cbx_empty->set_default_margin(MARGIN_BOTTOM, 5 * scale);
+ cbx_empty->set_default_margin(MARGIN_BOTTOM, 4 * scale);
Ref<StyleBox> cbx_focus = focus;
cbx_focus->set_default_margin(MARGIN_LEFT, 4 * scale);
- cbx_focus->set_default_margin(MARGIN_RIGHT, 22 * scale);
+ cbx_focus->set_default_margin(MARGIN_RIGHT, 4 * scale);
cbx_focus->set_default_margin(MARGIN_TOP, 4 * scale);
- cbx_focus->set_default_margin(MARGIN_BOTTOM, 5 * scale);
+ cbx_focus->set_default_margin(MARGIN_BOTTOM, 4 * scale);
theme->set_stylebox("normal", "CheckBox", cbx_empty);
theme->set_stylebox("pressed", "CheckBox", cbx_empty);
@@ -385,7 +385,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
Ref<StyleBox> cb_empty = memnew(StyleBoxEmpty);
cb_empty->set_default_margin(MARGIN_LEFT, 6 * scale);
- cb_empty->set_default_margin(MARGIN_RIGHT, 70 * scale);
+ cb_empty->set_default_margin(MARGIN_RIGHT, 6 * scale);
cb_empty->set_default_margin(MARGIN_TOP, 4 * scale);
cb_empty->set_default_margin(MARGIN_BOTTOM, 4 * scale);
diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp
index 2ef20f67f5..a2c3f1f111 100644
--- a/scene/resources/sky_box.cpp
+++ b/scene/resources/sky_box.cpp
@@ -180,7 +180,7 @@ Ref<Image> ProceduralSky::_generate_sky() {
normal.normalize();
- float v_angle = Math::acos(normal.y);
+ float v_angle = Math::acos(CLAMP(normal.y, -1.0, 1.0));
Color color;
@@ -193,7 +193,7 @@ Ref<Image> ProceduralSky::_generate_sky() {
float c = v_angle / (Math_PI * 0.5);
color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve));
- float sun_angle = Math::rad2deg(Math::acos(sun.dot(normal)));
+ float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0)));
if (sun_angle < sun_angle_min) {
color = color.blend(sun_color);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 1a46353fe3..bd6b917d4e 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -932,8 +932,8 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("find_tile_by_name", "name"), &TileSet::find_tile_by_name);
ClassDB::bind_method(D_METHOD("get_tiles_ids"), &TileSet::_get_tiles_ids);
- BIND_VMETHOD(MethodInfo("_is_tile_bound", PropertyInfo(Variant::INT, "drawn_id"), PropertyInfo(Variant::INT, "neighbor_id")));
- BIND_VMETHOD(MethodInfo("_forward_subtile_selection", PropertyInfo(Variant::INT, "autotile_id"), PropertyInfo(Variant::INT, "bitmask"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_tile_bound", PropertyInfo(Variant::INT, "drawn_id"), PropertyInfo(Variant::INT, "neighbor_id")));
+ BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_forward_subtile_selection", PropertyInfo(Variant::INT, "autotile_id"), PropertyInfo(Variant::INT, "bitmask"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location")));
BIND_ENUM_CONSTANT(BITMASK_2X2);
BIND_ENUM_CONSTANT(BITMASK_3X3);