Merge pull request #30291 from akien-mga/3.0
Assorted cherry-picks from the master branch for Godot 3.0.7
This commit is contained in:
commit
b896eb5fd4
|
@ -2302,7 +2302,7 @@ void _Thread::_start_func(void *ud) {
|
|||
} break;
|
||||
case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
|
||||
|
||||
reason = "Too Many Arguments";
|
||||
reason = "Too Few Arguments";
|
||||
} break;
|
||||
case Variant::CallError::CALL_ERROR_INVALID_METHOD: {
|
||||
|
||||
|
|
|
@ -1505,7 +1505,7 @@ Error Image::decompress() {
|
|||
_image_decompress_pvrtc(this);
|
||||
else if (format == FORMAT_ETC && _image_decompress_etc1)
|
||||
_image_decompress_etc1(this);
|
||||
else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc1)
|
||||
else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc2)
|
||||
_image_decompress_etc2(this);
|
||||
else
|
||||
return ERR_UNAVAILABLE;
|
||||
|
@ -1636,7 +1636,8 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
|
|||
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
|
||||
return;
|
||||
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
|
||||
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
|
||||
|
||||
PoolVector<uint8_t>::Write wp = data.write();
|
||||
uint8_t *dst_data_ptr = wp.ptr();
|
||||
|
@ -1684,7 +1685,8 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
|
|||
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
|
||||
return;
|
||||
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
|
||||
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
|
||||
|
||||
PoolVector<uint8_t>::Write wp = data.write();
|
||||
uint8_t *dst_data_ptr = wp.ptr();
|
||||
|
@ -1735,7 +1737,8 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
|
|||
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
|
||||
return;
|
||||
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
|
||||
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
|
||||
|
||||
lock();
|
||||
Ref<Image> img = p_src;
|
||||
|
@ -1783,7 +1786,8 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
|
|||
if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
|
||||
return;
|
||||
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
|
||||
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
|
||||
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
|
||||
|
||||
lock();
|
||||
Ref<Image> img = p_src;
|
||||
|
@ -2299,6 +2303,9 @@ void Image::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
|
||||
|
||||
BIND_CONSTANT(MAX_WIDTH);
|
||||
BIND_CONSTANT(MAX_HEIGHT);
|
||||
|
||||
BIND_ENUM_CONSTANT(FORMAT_L8); //luminance
|
||||
BIND_ENUM_CONSTANT(FORMAT_LA8); //luminance-alpha
|
||||
BIND_ENUM_CONSTANT(FORMAT_R8);
|
||||
|
|
|
@ -51,14 +51,14 @@ typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
|
|||
class Image : public Resource {
|
||||
GDCLASS(Image, Resource);
|
||||
|
||||
public:
|
||||
static SavePNGFunc save_png_func;
|
||||
|
||||
enum {
|
||||
MAX_WIDTH = 16384, // force a limit somehow
|
||||
MAX_HEIGHT = 16384 // force a limit somehow
|
||||
};
|
||||
|
||||
public:
|
||||
static SavePNGFunc save_png_func;
|
||||
|
||||
enum Format {
|
||||
|
||||
FORMAT_L8, //luminance
|
||||
|
|
|
@ -291,7 +291,6 @@ uint8_t FileAccessCompressed::get_8() const {
|
|||
} else {
|
||||
read_block--;
|
||||
at_end = true;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
|
|||
resolver->mutex->lock();
|
||||
|
||||
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
||||
if (resolver->cache.has(key)) {
|
||||
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
|
||||
IP_Address res = resolver->cache[key];
|
||||
resolver->mutex->unlock();
|
||||
return res;
|
||||
|
@ -144,7 +144,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
|
|||
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
||||
resolver->queue[id].hostname = p_hostname;
|
||||
resolver->queue[id].type = p_type;
|
||||
if (resolver->cache.has(key)) {
|
||||
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
|
||||
resolver->queue[id].response = resolver->cache[key];
|
||||
resolver->queue[id].status = IP::RESOLVER_STATUS_DONE;
|
||||
} else {
|
||||
|
|
|
@ -43,8 +43,7 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
|
|||
return ERR_CANT_RESOLVE;
|
||||
}
|
||||
|
||||
connect_to_host(ip, p_port);
|
||||
return OK;
|
||||
return connect_to_host(ip, p_port);
|
||||
}
|
||||
|
||||
void StreamPeerTCP::_bind_methods() {
|
||||
|
|
|
@ -54,31 +54,24 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
|
|||
int line = 1;
|
||||
bool skip_this = false;
|
||||
bool skip_next = false;
|
||||
bool is_eof = false;
|
||||
|
||||
while (true) {
|
||||
while (!is_eof) {
|
||||
|
||||
String l = f->get_line();
|
||||
String l = f->get_line().strip_edges();
|
||||
is_eof = f->eof_reached();
|
||||
|
||||
if (f->eof_reached()) {
|
||||
|
||||
if (status == STATUS_READING_STRING) {
|
||||
|
||||
if (msg_id != "") {
|
||||
if (!skip_this)
|
||||
translation->add_message(msg_id, msg_str);
|
||||
} else if (config == "")
|
||||
config = msg_str;
|
||||
break;
|
||||
|
||||
} else if (status == STATUS_NONE)
|
||||
break;
|
||||
// If we reached last line and it's not a content line, break, otherwise let processing that last loop
|
||||
if (is_eof && l.empty()) {
|
||||
|
||||
if (status == STATUS_READING_ID) {
|
||||
memdelete(f);
|
||||
ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
|
||||
ERR_FAIL_V(RES());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
l = l.strip_edges();
|
||||
|
||||
if (l.begins_with("msgid")) {
|
||||
|
||||
|
@ -160,6 +153,15 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
|
|||
f->close();
|
||||
memdelete(f);
|
||||
|
||||
if (status == STATUS_READING_STRING) {
|
||||
|
||||
if (msg_id != "") {
|
||||
if (!skip_this)
|
||||
translation->add_message(msg_id, msg_str);
|
||||
} else if (config == "")
|
||||
config = msg_str;
|
||||
}
|
||||
|
||||
if (config == "") {
|
||||
ERR_EXPLAIN("No config found in file: " + p_path);
|
||||
ERR_FAIL_V(RES());
|
||||
|
@ -175,7 +177,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
|
|||
String prop = c.substr(0, p).strip_edges();
|
||||
String value = c.substr(p + 1, c.length()).strip_edges();
|
||||
|
||||
if (prop == "X-Language") {
|
||||
if (prop == "X-Language" || prop == "Language") {
|
||||
translation->set_locale(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -397,7 +397,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
|
|||
Map<Edge, RetFaceConnect>::Element *F = ret_edges.find(e);
|
||||
|
||||
ERR_CONTINUE(!F);
|
||||
|
||||
List<Geometry::MeshData::Face>::Element *O = F->get().left == E ? F->get().right : F->get().left;
|
||||
ERR_CONTINUE(O == E);
|
||||
ERR_CONTINUE(O == NULL);
|
||||
|
@ -426,7 +425,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
|
|||
Edge e2(idx, idxn);
|
||||
|
||||
Map<Edge, RetFaceConnect>::Element *F2 = ret_edges.find(e2);
|
||||
|
||||
ERR_CONTINUE(!F2);
|
||||
//change faceconnect, point to this face instead
|
||||
if (F2->get().left == O)
|
||||
|
@ -439,6 +437,15 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
|
|||
}
|
||||
}
|
||||
|
||||
// remove all edge connections to this face
|
||||
for (Map<Edge, RetFaceConnect>::Element *E = ret_edges.front(); E; E = E->next()) {
|
||||
if (E->get().left == O)
|
||||
E->get().left = NULL;
|
||||
|
||||
if (E->get().right == O)
|
||||
E->get().right = NULL;
|
||||
}
|
||||
|
||||
ret_edges.erase(F); //remove the edge
|
||||
ret_faces.erase(O); //remove the face
|
||||
}
|
||||
|
|
|
@ -1330,7 +1330,10 @@ Array Object::_get_incoming_connections() const {
|
|||
void Object::get_signal_list(List<MethodInfo> *p_signals) const {
|
||||
|
||||
if (!script.is_null()) {
|
||||
Ref<Script>(script)->get_script_signal_list(p_signals);
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_valid()) {
|
||||
scr->get_script_signal_list(p_signals);
|
||||
}
|
||||
}
|
||||
|
||||
ClassDB::get_signal_list(get_class_name(), p_signals);
|
||||
|
|
|
@ -613,6 +613,9 @@ bool OS::has_feature(const String &p_feature) {
|
|||
if (_check_internal_feature_support(p_feature))
|
||||
return true;
|
||||
|
||||
if (ProjectSettings::get_singleton()->has_custom_feature(p_feature))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -359,7 +359,7 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
|
|||
//p_new_size = align(p_new_size)
|
||||
int _free = free_mem; // - static_area_size;
|
||||
|
||||
if ((_free + aligned(e->len)) - alloc_size < 0) {
|
||||
if (uint32_t(_free + aligned(e->len)) < alloc_size) {
|
||||
mt_unlock();
|
||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY);
|
||||
};
|
||||
|
|
|
@ -137,7 +137,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
|
|||
else {
|
||||
|
||||
if (p_name == CoreStringNames::get_singleton()->_custom_features) {
|
||||
Vector<String> custom_feature_array = p_value;
|
||||
Vector<String> custom_feature_array = String(p_value).split(",");
|
||||
for (int i = 0; i < custom_feature_array.size(); i++) {
|
||||
|
||||
custom_features.insert(custom_feature_array[i]);
|
||||
|
@ -886,6 +886,10 @@ Variant ProjectSettings::get_setting(const String &p_setting) const {
|
|||
return get(p_setting);
|
||||
}
|
||||
|
||||
bool ProjectSettings::has_custom_feature(const String &p_feature) const {
|
||||
return custom_features.has(p_feature);
|
||||
}
|
||||
|
||||
void ProjectSettings::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting);
|
||||
|
|
|
@ -148,6 +148,8 @@ public:
|
|||
|
||||
void set_registering_order(bool p_enable);
|
||||
|
||||
bool has_custom_feature(const String &p_feature) const;
|
||||
|
||||
ProjectSettings();
|
||||
~ProjectSettings();
|
||||
};
|
||||
|
|
|
@ -93,6 +93,7 @@ T *_nullptr() {
|
|||
#undef CLAMP // override standard definition
|
||||
#undef Error
|
||||
#undef OK
|
||||
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
|
||||
#endif
|
||||
|
||||
#include "int_types.h"
|
||||
|
|
|
@ -885,8 +885,8 @@ String String::to_upper() const {
|
|||
|
||||
for (int i = 0; i < upper.size(); i++) {
|
||||
|
||||
const char s = upper[i];
|
||||
const char t = _find_upper(s);
|
||||
const CharType s = upper[i];
|
||||
const CharType t = _find_upper(s);
|
||||
if (s != t) // avoid copy on write
|
||||
upper[i] = t;
|
||||
}
|
||||
|
@ -900,8 +900,8 @@ String String::to_lower() const {
|
|||
|
||||
for (int i = 0; i < lower.size(); i++) {
|
||||
|
||||
const char s = lower[i];
|
||||
const char t = _find_lower(s);
|
||||
const CharType s = lower[i];
|
||||
const CharType t = _find_lower(s);
|
||||
if (s != t) // avoid copy on write
|
||||
lower[i] = t;
|
||||
}
|
||||
|
@ -3011,7 +3011,7 @@ String String::simplify_path() const {
|
|||
} else if (s.begins_with("user://")) {
|
||||
|
||||
drive = "user://";
|
||||
s = s.substr(6, s.length());
|
||||
s = s.substr(7, s.length());
|
||||
} else if (s.begins_with("/") || s.begins_with("\\")) {
|
||||
|
||||
drive = s.substr(0, 1);
|
||||
|
@ -3929,7 +3929,7 @@ String String::sprintf(const Array &values, bool *error) const {
|
|||
str = str.pad_decimals(min_decimals);
|
||||
|
||||
// Show sign
|
||||
if (show_sign && value >= 0) {
|
||||
if (show_sign && str.left(1) != "-") {
|
||||
str = str.insert(0, "+");
|
||||
}
|
||||
|
||||
|
|
|
@ -2149,7 +2149,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
|
|||
int idx = p_index;
|
||||
if (idx < 0)
|
||||
idx += 4;
|
||||
if (idx >= 0 || idx < 4) {
|
||||
if (idx >= 0 && idx < 4) {
|
||||
Color *v = reinterpret_cast<Color *>(_data._mem);
|
||||
(*v)[idx] = p_value;
|
||||
valid = true;
|
||||
|
@ -2524,7 +2524,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
|
|||
int idx = p_index;
|
||||
if (idx < 0)
|
||||
idx += 4;
|
||||
if (idx >= 0 || idx < 4) {
|
||||
if (idx >= 0 && idx < 4) {
|
||||
const Color *v = reinterpret_cast<const Color *>(_data._mem);
|
||||
valid = true;
|
||||
return (*v)[idx];
|
||||
|
|
|
@ -228,31 +228,31 @@
|
|||
Amount of weights/bone indices per vertex (always 4).
|
||||
</constant>
|
||||
<constant name="ARRAY_VERTEX" value="0" enum="ArrayType">
|
||||
Vertex array (array of [Vector3] vertices).
|
||||
[PoolVector3Array], [PoolVector2Array], or [Array] of vertex positions.
|
||||
</constant>
|
||||
<constant name="ARRAY_NORMAL" value="1" enum="ArrayType">
|
||||
Normal array (array of [Vector3] normals).
|
||||
[PoolVector3Array] of vertex normals.
|
||||
</constant>
|
||||
<constant name="ARRAY_TANGENT" value="2" enum="ArrayType">
|
||||
Tangent array, array of groups of 4 floats. first 3 floats determine the tangent, and the last the binormal direction as -1 or 1.
|
||||
[PoolRealArray] of vertex tangents. Each element in groups of 4 floats, first 3 floats determine the tangent, and the last the binormal direction as -1 or 1.
|
||||
</constant>
|
||||
<constant name="ARRAY_COLOR" value="3" enum="ArrayType">
|
||||
Vertex array (array of [Color] colors).
|
||||
[PoolColorArray] of vertex colors.
|
||||
</constant>
|
||||
<constant name="ARRAY_TEX_UV" value="4" enum="ArrayType">
|
||||
UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
|
||||
[PoolVector2Array] for UV coordinates.
|
||||
</constant>
|
||||
<constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType">
|
||||
Second UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
|
||||
[PoolVector2Array] for second UV coordinates.
|
||||
</constant>
|
||||
<constant name="ARRAY_BONES" value="6" enum="ArrayType">
|
||||
Array of bone indices, as a float array. Each element in groups of 4 floats.
|
||||
[PoolRealArray] or [PoolIntArray] of bone indices. Each element in groups of 4 floats.
|
||||
</constant>
|
||||
<constant name="ARRAY_WEIGHTS" value="7" enum="ArrayType">
|
||||
Array of bone weights, as a float array. Each element in groups of 4 floats.
|
||||
[PoolRealArray] of bone weights. Each element in groups of 4 floats.
|
||||
</constant>
|
||||
<constant name="ARRAY_INDEX" value="8" enum="ArrayType">
|
||||
[Array] of integers used as indices referencing vertices, colors, normals, tangents, and textures. All of those arrays must have the same number of elements as the vertex array. No index can be beyond the vertex array size. When this index array is present, it puts the function into "index mode," where the index selects the *i*'th vertex, normal, tangent, color, UV, etc. This means if you want to have different normals or colors along an edge, you have to duplicate the vertices.
|
||||
[PoolIntArray] of integers used as indices referencing vertices, colors, normals, tangents, and textures. All of those arrays must have the same number of elements as the vertex array. No index can be beyond the vertex array size. When this index array is present, it puts the function into "index mode," where the index selects the *i*'th vertex, normal, tangent, color, UV, etc. This means if you want to have different normals or colors along an edge, you have to duplicate the vertices.
|
||||
For triangles, the index array is interpreted as triples, referring to the vertices of each triangle. For lines, the index array is in pairs indicating the start and end of each line.
|
||||
</constant>
|
||||
<constant name="ARRAY_MAX" value="9" enum="ArrayType">
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
Perspective Projection (object's size on the screen becomes smaller when far away).
|
||||
</constant>
|
||||
<constant name="PROJECTION_ORTHOGONAL" value="1" enum="Projection">
|
||||
Orthogonal Projection (objects remain the same size on the screen no matter how far away they are).
|
||||
Orthogonal Projection (objects remain the same size on the screen no matter how far away they are; also known as orthographic projection).
|
||||
</constant>
|
||||
<constant name="KEEP_WIDTH" value="0" enum="KeepAspect">
|
||||
Preserves the horizontal aspect ratio.
|
||||
|
|
|
@ -199,7 +199,7 @@
|
|||
</methods>
|
||||
<members>
|
||||
<member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable">
|
||||
If [code]true[/code] this object is pickable. A pickable object can detect the mouse pointer entering/leaving, and if the mouse is inside it, report input events.
|
||||
If [code]true[/code], this object is pickable. A pickable object can detect the mouse pointer entering/leaving, and if the mouse is inside it, report input events. Requires at least one [code]collision_layer[/code] bit to be set.
|
||||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
|
@ -211,17 +211,17 @@
|
|||
<argument index="2" name="shape_idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted when an input event occurs and [code]input_pickable[/code] is [code]true[/code]. See [method _input_event] for details.
|
||||
Emitted when an input event occurs. Requires [code]input_pickable[/code] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set. See [method _input_event] for details.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="mouse_entered">
|
||||
<description>
|
||||
Emitted when the mouse pointer enters any of this object's shapes.
|
||||
Emitted when the mouse pointer enters any of this object's shapes. Requires [code]input_pickable[/code] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="mouse_exited">
|
||||
<description>
|
||||
Emitted when the mouse pointer exits all this object's shapes.
|
||||
Emitted when the mouse pointer exits all this object's shapes. Requires [code]input_pickable[/code] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set.
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<argument index="0" name="point_cloud" type="PoolVector2Array">
|
||||
</argument>
|
||||
<description>
|
||||
Currently, this method does nothing.
|
||||
Based on the set of points provided, this creates and assigns the [member points] property using the convex hull algorithm. Removing all unneeded points. See [method Geometry.convex_hull_2d] for details.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Image datatype.
|
||||
</brief_description>
|
||||
<description>
|
||||
Native image datatype. Contains image data, which can be converted to a [Texture], and several functions to interact with it. The maximum width and height for an [code]Image[/code] is 16384 pixels.
|
||||
Native image datatype. Contains image data, which can be converted to a [Texture], and several functions to interact with it. The maximum width and height for an [code]Image[/code] are [constant MAX_WIDTH] and [constant MAX_HEIGHT].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
@ -431,6 +431,12 @@
|
|||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="MAX_WIDTH" value="16384">
|
||||
The maximal width allowed for [code]Image[/code] resources.
|
||||
</constant>
|
||||
<constant name="MAX_HEIGHT" value="16384">
|
||||
The maximal height allowed for [code]Image[/code] resources.
|
||||
</constant>
|
||||
<constant name="FORMAT_L8" value="0" enum="Format">
|
||||
</constant>
|
||||
<constant name="FORMAT_LA8" value="1" enum="Format">
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
Can have [PathFollow2D] child-nodes moving along the [Curve2D]. See [PathFollow2D] for more information on this usage.
|
||||
Note that the path is considered as relative to the moved nodes (children of [PathFollow2D]) - usually the curve should start with a zero vector (0, 0).
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
This node implements simulated 2D physics. You do not control a RigidBody2D directly. Instead you apply forces to it (gravity, impulses, etc.) and the physics simulation calculates the resulting movement based on its mass, friction, and other physical properties.
|
||||
A RigidBody2D has 4 behavior [member mode]s: Rigid, Static, Character, and Kinematic.
|
||||
[b]Note:[/b] You should not change a RigidBody2D's [code]position[/code] or [code]linear_velocity[/code] every frame or even very often. If you need to directly affect the body's state, use [method _integrate_forces], which allows you to directly access the physics state.
|
||||
If you need to override the default physics behavior, you can write a custom force integration. See [member custom_integrator].
|
||||
Please also keep in mind that physics bodies manage their own transform which overwrites the ones you set. So any direct or indirect transformation (including scaling of the node or its parent) will be visible in the editor only, and immediately reset at runtime.
|
||||
If you need to override the default physics behavior or add a transformation at runtime, you can write a custom force integration. See [member custom_integrator].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Vertical split container.
|
||||
</brief_description>
|
||||
<description>
|
||||
Vertical split container. See [SplitContainer]. This goes from left to right.
|
||||
Vertical split container. See [SplitContainer]. This goes from top to bottom.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
|
|
@ -191,7 +191,7 @@
|
|||
<argument index="0" name="phi" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Returns the vector rotated by [code]phi[/code] radians.
|
||||
Returns the vector rotated by [code]phi[/code] radians. See also [method @GDScript.deg2rad].
|
||||
</description>
|
||||
</method>
|
||||
<method name="round">
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
If [code]true[/code] the bounding box is on the screen.
|
||||
If [code]true[/code], the bounding box is on the screen.
|
||||
Note: It takes one frame for the node's visibility to be assessed once added to the scene tree, so this method will return [code]false[/code] right after it is instantiated, even if it will be on screen in the draw pass.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
If [code]true[/code] the bounding rectangle is on the screen.
|
||||
If [code]true[/code], the bounding rectangle is on the screen.
|
||||
Note: It takes one frame for the node's visibility to be assessed once added to the scene tree, so this method will return [code]false[/code] right after it is instantiated, even if it will be on screen in the draw pass.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -262,7 +262,7 @@ def rstize_text(text, cclass):
|
|||
escape_post = True
|
||||
|
||||
# Properly escape things like `[Node]s`
|
||||
if escape_post and post_text and post_text[0].isalnum(): # not punctuation, escape
|
||||
if escape_post and post_text and (post_text[0].isalnum() or post_text[0] == "("): # not punctuation, escape
|
||||
post_text = '\ ' + post_text
|
||||
|
||||
next_brac_pos = post_text.find('[',0)
|
||||
|
|
|
@ -58,7 +58,10 @@ Error AudioDriverALSA::init_device() {
|
|||
#define CHECK_FAIL(m_cond) \
|
||||
if (m_cond) { \
|
||||
fprintf(stderr, "ALSA ERR: %s\n", snd_strerror(status)); \
|
||||
if (pcm_handle) { \
|
||||
snd_pcm_close(pcm_handle); \
|
||||
pcm_handle = NULL; \
|
||||
} \
|
||||
ERR_FAIL_COND_V(m_cond, ERR_CANT_OPEN); \
|
||||
}
|
||||
|
||||
|
@ -152,7 +155,6 @@ Error AudioDriverALSA::init() {
|
|||
active = false;
|
||||
thread_exited = false;
|
||||
exit_thread = false;
|
||||
pcm_open = false;
|
||||
|
||||
Error err = init_device();
|
||||
if (err == OK) {
|
||||
|
@ -315,9 +317,9 @@ void AudioDriverALSA::unlock() {
|
|||
|
||||
void AudioDriverALSA::finish_device() {
|
||||
|
||||
if (pcm_open) {
|
||||
if (pcm_handle) {
|
||||
snd_pcm_close(pcm_handle);
|
||||
pcm_open = NULL;
|
||||
pcm_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ class AudioDriverALSA : public AudioDriver {
|
|||
bool active;
|
||||
bool thread_exited;
|
||||
mutable bool exit_thread;
|
||||
bool pcm_open;
|
||||
|
||||
public:
|
||||
const char *get_name() const {
|
||||
|
|
|
@ -191,11 +191,11 @@ void RasterizerCanvasGLES3::canvas_end() {
|
|||
state.using_ninepatch = false;
|
||||
}
|
||||
|
||||
RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) {
|
||||
RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map, bool p_force) {
|
||||
|
||||
RasterizerStorageGLES3::Texture *tex_return = NULL;
|
||||
|
||||
if (p_texture == state.current_tex) {
|
||||
if (p_texture == state.current_tex && !p_force) {
|
||||
tex_return = state.current_tex_ptr;
|
||||
} else if (p_texture.is_valid()) {
|
||||
|
||||
|
@ -230,7 +230,7 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
|
|||
state.current_tex_ptr = NULL;
|
||||
}
|
||||
|
||||
if (p_normal_map == state.current_normal) {
|
||||
if (p_normal_map == state.current_normal && !p_force) {
|
||||
//do none
|
||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
|
||||
|
||||
|
@ -997,7 +997,7 @@ void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
|
|||
state.using_texture_rect = true;
|
||||
_set_texture_rect_mode(false);
|
||||
|
||||
_bind_canvas_texture(state.current_tex, state.current_normal);
|
||||
_bind_canvas_texture(state.current_tex, state.current_normal, true);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
@ -1161,7 +1161,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
|
|||
}
|
||||
|
||||
int blend_mode = shader_cache ? shader_cache->canvas_item.blend_mode : RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX;
|
||||
bool unshaded = shader_cache && (shader_cache->canvas_item.light_mode == RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_UNSHADED || blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX);
|
||||
bool unshaded = shader_cache && (shader_cache->canvas_item.light_mode == RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA));
|
||||
bool reclip = false;
|
||||
|
||||
if (last_blend_mode != blend_mode) {
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
virtual void canvas_end();
|
||||
|
||||
_FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable, bool p_ninepatch = false);
|
||||
_FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
|
||||
_FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map, bool p_force = false);
|
||||
|
||||
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs);
|
||||
_FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
|
||||
|
|
|
@ -1384,7 +1384,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
|
|||
if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->particle_valid_histories[1]) {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer, this was used 2 frames ago so it should be good enough for flushing
|
||||
RasterizerGLES3Particle *particle_array = (RasterizerGLES3Particle *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
|
||||
RasterizerGLES3Particle *particle_array;
|
||||
#ifndef __EMSCRIPTEN__
|
||||
particle_array = static_cast<RasterizerGLES3Particle *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
|
||||
#else
|
||||
PoolVector<RasterizerGLES3Particle> particle_vector;
|
||||
particle_vector.resize(particles->amount);
|
||||
PoolVector<RasterizerGLES3Particle>::Write w = particle_vector.write();
|
||||
particle_array = w.ptr();
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), particle_array);
|
||||
#endif
|
||||
|
||||
SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter;
|
||||
|
||||
|
@ -1396,7 +1405,17 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
|
|||
|
||||
sorter.sort(particle_array, particles->amount);
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
#else
|
||||
w = PoolVector<RasterizerGLES3Particle>::Write();
|
||||
particle_array = NULL;
|
||||
{
|
||||
PoolVector<RasterizerGLES3Particle>::Read r = particle_vector.read();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), r.ptr());
|
||||
}
|
||||
particle_vector = PoolVector<RasterizerGLES3Particle>();
|
||||
#endif
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
|
||||
glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
|
||||
|
@ -2674,7 +2693,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
|
|||
|
||||
CameraMatrix shadow_mtx = rectm * bias * li->shadow_transform[j].camera * modelview;
|
||||
|
||||
store_camera(shadow_mtx, &ubo_data.shadow_matrix1[16 * j]);
|
||||
store_camera(shadow_mtx, &ubo_data.shadow.matrix[16 * j]);
|
||||
|
||||
ubo_data.light_clamp[0] = atlas_rect.position.x;
|
||||
ubo_data.light_clamp[1] = atlas_rect.position.y;
|
||||
|
@ -2785,7 +2804,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
|
|||
|
||||
Transform proj = (p_camera_inverse_transform * li->transform).inverse();
|
||||
|
||||
store_transform(proj, ubo_data.shadow_matrix1);
|
||||
store_transform(proj, ubo_data.shadow.matrix1);
|
||||
|
||||
ubo_data.light_params[3] = 1.0; //means it has shadow
|
||||
ubo_data.light_clamp[0] = float(x) / atlas_size;
|
||||
|
@ -2874,7 +2893,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
|
|||
|
||||
CameraMatrix shadow_mtx = rectm * bias * li->shadow_transform[0].camera * modelview;
|
||||
|
||||
store_camera(shadow_mtx, ubo_data.shadow_matrix1);
|
||||
store_camera(shadow_mtx, ubo_data.shadow.matrix1);
|
||||
}
|
||||
|
||||
li->light_index = state.spot_light_count;
|
||||
|
@ -3554,7 +3573,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
|
|||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
|
||||
if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] || storage->frame.current_rt->width < 4 || storage->frame.current_rt->height < 4) { //no post process on small render targets
|
||||
//no environment or transparent render, simply return and convert to SRGB
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
|
|
@ -568,10 +568,15 @@ public:
|
|||
float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
|
||||
float light_clamp[4];
|
||||
float light_shadow_color_contact[4];
|
||||
float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional
|
||||
float shadow_matrix2[16];
|
||||
float shadow_matrix3[16];
|
||||
float shadow_matrix4[16];
|
||||
union {
|
||||
struct {
|
||||
float matrix1[16]; //up to here for spot and omni, rest is for directional
|
||||
float matrix2[16];
|
||||
float matrix3[16];
|
||||
float matrix4[16];
|
||||
};
|
||||
float matrix[4 * 16];
|
||||
} shadow;
|
||||
float shadow_split_offsets[4];
|
||||
};
|
||||
|
||||
|
|
|
@ -100,6 +100,19 @@
|
|||
#define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
|
||||
#define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) {
|
||||
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
GLctx.getBufferSubData($0, $1, HEAPU8, $2, $3);
|
||||
}, target, offset, data, size);
|
||||
/* clang-format on */
|
||||
}
|
||||
#endif
|
||||
|
||||
void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) {
|
||||
|
||||
#ifdef GLES_OVER_GL
|
||||
|
@ -909,7 +922,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi
|
|||
#else
|
||||
|
||||
ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES");
|
||||
return Ref<Image>();
|
||||
ERR_FAIL_V(Ref<Image>());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3241,21 +3254,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_array(RID p_mesh, i
|
|||
|
||||
Surface *surface = mesh->surfaces[p_surface];
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
|
||||
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
|
||||
|
||||
ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(surface->array_byte_size);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, surface->array_byte_size, w.ptr());
|
||||
}
|
||||
#else
|
||||
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
|
||||
ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), data, surface->array_byte_size);
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3268,22 +3286,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_index_array(RID p_m
|
|||
|
||||
ERR_FAIL_COND_V(surface->index_array_len == 0, PoolVector<uint8_t>());
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
|
||||
|
||||
ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(surface->index_array_byte_size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr());
|
||||
}
|
||||
#else
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
|
||||
ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), data, surface->index_array_byte_size);
|
||||
}
|
||||
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3324,23 +3346,26 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap
|
|||
|
||||
for (int i = 0; i < mesh->surfaces[p_surface]->blend_shapes.size(); i++) {
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
|
||||
|
||||
ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(mesh->surfaces[p_surface]->array_byte_size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, w.ptr());
|
||||
}
|
||||
#else
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
|
||||
ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size);
|
||||
}
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
bsarr.push_back(ret);
|
||||
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
return bsarr;
|
||||
|
@ -3799,7 +3824,8 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
|
|||
|
||||
int format_floats = multimesh->color_floats + multimesh->xform_floats;
|
||||
multimesh->data.resize(format_floats * p_instances);
|
||||
for (int i = 0; i < p_instances; i += format_floats) {
|
||||
|
||||
for (int i = 0; i < p_instances * format_floats; i += format_floats) {
|
||||
|
||||
int color_from = 0;
|
||||
|
||||
|
@ -5607,9 +5633,21 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
|
|||
const Particles *particles = particles_owner.getornull(p_particles);
|
||||
ERR_FAIL_COND_V(!particles, AABB());
|
||||
|
||||
const float *data;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
|
||||
|
||||
float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
PoolVector<uint8_t> vector;
|
||||
vector.resize(particles->amount * 16 * 6);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = vector.write();
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, w.ptr());
|
||||
}
|
||||
PoolVector<uint8_t>::Read r = vector.read();
|
||||
data = reinterpret_cast<const float *>(r.ptr());
|
||||
#else
|
||||
data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
|
||||
#endif
|
||||
AABB aabb;
|
||||
|
||||
Transform inv = particles->emission_transform.affine_inverse();
|
||||
|
@ -5626,7 +5664,13 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
|
|||
aabb.expand_to(pos);
|
||||
}
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
r = PoolVector<uint8_t>::Read();
|
||||
vector = PoolVector<uint8_t>();
|
||||
#else
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
float longest_axis = 0;
|
||||
|
@ -7133,7 +7177,7 @@ void RasterizerStorageGLES3::initialize() {
|
|||
config.etc2_supported = true;
|
||||
config.hdr_supported = false;
|
||||
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
|
||||
config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc");
|
||||
config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc") || config.extensions.has("EXT_texture_compression_rgtc");
|
||||
#endif
|
||||
|
||||
config.pvrtc_supported = config.extensions.has("GL_IMG_texture_compression_pvrtc");
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#include "shaders/cubemap_filter.glsl.gen.h"
|
||||
#include "shaders/particles.glsl.gen.h"
|
||||
|
||||
// WebGL 2.0 has no MapBufferRange/UnmapBuffer, but offers a non-ES style BufferSubData API instead.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
|
||||
#endif
|
||||
|
||||
class RasterizerCanvasGLES3;
|
||||
class RasterizerSceneGLES3;
|
||||
|
||||
|
|
|
@ -729,7 +729,7 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
|
|||
|
||||
Vector<String> shader = p_code.split("\n");
|
||||
for (int i = 0; i < shader.size(); i++) {
|
||||
print_line(itos(i) + " " + shader[i]);
|
||||
print_line(itos(i + 1) + " " + shader[i]);
|
||||
}
|
||||
|
||||
_err_print_error(NULL, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), ERR_HANDLER_SHADER);
|
||||
|
@ -781,8 +781,6 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size";
|
||||
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture";
|
||||
|
@ -825,7 +823,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp";
|
||||
actions[VS::SHADER_SPATIAL].renames["COLOR"] = "color_interp";
|
||||
actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize";
|
||||
//actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"]=ShaderLanguage::TYPE_INT;
|
||||
actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "gl_InstanceID";
|
||||
|
||||
//builtins
|
||||
|
||||
|
@ -847,13 +845,11 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss";
|
||||
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy";
|
||||
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
|
||||
//actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread";
|
||||
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
|
||||
actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission";
|
||||
actions[VS::SHADER_SPATIAL].renames["AO"] = "ao";
|
||||
actions[VS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
|
||||
actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission";
|
||||
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
|
||||
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
|
||||
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
|
||||
actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
|
||||
|
@ -895,8 +891,6 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
|||
actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
|
||||
actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
|
||||
|
||||
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
|
||||
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
|
||||
actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
|
||||
|
|
|
@ -141,7 +141,7 @@ void FileAccessWindows::close() {
|
|||
}
|
||||
if (rename_error) {
|
||||
attempts--;
|
||||
OS::get_singleton()->delay_usec(1000000); //wait 100msec and try again
|
||||
OS::get_singleton()->delay_usec(100000); // wait 100msec and try again
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -448,7 +448,7 @@ if env['tools']:
|
|||
|
||||
# Fonts
|
||||
flist = glob.glob(path + "/../thirdparty/fonts/*.ttf")
|
||||
flist.append(glob.glob(path + "/../thirdparty/fonts/*.otf"))
|
||||
flist.extend(glob.glob(path + "/../thirdparty/fonts/*.otf"))
|
||||
env.Depends('#editor/builtin_fonts.gen.h', flist)
|
||||
env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, make_fonts_header)
|
||||
|
||||
|
|
|
@ -149,7 +149,6 @@ void EditorLog::_bind_methods() {
|
|||
EditorLog::EditorLog() {
|
||||
|
||||
VBoxContainer *vb = this;
|
||||
add_constant_override("separation", get_constant("separation", "VBoxContainer"));
|
||||
|
||||
HBoxContainer *hb = memnew(HBoxContainer);
|
||||
vb->add_child(hb);
|
||||
|
@ -181,6 +180,8 @@ EditorLog::EditorLog() {
|
|||
|
||||
current = Thread::get_caller_id();
|
||||
|
||||
add_constant_override("separation", get_constant("separation", "VBoxContainer"));
|
||||
|
||||
EditorNode::get_undo_redo()->set_commit_notify_callback(_undo_redo_cbk, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -2045,10 +2045,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
|
|||
|
||||
} break;
|
||||
|
||||
case SETTINGS_EXPORT_PREFERENCES: {
|
||||
|
||||
//project_export_settings->popup_centered_ratio();
|
||||
} break;
|
||||
case FILE_IMPORT_SUBSCENE: {
|
||||
|
||||
//import_subscene->popup_centered_ratio();
|
||||
|
@ -2490,7 +2486,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
|
|||
export_template_manager->popup_manager();
|
||||
|
||||
} break;
|
||||
case SETTINGS_TOGGLE_FULLSCREN: {
|
||||
case SETTINGS_TOGGLE_FULLSCREEN: {
|
||||
|
||||
OS::get_singleton()->set_window_fullscreen(!OS::get_singleton()->is_window_fullscreen());
|
||||
|
||||
|
@ -4447,7 +4443,7 @@ void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
|
|||
for (int i = 0; i < p_files.size(); i++) {
|
||||
|
||||
String from = p_files[i];
|
||||
if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) != -1)) {
|
||||
if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) == -1)) {
|
||||
continue;
|
||||
}
|
||||
String to = to_path.plus_file(from.get_file());
|
||||
|
@ -5058,7 +5054,11 @@ EditorNode::EditorNode() {
|
|||
srt->add_child(tabbar_container);
|
||||
tabbar_container->add_child(scene_tabs);
|
||||
distraction_free = memnew(ToolButton);
|
||||
#ifdef OSX_ENABLED
|
||||
distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_D));
|
||||
#else
|
||||
distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11));
|
||||
#endif
|
||||
distraction_free->set_tooltip(TTR("Toggle distraction-free mode."));
|
||||
distraction_free->connect("pressed", this, "_toggle_distraction_free_mode");
|
||||
distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
|
||||
|
@ -5167,7 +5167,7 @@ EditorNode::EditorNode() {
|
|||
p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save all Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
|
||||
p->add_separator();
|
||||
p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_W), FILE_CLOSE);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
|
||||
p->add_separator();
|
||||
p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
|
||||
p->add_separator();
|
||||
|
@ -5221,7 +5221,7 @@ EditorNode::EditorNode() {
|
|||
#ifdef OSX_ENABLED
|
||||
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
|
||||
#else
|
||||
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Q);
|
||||
p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q);
|
||||
#endif
|
||||
|
||||
PanelContainer *editor_region = memnew(PanelContainer);
|
||||
|
@ -5270,7 +5270,11 @@ EditorNode::EditorNode() {
|
|||
p->add_child(editor_layouts);
|
||||
editor_layouts->connect("id_pressed", this, "_layout_menu_option");
|
||||
p->add_submenu_item(TTR("Editor Layout"), "Layouts");
|
||||
p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREN);
|
||||
#ifdef OSX_ENABLED
|
||||
p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F), SETTINGS_TOGGLE_FULLSCREEN);
|
||||
#else
|
||||
p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN);
|
||||
#endif
|
||||
p->add_separator();
|
||||
p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
|
||||
|
||||
|
@ -5311,7 +5315,11 @@ EditorNode::EditorNode() {
|
|||
play_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
play_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY));
|
||||
play_button->set_tooltip(TTR("Play the project."));
|
||||
#ifdef OSX_ENABLED
|
||||
play_button->set_shortcut(ED_SHORTCUT("editor/play", TTR("Play"), KEY_MASK_CMD | KEY_B));
|
||||
#else
|
||||
play_button->set_shortcut(ED_SHORTCUT("editor/play", TTR("Play"), KEY_F5));
|
||||
#endif
|
||||
|
||||
pause_button = memnew(ToolButton);
|
||||
pause_button->set_toggle_mode(true);
|
||||
|
@ -5320,7 +5328,11 @@ EditorNode::EditorNode() {
|
|||
pause_button->set_tooltip(TTR("Pause the scene"));
|
||||
pause_button->set_disabled(true);
|
||||
play_hb->add_child(pause_button);
|
||||
#ifdef OSX_ENABLED
|
||||
pause_button->set_shortcut(ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_Y));
|
||||
#else
|
||||
pause_button->set_shortcut(ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), KEY_F7));
|
||||
#endif
|
||||
|
||||
stop_button = memnew(ToolButton);
|
||||
play_hb->add_child(stop_button);
|
||||
|
@ -5329,7 +5341,11 @@ EditorNode::EditorNode() {
|
|||
stop_button->connect("pressed", this, "_menu_option", make_binds(RUN_STOP));
|
||||
stop_button->set_tooltip(TTR("Stop the scene."));
|
||||
stop_button->set_disabled(true);
|
||||
#ifdef OSX_ENABLED
|
||||
stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_MASK_CMD | KEY_PERIOD));
|
||||
#else
|
||||
stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_F8));
|
||||
#endif
|
||||
|
||||
run_native = memnew(EditorRunNative);
|
||||
play_hb->add_child(run_native);
|
||||
|
@ -5347,7 +5363,11 @@ EditorNode::EditorNode() {
|
|||
play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
|
||||
play_scene_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY_SCENE));
|
||||
play_scene_button->set_tooltip(TTR("Play the edited scene."));
|
||||
#ifdef OSX_ENABLED
|
||||
play_scene_button->set_shortcut(ED_SHORTCUT("editor/play_scene", TTR("Play Scene"), KEY_MASK_CMD | KEY_R));
|
||||
#else
|
||||
play_scene_button->set_shortcut(ED_SHORTCUT("editor/play_scene", TTR("Play Scene"), KEY_F6));
|
||||
#endif
|
||||
|
||||
play_custom_scene_button = memnew(ToolButton);
|
||||
play_hb->add_child(play_custom_scene_button);
|
||||
|
@ -5356,7 +5376,11 @@ EditorNode::EditorNode() {
|
|||
play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
|
||||
play_custom_scene_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY_CUSTOM_SCENE));
|
||||
play_custom_scene_button->set_tooltip(TTR("Play custom scene"));
|
||||
#ifdef OSX_ENABLED
|
||||
play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R));
|
||||
#else
|
||||
play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5));
|
||||
#endif
|
||||
|
||||
progress_hb = memnew(BackgroundProgress);
|
||||
|
||||
|
@ -5868,10 +5892,17 @@ EditorNode::EditorNode() {
|
|||
print_handler.userdata = this;
|
||||
add_print_handler(&print_handler);
|
||||
|
||||
#ifdef OSX_ENABLED
|
||||
ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_ALT | KEY_1);
|
||||
ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2);
|
||||
ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_ALT | KEY_3);
|
||||
ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE);
|
||||
#else
|
||||
ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F1);
|
||||
ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F2);
|
||||
ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F3); //hack neded for script editor F3 search to work :) Assign like this or don't use F3
|
||||
ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F4);
|
||||
#endif
|
||||
ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"));
|
||||
ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor"));
|
||||
ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor"));
|
||||
|
|
|
@ -173,14 +173,13 @@ private:
|
|||
SETTINGS_UPDATE_ALWAYS,
|
||||
SETTINGS_UPDATE_CHANGES,
|
||||
SETTINGS_UPDATE_SPINNER_HIDE,
|
||||
SETTINGS_EXPORT_PREFERENCES,
|
||||
SETTINGS_PREFERENCES,
|
||||
SETTINGS_LAYOUT_SAVE,
|
||||
SETTINGS_LAYOUT_DELETE,
|
||||
SETTINGS_LAYOUT_DEFAULT,
|
||||
SETTINGS_MANAGE_EXPORT_TEMPLATES,
|
||||
SETTINGS_PICK_MAIN_SCENE,
|
||||
SETTINGS_TOGGLE_FULLSCREN,
|
||||
SETTINGS_TOGGLE_FULLSCREEN,
|
||||
SETTINGS_HELP,
|
||||
SCENE_TAB_CLOSE,
|
||||
|
||||
|
|
|
@ -68,13 +68,13 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
|
|||
}
|
||||
updating_frame = false;
|
||||
|
||||
if (!frame_delay->is_processing()) {
|
||||
if (frame_delay->is_stopped()) {
|
||||
|
||||
frame_delay->set_wait_time(p_final ? 0.1 : 1);
|
||||
frame_delay->start();
|
||||
}
|
||||
|
||||
if (!plot_delay->is_processing()) {
|
||||
if (plot_delay->is_stopped()) {
|
||||
plot_delay->set_wait_time(0.1);
|
||||
plot_delay->start();
|
||||
}
|
||||
|
|
|
@ -511,6 +511,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
_initial_set("filesystem/import/pvrtc_fast_conversion", false);
|
||||
|
||||
_initial_set("run/auto_save/save_before_running", true);
|
||||
|
||||
// Output
|
||||
hints["run/output/font_size"] = PropertyInfo(Variant::INT, "run/output/font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT);
|
||||
_initial_set("run/output/always_clear_output_on_play", true);
|
||||
_initial_set("run/output/always_open_output_on_play", true);
|
||||
_initial_set("run/output/always_close_output_on_stop", false);
|
||||
|
@ -734,12 +737,6 @@ void EditorSettings::create() {
|
|||
// Validate/create data dir and subdirectories
|
||||
|
||||
dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
if (dir->change_dir(data_path) != OK) {
|
||||
ERR_PRINT("Cannot find path for data directory!");
|
||||
memdelete(dir);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dir->change_dir(data_dir) != OK) {
|
||||
dir->make_dir_recursive(data_dir);
|
||||
if (dir->change_dir(data_dir) != OK) {
|
||||
|
@ -1351,33 +1348,9 @@ struct ShortCutMapping {
|
|||
Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
|
||||
|
||||
#ifdef OSX_ENABLED
|
||||
static const ShortCutMapping macos_mappings[] = {
|
||||
{ "editor/play", KEY_MASK_CMD | KEY_B },
|
||||
{ "editor/play_scene", KEY_MASK_CMD | KEY_R },
|
||||
{ "editor/pause_scene", KEY_MASK_CMD | KEY_MASK_CTRL | KEY_Y },
|
||||
{ "editor/stop", KEY_MASK_CMD | KEY_PERIOD },
|
||||
{ "editor/play_custom_scene", KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_R },
|
||||
{ "editor/editor_2d", KEY_MASK_ALT | KEY_1 },
|
||||
{ "editor/editor_3d", KEY_MASK_ALT | KEY_2 },
|
||||
{ "editor/editor_script", KEY_MASK_ALT | KEY_3 },
|
||||
{ "editor/editor_help", KEY_MASK_ALT | KEY_SPACE },
|
||||
{ "editor/fullscreen_mode", KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F },
|
||||
{ "editor/distraction_free_mode", KEY_MASK_CMD | KEY_MASK_CTRL | KEY_D },
|
||||
{ "script_text_editor/contextual_help", KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE },
|
||||
{ "script_text_editor/find_next", KEY_MASK_CMD | KEY_G },
|
||||
{ "script_text_editor/find_previous", KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G },
|
||||
{ "script_text_editor/toggle_breakpoint", KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B }
|
||||
};
|
||||
|
||||
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
|
||||
if (p_keycode == KEY_DELETE) {
|
||||
p_keycode = KEY_MASK_CMD | KEY_BACKSPACE;
|
||||
} else {
|
||||
for (int i = 0; i < sizeof(macos_mappings) / sizeof(ShortCutMapping); i++) {
|
||||
if (p_path == macos_mappings[i].path) {
|
||||
p_keycode = macos_mappings[i].keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -992,6 +992,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
|
||||
theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE);
|
||||
theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE);
|
||||
theme->set_constant("title_offset", "GraphNode", 20 * EDSCALE);
|
||||
theme->set_constant("close_h_offset", "GraphNode", 20 * EDSCALE);
|
||||
theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE);
|
||||
theme->set_icon("close", "GraphNode", theme->get_icon("GuiCloseCustomizable", "EditorIcons"));
|
||||
|
|
|
@ -121,7 +121,6 @@ void ExportTemplateManager::_update_template_list() {
|
|||
|
||||
void ExportTemplateManager::_download_template(const String &p_version) {
|
||||
|
||||
print_line("download " + p_version);
|
||||
while (template_list->get_child_count()) {
|
||||
memdelete(template_list->get_child(0));
|
||||
}
|
||||
|
@ -226,7 +225,10 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
|
|||
version = data_str;
|
||||
}
|
||||
|
||||
if (file.get_file().size() != 0) {
|
||||
fc++;
|
||||
}
|
||||
|
||||
ret = unzGoToNextFile(pkg);
|
||||
}
|
||||
|
||||
|
@ -266,6 +268,11 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
|
|||
|
||||
String file = String(fname).get_file();
|
||||
|
||||
if (file.size() == 0) {
|
||||
ret = unzGoToNextFile(pkg);
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector<uint8_t> data;
|
||||
data.resize(info.uncompressed_size);
|
||||
|
||||
|
@ -342,7 +349,6 @@ void ExportTemplateManager::_http_download_mirror_completed(int p_status, int p_
|
|||
bool mirrors_found = false;
|
||||
|
||||
Dictionary d = r;
|
||||
print_line(r);
|
||||
if (d.has("mirrors")) {
|
||||
Array mirrors = d["mirrors"];
|
||||
for (int i = 0; i < mirrors.size(); i++) {
|
||||
|
@ -488,7 +494,6 @@ void ExportTemplateManager::_notification(int p_what) {
|
|||
|
||||
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
if (!is_visible_in_tree()) {
|
||||
print_line("closed");
|
||||
download_templates->cancel_request();
|
||||
set_process(false);
|
||||
}
|
||||
|
|
|
@ -339,7 +339,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
|
|||
NodeMap nm;
|
||||
nm.node = node;
|
||||
node_map[p_node->id] = nm;
|
||||
node_name_map[p_node->name] = p_node->id;
|
||||
node_name_map[node->get_name()] = p_node->id;
|
||||
Transform xf = p_node->default_transform;
|
||||
|
||||
xf = collada.fix_transform(xf) * p_node->post_transform;
|
||||
|
|
|
@ -1708,14 +1708,14 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
|
|||
#endif
|
||||
for (int i = 0; i < n->children.size(); i++) {
|
||||
if (state.nodes[n->children[i]]->joints.size()) {
|
||||
_generate_bone(state, n->children[i], skeletons, Vector<int>(), node);
|
||||
_generate_bone(state, n->children[i], skeletons, node);
|
||||
} else {
|
||||
_generate_node(state, n->children[i], node, p_owner, skeletons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, const Vector<int> &p_parent_bones, Node *p_parent_node) {
|
||||
void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node) {
|
||||
ERR_FAIL_INDEX(p_node, state.nodes.size());
|
||||
|
||||
if (state.skeleton_nodes.has(p_node)) {
|
||||
|
@ -1730,30 +1730,28 @@ void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vecto
|
|||
}
|
||||
|
||||
GLTFNode *n = state.nodes[p_node];
|
||||
Vector<int> parent_bones;
|
||||
|
||||
for (int i = 0; i < n->joints.size(); i++) {
|
||||
ERR_FAIL_COND(n->joints[i].skin < 0);
|
||||
const int skin = n->joints[i].skin;
|
||||
ERR_FAIL_COND(skin < 0);
|
||||
|
||||
int bone_index = n->joints[i].bone;
|
||||
Skeleton *s = skeletons[skin];
|
||||
const GLTFNode *gltf_bone_node = state.nodes[state.skins[skin].bones[n->joints[i].bone].node];
|
||||
const String bone_name = gltf_bone_node->name;
|
||||
const int parent = gltf_bone_node->parent;
|
||||
const int parent_index = s->find_bone(state.nodes[parent]->name);
|
||||
|
||||
Skeleton *s = skeletons[n->joints[i].skin];
|
||||
while (s->get_bone_count() <= bone_index) {
|
||||
s->add_bone("Bone " + itos(s->get_bone_count()));
|
||||
}
|
||||
|
||||
if (p_parent_bones.size()) {
|
||||
s->set_bone_parent(bone_index, p_parent_bones[i]);
|
||||
}
|
||||
s->set_bone_rest(bone_index, state.skins[n->joints[i].skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
|
||||
s->add_bone(bone_name);
|
||||
const int bone_index = s->find_bone(bone_name);
|
||||
s->set_bone_parent(bone_index, parent_index);
|
||||
s->set_bone_rest(bone_index, state.skins[skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
|
||||
|
||||
n->godot_nodes.push_back(s);
|
||||
n->joints[i].godot_bone_index = bone_index;
|
||||
parent_bones.push_back(bone_index);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n->children.size(); i++) {
|
||||
_generate_bone(state, n->children[i], skeletons, parent_bones, p_parent_node);
|
||||
_generate_bone(state, n->children[i], skeletons, p_parent_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2068,7 +2066,7 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
|
|||
}
|
||||
for (int i = 0; i < state.root_nodes.size(); i++) {
|
||||
if (state.nodes[state.root_nodes[i]]->joints.size()) {
|
||||
_generate_bone(state, state.root_nodes[i], skeletons, Vector<int>(), root);
|
||||
_generate_bone(state, state.root_nodes[i], skeletons, root);
|
||||
} else {
|
||||
_generate_node(state, state.root_nodes[i], root, root, skeletons);
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
|
|||
Vector<Basis> _decode_accessor_as_basis(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
Vector<Transform> _decode_accessor_as_xform(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
|
||||
void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, const Vector<int> &p_parent_bones, Node *p_parent_node);
|
||||
void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node);
|
||||
void _generate_node(GLTFState &state, int p_node, Node *p_parent, Node *p_owner, Vector<Skeleton *> &skeletons);
|
||||
void _import_animation(GLTFState &state, AnimationPlayer *ap, int index, int bake_fps, Vector<Skeleton *> skeletons);
|
||||
|
||||
|
|
|
@ -126,7 +126,12 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati
|
|||
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
|
||||
|
||||
String p = l.replace("map_Kd", "").replace("\\", "/").strip_edges();
|
||||
String path = base_path.plus_file(p);
|
||||
String path;
|
||||
if (p.is_abs_path()) {
|
||||
path = p;
|
||||
} else {
|
||||
path = base_path.plus_file(p);
|
||||
}
|
||||
|
||||
Ref<Texture> texture = ResourceLoader::load(path);
|
||||
|
||||
|
@ -141,7 +146,12 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati
|
|||
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
|
||||
|
||||
String p = l.replace("map_Ks", "").replace("\\", "/").strip_edges();
|
||||
String path = base_path.plus_file(p);
|
||||
String path;
|
||||
if (p.is_abs_path()) {
|
||||
path = p;
|
||||
} else {
|
||||
path = base_path.plus_file(p);
|
||||
}
|
||||
|
||||
Ref<Texture> texture = ResourceLoader::load(path);
|
||||
|
||||
|
@ -156,7 +166,12 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati
|
|||
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
|
||||
|
||||
String p = l.replace("map_Ns", "").replace("\\", "/").strip_edges();
|
||||
String path = base_path.plus_file(p);
|
||||
String path;
|
||||
if (p.is_abs_path()) {
|
||||
path = p;
|
||||
} else {
|
||||
path = base_path.plus_file(p);
|
||||
}
|
||||
|
||||
Ref<Texture> texture = ResourceLoader::load(path);
|
||||
|
||||
|
|
|
@ -739,6 +739,10 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
|
|||
|
||||
_goto_line(p_row);
|
||||
|
||||
if (result.class_name.begins_with("_")) {
|
||||
result.class_name = result.class_name.substr(1, result.class_name.length() - 1);
|
||||
}
|
||||
|
||||
switch (result.type) {
|
||||
case ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION: {
|
||||
|
||||
|
@ -1660,7 +1664,7 @@ void ScriptTextEditor::register_editor() {
|
|||
ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD | KEY_A);
|
||||
ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT | KEY_UP);
|
||||
ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN);
|
||||
ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CTRL | KEY_MASK_SHIFT | KEY_K);
|
||||
ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K);
|
||||
|
||||
//leave these at zero, same can be accomplished with tab/shift-tab, including selection
|
||||
//the next/previous in history shortcut in this case makes a lot more sene.
|
||||
|
@ -1673,34 +1677,46 @@ void ScriptTextEditor::register_editor() {
|
|||
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
|
||||
#ifdef OSX_ENABLED
|
||||
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C);
|
||||
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE);
|
||||
#else
|
||||
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B);
|
||||
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
|
||||
#endif
|
||||
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CTRL | KEY_MASK_ALT | KEY_T);
|
||||
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent To Spaces"), KEY_MASK_CTRL | KEY_MASK_SHIFT | KEY_Y);
|
||||
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent To Tabs"), KEY_MASK_CTRL | KEY_MASK_SHIFT | KEY_X);
|
||||
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
|
||||
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
|
||||
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent To Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
|
||||
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent To Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X);
|
||||
ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I);
|
||||
|
||||
#ifdef OSX_ENABLED
|
||||
ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
|
||||
#else
|
||||
ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
|
||||
ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CTRL | KEY_MASK_SHIFT | KEY_F9);
|
||||
ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Goto Next Breakpoint"), KEY_MASK_CTRL | KEY_PERIOD);
|
||||
ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Goto Previous Breakpoint"), KEY_MASK_CTRL | KEY_COMMA);
|
||||
#endif
|
||||
ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9);
|
||||
ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Goto Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
|
||||
ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Goto Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
|
||||
|
||||
ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Convert To Uppercase"), KEY_MASK_SHIFT | KEY_F4);
|
||||
ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Convert To Lowercase"), KEY_MASK_SHIFT | KEY_F3);
|
||||
ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KEY_MASK_SHIFT | KEY_F2);
|
||||
|
||||
ED_SHORTCUT("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F);
|
||||
#ifdef OSX_ENABLED
|
||||
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G);
|
||||
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G);
|
||||
#else
|
||||
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3);
|
||||
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3);
|
||||
#endif
|
||||
ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_CMD | KEY_R);
|
||||
|
||||
ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function..."), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_F);
|
||||
ED_SHORTCUT("script_text_editor/goto_line", TTR("Goto Line..."), KEY_MASK_CMD | KEY_L);
|
||||
|
||||
#ifdef OSX_ENABLED
|
||||
ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
|
||||
#else
|
||||
ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_SHIFT | KEY_F1);
|
||||
#endif
|
||||
|
||||
ScriptEditor::register_create_script_editor_function(create_editor);
|
||||
}
|
||||
|
|
|
@ -595,7 +595,7 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
|
|||
return false;
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
String file = files[0];
|
||||
String file = files[i];
|
||||
String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
|
||||
|
||||
if (!ClassDB::is_parent_class(ftype, "Texture")) {
|
||||
|
|
|
@ -70,6 +70,9 @@ void ProjectExportDialog::popup_export() {
|
|||
}
|
||||
|
||||
_update_presets();
|
||||
if (presets->get_current() >= 0) {
|
||||
_edit_preset(presets->get_current()); // triggers rescan for templates if newly installed
|
||||
}
|
||||
|
||||
// Restore valid window bounds or pop up at default size.
|
||||
if (EditorSettings::get_singleton()->has_setting("interface/dialogs/export_bounds")) {
|
||||
|
@ -141,7 +144,6 @@ void ProjectExportDialog::_update_presets() {
|
|||
|
||||
if (current_idx != -1) {
|
||||
presets->select(current_idx);
|
||||
//_edit_preset(current_idx);
|
||||
}
|
||||
|
||||
updating = false;
|
||||
|
@ -154,6 +156,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
|
|||
name->set_editable(false);
|
||||
runnable->set_disabled(true);
|
||||
parameters->edit(NULL);
|
||||
presets->unselect_all();
|
||||
delete_preset->set_disabled(true);
|
||||
sections->hide();
|
||||
patches->clear();
|
||||
|
@ -215,7 +218,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
|
|||
|
||||
if (error != String()) {
|
||||
|
||||
Vector<String> items = error.split("\n");
|
||||
Vector<String> items = error.split("\n", false);
|
||||
error = "";
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
if (i > 0)
|
||||
|
@ -425,11 +428,9 @@ void ProjectExportDialog::_delete_preset() {
|
|||
void ProjectExportDialog::_delete_preset_confirm() {
|
||||
|
||||
int idx = presets->get_current();
|
||||
parameters->edit(NULL); //to avoid crash
|
||||
_edit_preset(-1);
|
||||
EditorExport::get_singleton()->remove_export_preset(idx);
|
||||
_update_presets();
|
||||
_edit_preset(presets->get_current());
|
||||
}
|
||||
|
||||
Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
|
||||
|
@ -742,7 +743,7 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
|
|||
|
||||
Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0);
|
||||
if (err != OK) {
|
||||
error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted: ") + platform->get_name());
|
||||
error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted:") + " " + platform->get_name());
|
||||
error_dialog->show();
|
||||
error_dialog->popup_centered_minsize(Size2(300, 80));
|
||||
ERR_PRINT("Failed to export project");
|
||||
|
@ -942,7 +943,7 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
export_error = memnew(Label);
|
||||
main_vb->add_child(export_error);
|
||||
export_error->hide();
|
||||
export_error->add_color_override("font_color", get_color("error_color", "Editor"));
|
||||
export_error->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
|
||||
|
||||
export_templates_error = memnew(HBoxContainer);
|
||||
main_vb->add_child(export_templates_error);
|
||||
|
@ -950,7 +951,7 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
|
||||
Label *export_error2 = memnew(Label);
|
||||
export_templates_error->add_child(export_error2);
|
||||
export_error2->add_color_override("font_color", get_color("error_color", "Editor"));
|
||||
export_error2->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
|
||||
export_error2->set_text(" - " + TTR("Export templates for this platform are missing:") + " ");
|
||||
|
||||
error_dialog = memnew(AcceptDialog);
|
||||
|
@ -961,6 +962,7 @@ ProjectExportDialog::ProjectExportDialog() {
|
|||
|
||||
LinkButton *download_templates = memnew(LinkButton);
|
||||
download_templates->set_text(TTR("Manage Export Templates"));
|
||||
download_templates->set_v_size_flags(SIZE_SHRINK_CENTER);
|
||||
export_templates_error->add_child(download_templates);
|
||||
download_templates->connect("pressed", this, "_open_export_template_manager");
|
||||
|
||||
|
|
|
@ -2397,6 +2397,7 @@ void PropertyEditor::_check_reload_status(const String &p_name, TreeItem *item)
|
|||
|
||||
if (!has_reload && !obj->get_script().is_null()) {
|
||||
Ref<Script> scr = obj->get_script();
|
||||
if (scr.is_valid()) {
|
||||
Variant orig_value;
|
||||
if (scr->get_property_default_value(p_name, orig_value)) {
|
||||
if (orig_value != obj->get(p_name)) {
|
||||
|
@ -2404,6 +2405,7 @@ void PropertyEditor::_check_reload_status(const String &p_name, TreeItem *item)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found != -1 && !has_reload) {
|
||||
|
||||
|
@ -3558,6 +3560,7 @@ void PropertyEditor::update_tree() {
|
|||
|
||||
if (!has_reload && !obj->get_script().is_null()) {
|
||||
Ref<Script> scr = obj->get_script();
|
||||
if (scr.is_valid()) {
|
||||
Variant orig_value;
|
||||
if (scr->get_property_default_value(p.name, orig_value)) {
|
||||
if (orig_value != obj->get(p.name)) {
|
||||
|
@ -3566,6 +3569,7 @@ void PropertyEditor::update_tree() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_might_be_in_instance() && !has_reload && item->get_cell_mode(1) == TreeItem::CELL_MODE_RANGE && item->get_text(1) == String()) {
|
||||
item->add_button(1, get_icon("ReloadEmpty", "EditorIcons"), 3, true);
|
||||
|
@ -3950,11 +3954,13 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
|
|||
|
||||
if (!obj->get_script().is_null()) {
|
||||
Ref<Script> scr = obj->get_script();
|
||||
if (scr.is_valid()) {
|
||||
Variant orig_value;
|
||||
if (scr->get_property_default_value(prop, orig_value)) {
|
||||
_edit_set(prop, orig_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
|
|
@ -537,6 +537,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||
|
||||
auto_build_solutions = true;
|
||||
editor = true;
|
||||
} else if (I->get() == "--export" || I->get() == "--export-debug") { // Export project
|
||||
|
||||
editor = true;
|
||||
main_args.push_back(I->get());
|
||||
#endif
|
||||
} else if (I->get() == "--no-window") { // disable window creation, Windows only
|
||||
|
||||
|
@ -1286,20 +1290,10 @@ bool Main::start() {
|
|||
removal_docs.push_back(args[j]);
|
||||
} else if (args[i] == "--export") {
|
||||
editor = true; //needs editor
|
||||
if (i + 1 < args.size()) {
|
||||
_export_preset = args[i + 1];
|
||||
} else {
|
||||
ERR_PRINT("Export preset name not specified");
|
||||
return false;
|
||||
}
|
||||
} else if (args[i] == "--export-debug") {
|
||||
editor = true; //needs editor
|
||||
if (i + 1 < args.size()) {
|
||||
_export_preset = args[i + 1];
|
||||
} else {
|
||||
ERR_PRINT("Export preset name not specified");
|
||||
return false;
|
||||
}
|
||||
export_debug = true;
|
||||
#endif
|
||||
} else {
|
||||
|
@ -1703,6 +1697,7 @@ bool Main::start() {
|
|||
#ifdef TOOLS_ENABLED
|
||||
if (project_manager || (script == "" && test == "" && game_path == "" && !editor)) {
|
||||
|
||||
Engine::get_singleton()->set_editor_hint(true);
|
||||
ProjectManager *pmanager = memnew(ProjectManager);
|
||||
ProgressDialog *progress_dialog = memnew(ProgressDialog);
|
||||
pmanager->add_child(progress_dialog);
|
||||
|
|
|
@ -180,7 +180,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
|
|||
|
||||
String scode = dump_node_code(bnode->statements[i], p_level);
|
||||
|
||||
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) {
|
||||
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) {
|
||||
code += scode; //use directly
|
||||
} else {
|
||||
code += _mktab(p_level) + scode + ";\n";
|
||||
|
|
|
@ -51,8 +51,8 @@ bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) co
|
|||
if (needs) {
|
||||
btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject);
|
||||
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
|
||||
if (m_pickRay && gObj->is_ray_pickable()) {
|
||||
return true;
|
||||
if (m_pickRay && !gObj->is_ray_pickable()) {
|
||||
return false;
|
||||
} else if (m_exclude->has(gObj->get_self())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -235,6 +235,7 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp
|
|||
colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
|
||||
m_result->shape = cp.m_index1;
|
||||
B_TO_G(cp.getPositionWorldOnB(), m_result->point);
|
||||
B_TO_G(cp.m_normalWorldOnB, m_result->normal);
|
||||
m_rest_info_bt_point = cp.getPositionWorldOnB();
|
||||
m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
|
||||
} else {
|
||||
|
|
|
@ -291,6 +291,9 @@ void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) {
|
|||
}
|
||||
|
||||
btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
|
||||
if (!vertices.size())
|
||||
// This is necessary since 0 vertices
|
||||
return prepare(ShapeBullet::create_shape_empty());
|
||||
btCollisionShape *cs(ShapeBullet::create_shape_convex(vertices));
|
||||
cs->setLocalScaling(p_implicit_scale);
|
||||
prepare(cs);
|
||||
|
|
|
@ -108,8 +108,8 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
|
|||
uint32_t magic = f->get_32();
|
||||
uint32_t hsize = f->get_32();
|
||||
uint32_t flags = f->get_32();
|
||||
uint32_t width = f->get_32();
|
||||
uint32_t height = f->get_32();
|
||||
uint32_t width = f->get_32();
|
||||
uint32_t pitch = f->get_32();
|
||||
/* uint32_t depth = */ f->get_32();
|
||||
uint32_t mipmaps = f->get_32();
|
||||
|
|
|
@ -59,6 +59,7 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
|
|||
ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
|
||||
|
||||
ENetAddress address;
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
#ifdef GODOT_ENET
|
||||
if (bind_ip.is_wildcard()) {
|
||||
|
|
|
@ -36,7 +36,3 @@ env_etc.add_source_files(env.modules_sources, "*.cpp")
|
|||
# upstream uses c++11
|
||||
if (not env_etc.msvc):
|
||||
env_etc.Append(CCFLAGS="-std=c++11")
|
||||
# -ffast-math seems to be incompatible with ec2comp on recent versions of
|
||||
# GCC and Clang
|
||||
if '-ffast-math' in env_etc['CCFLAGS']:
|
||||
env_etc['CCFLAGS'].remove('-ffast-math')
|
||||
|
|
|
@ -150,7 +150,10 @@ Ref<Script> NativeScript::get_base_script() const {
|
|||
if (!script_data)
|
||||
return Ref<Script>();
|
||||
|
||||
Ref<NativeScript> ns = Ref<NativeScript>(NSL->create_script());
|
||||
NativeScript *script = (NativeScript *)NSL->create_script();
|
||||
Ref<NativeScript> ns = Ref<NativeScript>(script);
|
||||
ERR_FAIL_COND_V(!ns.is_valid(), Ref<Script>());
|
||||
|
||||
ns->set_class_name(script_data->base);
|
||||
ns->set_library(get_library());
|
||||
return ns;
|
||||
|
@ -358,14 +361,13 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const {
|
|||
NativeScriptDesc *script_data = get_script_desc();
|
||||
|
||||
Set<StringName> existing_properties;
|
||||
List<PropertyInfo>::Element *original_back = p_list->back();
|
||||
while (script_data) {
|
||||
List<PropertyInfo>::Element *insert_position = p_list->front();
|
||||
bool insert_before = true;
|
||||
List<PropertyInfo>::Element *insert_position = original_back;
|
||||
|
||||
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
|
||||
if (!existing_properties.has(E.key())) {
|
||||
insert_position = insert_before ? p_list->insert_before(insert_position, E.get().info) : p_list->insert_after(insert_position, E.get().info);
|
||||
insert_before = false;
|
||||
insert_position = p_list->insert_after(insert_position, E.get().info);
|
||||
existing_properties.insert(E.key());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,35 +84,20 @@ StringName PluginScript::get_instance_base_type() const {
|
|||
}
|
||||
|
||||
void PluginScript::update_exports() {
|
||||
// TODO
|
||||
#ifdef TOOLS_ENABLED
|
||||
#if 0
|
||||
ASSERT_SCRIPT_VALID();
|
||||
if (/*changed &&*/ placeholders.size()) { //hm :(
|
||||
if (placeholders.size()) {
|
||||
|
||||
//update placeholders if any
|
||||
Map<StringName, Variant> propdefvalues;
|
||||
List<PropertyInfo> propinfos;
|
||||
const String *props = (const String *)pybind_get_prop_list(_py_exposed_class);
|
||||
for (int i = 0; props[i] != ""; ++i) {
|
||||
const String propname = props[i];
|
||||
pybind_get_prop_default_value(_py_exposed_class, propname.c_str(), (godot_variant *)&propdefvalues[propname]);
|
||||
pybind_prop_info raw_info;
|
||||
pybind_get_prop_info(_py_exposed_class, propname.c_str(), &raw_info);
|
||||
PropertyInfo info;
|
||||
info.type = (Variant::Type)raw_info.type;
|
||||
info.name = propname;
|
||||
info.hint = (PropertyHint)raw_info.hint;
|
||||
info.hint_string = *(String *)&raw_info.hint_string;
|
||||
info.usage = raw_info.usage;
|
||||
propinfos.push_back(info);
|
||||
}
|
||||
|
||||
get_script_property_list(&propinfos);
|
||||
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
|
||||
E->get()->update(propinfos, propdefvalues);
|
||||
E->get()->update(propinfos, _properties_default_values);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: rename p_this "p_owner" ?
|
||||
|
|
|
@ -726,6 +726,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
|
|||
case GDScriptParser::OperatorNode::OP_NEG: {
|
||||
if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) return -1;
|
||||
} break;
|
||||
case GDScriptParser::OperatorNode::OP_POS: {
|
||||
if (!_create_unary_operator(codegen, on, Variant::OP_POSITIVE, p_stack_level)) return -1;
|
||||
} break;
|
||||
case GDScriptParser::OperatorNode::OP_NOT: {
|
||||
if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) return -1;
|
||||
} break;
|
||||
|
|
|
@ -256,7 +256,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
#endif
|
||||
|
||||
uint32_t alloca_size = 0;
|
||||
GDScript *_class;
|
||||
GDScript *script;
|
||||
int ip = 0;
|
||||
int line = _initial_line;
|
||||
|
||||
|
@ -267,7 +267,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
line = p_state->line;
|
||||
ip = p_state->ip;
|
||||
alloca_size = p_state->stack.size();
|
||||
_class = p_state->_class;
|
||||
script = p_state->script.ptr();
|
||||
p_instance = p_state->instance;
|
||||
defarg = p_state->defarg;
|
||||
self = p_state->self;
|
||||
|
@ -331,9 +331,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
} else {
|
||||
self = p_instance->owner;
|
||||
}
|
||||
_class = p_instance->script.ptr();
|
||||
script = p_instance->script.ptr();
|
||||
} else {
|
||||
_class = _script;
|
||||
script = _script;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
|
||||
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
|
||||
Variant *m_v; \
|
||||
m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, _class, self, stack, err_text); \
|
||||
m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); \
|
||||
if (unlikely(!m_v)) \
|
||||
OPCODE_BREAK;
|
||||
|
||||
|
@ -367,7 +367,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
#define CHECK_SPACE(m_space)
|
||||
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
|
||||
Variant *m_v; \
|
||||
m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, _class, self, stack, err_text);
|
||||
m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -991,11 +991,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
gdfs->state.stack_size = _stack_size;
|
||||
gdfs->state.self = self;
|
||||
gdfs->state.alloca_size = alloca_size;
|
||||
gdfs->state._class = _class;
|
||||
gdfs->state.script = Ref<GDScript>(_script);
|
||||
gdfs->state.ip = ip + ipofs;
|
||||
gdfs->state.line = line;
|
||||
gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : 0;
|
||||
gdfs->state.script_id = _class->get_instance_id();
|
||||
//gdfs->state.result_pos=ip+ipofs-1;
|
||||
gdfs->state.defarg = defarg;
|
||||
gdfs->state.instance = p_instance;
|
||||
|
@ -1278,8 +1277,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
String err_file;
|
||||
if (p_instance)
|
||||
err_file = p_instance->script->path;
|
||||
else if (_class)
|
||||
err_file = _class->path;
|
||||
else if (script)
|
||||
err_file = script->path;
|
||||
if (err_file == "")
|
||||
err_file = "<built-in>";
|
||||
String err_func = name;
|
||||
|
@ -1484,17 +1483,14 @@ GDScriptFunction::~GDScriptFunction() {
|
|||
|
||||
Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_EXPLAIN("Resumed after yield, but class instance is gone");
|
||||
ERR_FAIL_V(Variant());
|
||||
}
|
||||
|
||||
if (state.script_id && !ObjectDB::get_instance(state.script_id)) {
|
||||
ERR_EXPLAIN("Resumed after yield, but script is gone");
|
||||
ERR_FAIL_V(Variant());
|
||||
}
|
||||
#else
|
||||
return Variant();
|
||||
#endif
|
||||
}
|
||||
|
||||
Variant arg;
|
||||
r_error.error = Variant::CallError::CALL_OK;
|
||||
|
@ -1537,7 +1533,7 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
|
|||
GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret);
|
||||
if (gdfs && gdfs->function == function) {
|
||||
completed = false;
|
||||
gdfs->previous_state = Ref<GDScriptFunctionState>(this);
|
||||
gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1545,10 +1541,10 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
|
|||
state.result = Variant();
|
||||
|
||||
if (completed) {
|
||||
GDScriptFunctionState *state = this;
|
||||
while (state != NULL) {
|
||||
state->emit_signal("completed", ret);
|
||||
state = *(state->previous_state);
|
||||
if (first_state.is_valid()) {
|
||||
first_state->emit_signal("completed", ret);
|
||||
} else {
|
||||
emit_signal("completed", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1564,9 +1560,6 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
|
|||
//class instance gone?
|
||||
if (state.instance_id && !ObjectDB::get_instance(state.instance_id))
|
||||
return false;
|
||||
//script gone?
|
||||
if (state.script_id && !ObjectDB::get_instance(state.script_id))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1575,17 +1568,14 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
|
|||
Variant GDScriptFunctionState::resume(const Variant &p_arg) {
|
||||
|
||||
ERR_FAIL_COND_V(!function, Variant());
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_EXPLAIN("Resumed after yield, but class instance is gone");
|
||||
ERR_FAIL_V(Variant());
|
||||
}
|
||||
|
||||
if (state.script_id && !ObjectDB::get_instance(state.script_id)) {
|
||||
ERR_EXPLAIN("Resumed after yield, but script is gone");
|
||||
ERR_FAIL_V(Variant());
|
||||
}
|
||||
#else
|
||||
return Variant();
|
||||
#endif
|
||||
}
|
||||
|
||||
state.result = p_arg;
|
||||
Variant::CallError err;
|
||||
|
@ -1599,7 +1589,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
|
|||
GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret);
|
||||
if (gdfs && gdfs->function == function) {
|
||||
completed = false;
|
||||
gdfs->previous_state = Ref<GDScriptFunctionState>(this);
|
||||
gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1607,10 +1597,10 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
|
|||
state.result = Variant();
|
||||
|
||||
if (completed) {
|
||||
GDScriptFunctionState *state = this;
|
||||
while (state != NULL) {
|
||||
state->emit_signal("completed", ret);
|
||||
state = *(state->previous_state);
|
||||
if (first_state.is_valid()) {
|
||||
first_state->emit_signal("completed", ret);
|
||||
} else {
|
||||
emit_signal("completed", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,15 +174,13 @@ private:
|
|||
public:
|
||||
struct CallState {
|
||||
|
||||
ObjectID instance_id; //by debug only
|
||||
ObjectID script_id;
|
||||
|
||||
ObjectID instance_id;
|
||||
GDScriptInstance *instance;
|
||||
Vector<uint8_t> stack;
|
||||
int stack_size;
|
||||
Variant self;
|
||||
uint32_t alloca_size;
|
||||
GDScript *_class;
|
||||
Ref<GDScript> script;
|
||||
int ip;
|
||||
int line;
|
||||
int defarg;
|
||||
|
@ -234,7 +232,7 @@ class GDScriptFunctionState : public Reference {
|
|||
GDScriptFunction *function;
|
||||
GDScriptFunction::CallState state;
|
||||
Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
|
||||
Ref<GDScriptFunctionState> previous_state;
|
||||
Ref<GDScriptFunctionState> first_state;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
|
|
@ -82,6 +82,7 @@ def configure(env):
|
|||
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
|
||||
|
||||
if env['platform'] == 'windows':
|
||||
mono_root = ''
|
||||
if bits == '32':
|
||||
if os.getenv('MONO32_PREFIX'):
|
||||
mono_root = os.getenv('MONO32_PREFIX')
|
||||
|
@ -263,11 +264,13 @@ def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext):
|
|||
|
||||
|
||||
def pkgconfig_try_find_mono_version():
|
||||
from compat import decode_utf8
|
||||
|
||||
lines = subprocess.check_output(['pkg-config', 'monosgen-2', '--modversion']).splitlines()
|
||||
greater_version = None
|
||||
for line in lines:
|
||||
try:
|
||||
version = LooseVersion(line)
|
||||
version = LooseVersion(decode_utf8(line))
|
||||
if greater_version is None or version > greater_version:
|
||||
greater_version = version
|
||||
except ValueError:
|
||||
|
|
|
@ -40,7 +40,7 @@ def _reg_open_key_bits(key, subkey, bits):
|
|||
def _find_mono_in_reg(subkey, bits):
|
||||
try:
|
||||
with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
|
||||
value, regtype = winreg.QueryValueEx(hKey, 'SdkInstallRoot')
|
||||
value = winreg.QueryValueEx(hKey, 'SdkInstallRoot')[0]
|
||||
return value
|
||||
except (WindowsError, OSError):
|
||||
return None
|
||||
|
@ -49,7 +49,7 @@ def _find_mono_in_reg(subkey, bits):
|
|||
def _find_mono_in_reg_old(subkey, bits):
|
||||
try:
|
||||
with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
|
||||
default_clr, regtype = winreg.QueryValueEx(hKey, 'DefaultCLR')
|
||||
default_clr = winreg.QueryValueEx(hKey, 'DefaultCLR')[0]
|
||||
if default_clr:
|
||||
return _find_mono_in_reg(subkey + '\\' + default_clr, bits)
|
||||
return None
|
||||
|
@ -91,7 +91,13 @@ def find_msbuild_tools_path_reg():
|
|||
if not val:
|
||||
raise ValueError('Value of `installationPath` entry is empty')
|
||||
|
||||
return os.path.join(val, "MSBuild\\15.0\\Bin")
|
||||
# Since VS2019, the directory is simply named "Current"
|
||||
msbuild_dir = os.path.join(val, 'MSBuild\\Current\\Bin')
|
||||
if os.path.isdir(msbuild_dir):
|
||||
return msbuild_dir
|
||||
|
||||
# Directory name "15.0" is used in VS 2017
|
||||
return os.path.join(val, 'MSBuild\\15.0\\Bin')
|
||||
|
||||
raise ValueError('Cannot find `installationPath` entry')
|
||||
except ValueError as e:
|
||||
|
@ -106,7 +112,7 @@ def find_msbuild_tools_path_reg():
|
|||
try:
|
||||
subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0'
|
||||
with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
|
||||
value, regtype = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')
|
||||
value = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')[0]
|
||||
return value
|
||||
except (WindowsError, OSError):
|
||||
return ''
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
/*************************************************************************/
|
||||
|
||||
#include "mono_reg_utils.h"
|
||||
#include "core/os/dir_access.h"
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
|
||||
|
@ -202,6 +203,13 @@ String find_msbuild_tools_path() {
|
|||
val += "\\";
|
||||
}
|
||||
|
||||
// Since VS2019, the directory is simply named "Current"
|
||||
String msbuild_dir = val + "MSBuild\\Current\\Bin";
|
||||
if (DirAccess::exists(msbuild_dir)) {
|
||||
return msbuild_dir;
|
||||
}
|
||||
|
||||
// Directory name "15.0" is used in VS 2017
|
||||
return val + "MSBuild\\15.0\\Bin";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ struct ThreadLocalStorage::Impl {
|
|||
#define _CALLBACK_FUNC_
|
||||
#endif
|
||||
|
||||
Impl(void _CALLBACK_FUNC_ (*p_destr_callback_func)(void *)) {
|
||||
Impl(void (_CALLBACK_FUNC_ *p_destr_callback_func)(void *)) {
|
||||
#ifdef WINDOWS_ENABLED
|
||||
dwFlsIndex = FlsAlloc(p_destr_callback_func);
|
||||
ERR_FAIL_COND(dwFlsIndex == FLS_OUT_OF_INDEXES);
|
||||
|
@ -95,7 +95,7 @@ void ThreadLocalStorage::set_value(void *p_value) const {
|
|||
pimpl->set_value(p_value);
|
||||
}
|
||||
|
||||
void ThreadLocalStorage::alloc(void _CALLBACK_FUNC_ (*p_destr_callback)(void *)) {
|
||||
void ThreadLocalStorage::alloc(void (_CALLBACK_FUNC_ *p_destr_callback)(void *)) {
|
||||
pimpl = memnew(ThreadLocalStorage::Impl(p_destr_callback));
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ struct ThreadLocalStorage {
|
|||
void *get_value() const;
|
||||
void set_value(void *p_value) const;
|
||||
|
||||
void alloc(void _CALLBACK_FUNC_ (*p_dest_callback)(void *));
|
||||
void alloc(void (_CALLBACK_FUNC_ *p_dest_callback)(void *));
|
||||
void free();
|
||||
|
||||
private:
|
||||
|
|
|
@ -178,13 +178,17 @@ void RegEx::clear() {
|
|||
|
||||
if (sizeof(CharType) == 2) {
|
||||
|
||||
if (code)
|
||||
if (code) {
|
||||
pcre2_code_free_16((pcre2_code_16 *)code);
|
||||
code = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (code)
|
||||
if (code) {
|
||||
pcre2_code_free_32((pcre2_code_32 *)code);
|
||||
code = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ void image_decompress_squish(Image *p_image) {
|
|||
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
|
||||
|
||||
if (p_image->get_format() >= Image::FORMAT_DXT1)
|
||||
|
@ -176,3 +177,4 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
|
|||
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
|
||||
#include "image.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void image_compress_squish(Image *p_image, Image::CompressSource p_source);
|
||||
#endif
|
||||
void image_decompress_squish(Image *p_image);
|
||||
|
||||
#endif // IMAGE_COMPRESS_SQUISH_H
|
||||
|
|
|
@ -29,17 +29,14 @@
|
|||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#include "image_compress_squish.h"
|
||||
|
||||
void register_squish_types() {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Image::set_compress_bc_func(image_compress_squish);
|
||||
#endif
|
||||
Image::_image_decompress_bc = image_decompress_squish;
|
||||
}
|
||||
|
||||
void unregister_squish_types() {}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,5 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void register_squish_types();
|
||||
void unregister_squish_types();
|
||||
#endif
|
||||
|
|
|
@ -110,7 +110,12 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
|
|||
float upscale = upsample ? 2.0 : 1.0;
|
||||
|
||||
int w = (int)(svg_image->width * p_scale * upscale);
|
||||
ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale)));
|
||||
ERR_FAIL_COND_V(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR);
|
||||
|
||||
int h = (int)(svg_image->height * p_scale * upscale);
|
||||
ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
|
||||
ERR_FAIL_COND_V(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR);
|
||||
|
||||
PoolVector<uint8_t> dst_image;
|
||||
dst_image.resize(w * h * 4);
|
||||
|
|
|
@ -250,8 +250,9 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
|
|||
if (tga_header.image_width <= 0 || tga_header.image_height <= 0)
|
||||
err = FAILED;
|
||||
|
||||
if (tga_header.pixel_depth != 8 && tga_header.pixel_depth != 24 && tga_header.pixel_depth != 32)
|
||||
if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) {
|
||||
err = FAILED;
|
||||
}
|
||||
|
||||
if (err == OK) {
|
||||
f->seek(f->get_position() + tga_header.id_length);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="ResourceImporterTheora" inherits="ResourceImporter" category="Core" version="3.0.7">
|
||||
<brief_description>
|
||||
</brief_description>
|
||||
<description>
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<demos>
|
||||
</demos>
|
||||
<methods>
|
||||
</methods>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -29,18 +29,22 @@
|
|||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
#include "resource_importer_theora.h"
|
||||
|
||||
#include "video_stream_theora.h"
|
||||
|
||||
static ResourceFormatLoaderTheora *resource_loader_theora = NULL;
|
||||
|
||||
void register_theora_types() {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Ref<ResourceImporterTheora> theora_import;
|
||||
theora_import.instance();
|
||||
ResourceFormatImporter::get_singleton()->add_importer(theora_import);
|
||||
#endif
|
||||
resource_loader_theora = memnew(ResourceFormatLoaderTheora);
|
||||
ResourceLoader::add_resource_format_loader(resource_loader_theora, true);
|
||||
|
||||
ClassDB::register_class<VideoStreamTheora>();
|
||||
}
|
||||
|
||||
void unregister_theora_types() {
|
||||
|
||||
if (resource_loader_theora) {
|
||||
memdelete(resource_loader_theora);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* resource_importer_theora.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "resource_importer_theora.h"
|
||||
|
||||
#include "io/resource_saver.h"
|
||||
#include "os/file_access.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
String ResourceImporterTheora::get_importer_name() const {
|
||||
|
||||
return "Theora";
|
||||
}
|
||||
|
||||
String ResourceImporterTheora::get_visible_name() const {
|
||||
|
||||
return "Theora";
|
||||
}
|
||||
void ResourceImporterTheora::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("ogv");
|
||||
p_extensions->push_back("ogm");
|
||||
}
|
||||
|
||||
String ResourceImporterTheora::get_save_extension() const {
|
||||
return "ogvstr";
|
||||
}
|
||||
|
||||
String ResourceImporterTheora::get_resource_type() const {
|
||||
|
||||
return "VideoStreamTheora";
|
||||
}
|
||||
|
||||
bool ResourceImporterTheora::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ResourceImporterTheora::get_preset_count() const {
|
||||
return 0;
|
||||
}
|
||||
String ResourceImporterTheora::get_preset_name(int p_idx) const {
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
void ResourceImporterTheora::get_import_options(List<ImportOption> *r_options, int p_preset) const {
|
||||
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true));
|
||||
}
|
||||
|
||||
Error ResourceImporterTheora::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
|
||||
|
||||
VideoStreamTheora *stream = memnew(VideoStreamTheora);
|
||||
stream->set_file(p_source_file);
|
||||
|
||||
Ref<VideoStreamTheora> ogv_stream = Ref<VideoStreamTheora>(stream);
|
||||
|
||||
return ResourceSaver::save(p_save_path + ".ogvstr", ogv_stream);
|
||||
}
|
||||
|
||||
ResourceImporterTheora::ResourceImporterTheora() {
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* resource_importer_theora.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef RESOURCEIMPORTEROGGTHEORA_H
|
||||
#define RESOURCEIMPORTEROGGTHEORA_H
|
||||
|
||||
#include "video_stream_theora.h"
|
||||
|
||||
#include "core/io/resource_import.h"
|
||||
|
||||
class ResourceImporterTheora : public ResourceImporter {
|
||||
GDCLASS(ResourceImporterTheora, ResourceImporter)
|
||||
public:
|
||||
virtual String get_importer_name() const;
|
||||
virtual String get_visible_name() const;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual String get_save_extension() const;
|
||||
virtual String get_resource_type() const;
|
||||
|
||||
virtual int get_preset_count() const;
|
||||
virtual String get_preset_name(int p_idx) const;
|
||||
|
||||
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
|
||||
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
|
||||
|
||||
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
|
||||
|
||||
ResourceImporterTheora();
|
||||
};
|
||||
|
||||
#endif // RESOURCEIMPORTEROGGTHEORA_H
|
|
@ -730,3 +730,46 @@ void VideoStreamTheora::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file");
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!f) {
|
||||
if (r_error) {
|
||||
*r_error = ERR_CANT_OPEN;
|
||||
}
|
||||
memdelete(f);
|
||||
return RES();
|
||||
}
|
||||
|
||||
VideoStreamTheora *stream = memnew(VideoStreamTheora);
|
||||
stream->set_file(p_path);
|
||||
|
||||
Ref<VideoStreamTheora> ogv_stream = Ref<VideoStreamTheora>(stream);
|
||||
|
||||
if (r_error) {
|
||||
*r_error = OK;
|
||||
}
|
||||
|
||||
return ogv_stream;
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderTheora::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("ogv");
|
||||
}
|
||||
|
||||
bool ResourceFormatLoaderTheora::handles_type(const String &p_type) const {
|
||||
|
||||
return ClassDB::is_parent_class(p_type, "VideoStream");
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderTheora::get_resource_type(const String &p_path) const {
|
||||
|
||||
String el = p_path.get_extension().to_lower();
|
||||
if (el == "ogv")
|
||||
return "VideoStreamTheora";
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -163,7 +163,6 @@ public:
|
|||
class VideoStreamTheora : public VideoStream {
|
||||
|
||||
GDCLASS(VideoStreamTheora, VideoStream);
|
||||
RES_BASE_EXTENSION("ogvstr");
|
||||
|
||||
String file;
|
||||
int audio_track;
|
||||
|
@ -186,4 +185,12 @@ public:
|
|||
VideoStreamTheora() { audio_track = 0; }
|
||||
};
|
||||
|
||||
class ResourceFormatLoaderTheora : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String &p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -131,7 +131,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
Image::Format format;
|
||||
int output_channels = 0;
|
||||
|
||||
if (idxA > 0) {
|
||||
if (idxA != -1) {
|
||||
|
||||
imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
|
||||
format = Image::FORMAT_RGBAH;
|
||||
|
@ -187,7 +187,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
const float *b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
|
||||
const float *a_channel_start = NULL;
|
||||
|
||||
if (idxA > 0) {
|
||||
if (idxA != -1) {
|
||||
a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]);
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
|
|||
*row_w++ = Math::make_half_float(color.g);
|
||||
*row_w++ = Math::make_half_float(color.b);
|
||||
|
||||
if (idxA > 0) {
|
||||
if (idxA != -1) {
|
||||
*row_w++ = Math::make_half_float(*a_channel++);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1274,7 +1274,7 @@ void VisualScriptEditor::_on_nodes_duplicate() {
|
|||
|
||||
Ref<VisualScriptNode> node = script->get_node(edited_func, F->get());
|
||||
|
||||
Ref<VisualScriptNode> dupe = node->duplicate();
|
||||
Ref<VisualScriptNode> dupe = node->duplicate(true);
|
||||
|
||||
int new_id = idc++;
|
||||
to_select.insert(new_id);
|
||||
|
@ -2958,7 +2958,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
|
|||
return;
|
||||
}
|
||||
if (node.is_valid()) {
|
||||
clipboard->nodes[id] = node->duplicate();
|
||||
clipboard->nodes[id] = node->duplicate(true);
|
||||
clipboard->nodes_positions[id] = script->get_node_position(edited_func, id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="ResourceImporterWebm" inherits="ResourceImporter" category="Core" version="3.0.7">
|
||||
<brief_description>
|
||||
</brief_description>
|
||||
<description>
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<demos>
|
||||
</demos>
|
||||
<methods>
|
||||
</methods>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -38,7 +38,6 @@ libvpx_sources = [
|
|||
"vp8/decoder/decodemv.c",
|
||||
"vp8/decoder/detokenize.c",
|
||||
"vp8/decoder/onyxd_if.c",
|
||||
"vp8/decoder/threading.c",
|
||||
|
||||
|
||||
"vp9/vp9_dx_iface.c",
|
||||
|
@ -102,6 +101,10 @@ libvpx_sources = [
|
|||
"vpx_util/vpx_thread.c"
|
||||
]
|
||||
|
||||
libvpx_sources_mt = [
|
||||
"vp8/decoder/threading.c",
|
||||
]
|
||||
|
||||
libvpx_sources_intrin_x86 = [
|
||||
"vp8/common/x86/filter_x86.c",
|
||||
"vp8/common/x86/loopfilter_x86.c",
|
||||
|
@ -231,6 +234,7 @@ libvpx_sources_arm_neon_gas_apple = [
|
|||
]
|
||||
|
||||
libvpx_sources = [libvpx_dir + file for file in libvpx_sources]
|
||||
libvpx_sources_mt = [libvpx_dir + file for file in libvpx_sources_mt]
|
||||
libvpx_sources_intrin_x86 = [libvpx_dir + file for file in libvpx_sources_intrin_x86]
|
||||
libvpx_sources_intrin_x86_mmx = [libvpx_dir + file for file in libvpx_sources_intrin_x86_mmx]
|
||||
libvpx_sources_intrin_x86_sse2 = [libvpx_dir + file for file in libvpx_sources_intrin_x86_sse2]
|
||||
|
@ -253,6 +257,8 @@ env_webm.Append(CPPPATH=[libvpx_dir])
|
|||
env_libvpx = env.Clone()
|
||||
env_libvpx.Append(CPPPATH=[libvpx_dir])
|
||||
|
||||
webm_multithread = env["platform"] != 'javascript'
|
||||
|
||||
cpu_bits = env["bits"]
|
||||
osx_fat = (env["platform"] == 'osx' and cpu_bits == 'fat')
|
||||
webm_cpu_x86 = False
|
||||
|
@ -348,6 +354,10 @@ if webm_simd_optimizations == False:
|
|||
print("WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!")
|
||||
|
||||
env_libvpx.add_source_files(env.modules_sources, libvpx_sources)
|
||||
|
||||
if webm_multithread:
|
||||
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_mt)
|
||||
|
||||
if webm_cpu_x86:
|
||||
is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"]) or ("OSXCROSS_ROOT" in os.environ)
|
||||
|
||||
|
|
|
@ -29,18 +29,22 @@
|
|||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
#include "resource_importer_webm.h"
|
||||
|
||||
#include "video_stream_webm.h"
|
||||
|
||||
static ResourceFormatLoaderWebm *resource_loader_webm = NULL;
|
||||
|
||||
void register_webm_types() {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Ref<ResourceImporterWebm> webm_import;
|
||||
webm_import.instance();
|
||||
ResourceFormatImporter::get_singleton()->add_importer(webm_import);
|
||||
#endif
|
||||
resource_loader_webm = memnew(ResourceFormatLoaderWebm);
|
||||
ResourceLoader::add_resource_format_loader(resource_loader_webm, true);
|
||||
|
||||
ClassDB::register_class<VideoStreamWebm>();
|
||||
}
|
||||
|
||||
void unregister_webm_types() {
|
||||
|
||||
if (resource_loader_webm) {
|
||||
memdelete(resource_loader_webm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* resource_importer_webm.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "resource_importer_webm.h"
|
||||
|
||||
#include "io/resource_saver.h"
|
||||
#include "os/file_access.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "video_stream_webm.h"
|
||||
|
||||
String ResourceImporterWebm::get_importer_name() const {
|
||||
|
||||
return "Webm";
|
||||
}
|
||||
|
||||
String ResourceImporterWebm::get_visible_name() const {
|
||||
|
||||
return "Webm";
|
||||
}
|
||||
void ResourceImporterWebm::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("webm");
|
||||
}
|
||||
|
||||
String ResourceImporterWebm::get_save_extension() const {
|
||||
return "webmstr";
|
||||
}
|
||||
|
||||
String ResourceImporterWebm::get_resource_type() const {
|
||||
|
||||
return "VideoStreamWebm";
|
||||
}
|
||||
|
||||
bool ResourceImporterWebm::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ResourceImporterWebm::get_preset_count() const {
|
||||
return 0;
|
||||
}
|
||||
String ResourceImporterWebm::get_preset_name(int p_idx) const {
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
void ResourceImporterWebm::get_import_options(List<ImportOption> *r_options, int p_preset) const {
|
||||
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true));
|
||||
}
|
||||
|
||||
Error ResourceImporterWebm::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
|
||||
if (!f) {
|
||||
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
|
||||
}
|
||||
memdelete(f);
|
||||
|
||||
VideoStreamWebm *stream = memnew(VideoStreamWebm);
|
||||
stream->set_file(p_source_file);
|
||||
|
||||
Ref<VideoStreamWebm> webm_stream = Ref<VideoStreamWebm>(stream);
|
||||
|
||||
return ResourceSaver::save(p_save_path + ".webmstr", webm_stream);
|
||||
}
|
||||
|
||||
ResourceImporterWebm::ResourceImporterWebm() {
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* resource_importer_webm.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef RESOURCEIMPORTERWEBM_H
|
||||
#define RESOURCEIMPORTERWEBM_H
|
||||
|
||||
#include "io/resource_import.h"
|
||||
|
||||
class ResourceImporterWebm : public ResourceImporter {
|
||||
GDCLASS(ResourceImporterWebm, ResourceImporter)
|
||||
public:
|
||||
virtual String get_importer_name() const;
|
||||
virtual String get_visible_name() const;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual String get_save_extension() const;
|
||||
virtual String get_resource_type() const;
|
||||
|
||||
virtual int get_preset_count() const;
|
||||
virtual String get_preset_name(int p_idx) const;
|
||||
|
||||
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
|
||||
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
|
||||
|
||||
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
|
||||
|
||||
ResourceImporterWebm();
|
||||
};
|
||||
|
||||
#endif // RESOURCEIMPORTERWEBM_H
|
|
@ -443,3 +443,46 @@ void VideoStreamWebm::set_audio_track(int p_track) {
|
|||
|
||||
audio_track = p_track;
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!f) {
|
||||
if (r_error) {
|
||||
*r_error = ERR_CANT_OPEN;
|
||||
}
|
||||
memdelete(f);
|
||||
return RES();
|
||||
}
|
||||
|
||||
VideoStreamWebm *stream = memnew(VideoStreamWebm);
|
||||
stream->set_file(p_path);
|
||||
|
||||
Ref<VideoStreamWebm> webm_stream = Ref<VideoStreamWebm>(stream);
|
||||
|
||||
if (r_error) {
|
||||
*r_error = OK;
|
||||
}
|
||||
|
||||
return webm_stream;
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderWebm::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("webm");
|
||||
}
|
||||
|
||||
bool ResourceFormatLoaderWebm::handles_type(const String &p_type) const {
|
||||
|
||||
return ClassDB::is_parent_class(p_type, "VideoStream");
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderWebm::get_resource_type(const String &p_path) const {
|
||||
|
||||
String el = p_path.get_extension().to_lower();
|
||||
if (el == "webm")
|
||||
return "VideoStreamWebm";
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -109,7 +109,6 @@ private:
|
|||
class VideoStreamWebm : public VideoStream {
|
||||
|
||||
GDCLASS(VideoStreamWebm, VideoStream);
|
||||
RES_BASE_EXTENSION("webmstr");
|
||||
|
||||
String file;
|
||||
int audio_track;
|
||||
|
@ -127,4 +126,12 @@ public:
|
|||
virtual void set_audio_track(int p_track);
|
||||
};
|
||||
|
||||
class ResourceFormatLoaderWebm : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String &p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
};
|
||||
|
||||
#endif // VIDEO_STREAM_WEBM_H
|
||||
|
|
|
@ -14,9 +14,9 @@ apply plugin: 'com.android.application'
|
|||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
$$GRADLE_REPOSITORY_URLS$$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ def configure(env):
|
|||
|
||||
if (env["target"].startswith("release")):
|
||||
env.Append(LINKFLAGS=['-O2'])
|
||||
env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-ffast-math', '-funsafe-math-optimizations', '-fomit-frame-pointer'])
|
||||
env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-fomit-frame-pointer'])
|
||||
if (can_vectorize):
|
||||
env.Append(CPPFLAGS=['-ftree-vectorize'])
|
||||
if (env["target"] == "release_debug"):
|
||||
|
|
|
@ -228,7 +228,7 @@ class EditorExportAndroid : public EditorExportPlatform {
|
|||
};
|
||||
|
||||
Vector<Device> devices;
|
||||
bool devices_changed;
|
||||
volatile bool devices_changed;
|
||||
Mutex *device_lock;
|
||||
Thread *device_thread;
|
||||
volatile bool quit_request;
|
||||
|
@ -345,8 +345,7 @@ class EditorExportAndroid : public EditorExportPlatform {
|
|||
}
|
||||
|
||||
d.name = vendor + " " + device;
|
||||
//print_line("name: "+d.name);
|
||||
//print_line("description: "+d.description);
|
||||
if (device == String()) continue;
|
||||
}
|
||||
|
||||
ndevices.push_back(d);
|
||||
|
@ -1156,7 +1155,10 @@ public:
|
|||
virtual bool poll_devices() {
|
||||
|
||||
bool dc = devices_changed;
|
||||
if (dc) {
|
||||
// don't clear unless we're reporting true, to avoid race
|
||||
devices_changed = false;
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
|
@ -1859,9 +1861,9 @@ public:
|
|||
run_icon->create_from_image(img);
|
||||
|
||||
device_lock = Mutex::create();
|
||||
device_thread = Thread::create(_device_poll_thread, this);
|
||||
devices_changed = true;
|
||||
quit_request = false;
|
||||
device_thread = Thread::create(_device_poll_thread, this);
|
||||
}
|
||||
|
||||
~EditorExportAndroid() {
|
||||
|
|
|
@ -202,22 +202,29 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
return i;
|
||||
}
|
||||
}
|
||||
onInputDeviceAdded(device_id);
|
||||
return joy_devices.size() - 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceAdded(int deviceId) {
|
||||
int id = find_joy_device(deviceId);
|
||||
|
||||
// Check if the device has not been already added
|
||||
if (id < 0) {
|
||||
InputDevice device = mInputManager.getInputDevice(deviceId);
|
||||
|
||||
id = joy_devices.size();
|
||||
|
||||
joystick joy = new joystick();
|
||||
joy.device_id = deviceId;
|
||||
final int id = joy_devices.size();
|
||||
InputDevice device = mInputManager.getInputDevice(deviceId);
|
||||
final String name = device.getName();
|
||||
joy.name = device.getName();
|
||||
joy.axes = new ArrayList<InputDevice.MotionRange>();
|
||||
joy.hats = new ArrayList<InputDevice.MotionRange>();
|
||||
|
||||
List<InputDevice.MotionRange> ranges = device.getMotionRanges();
|
||||
Collections.sort(ranges, new RangeComparator());
|
||||
|
||||
for (InputDevice.MotionRange range : ranges) {
|
||||
if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
|
||||
joy.hats.add(range);
|
||||
|
@ -225,26 +232,36 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
joy.axes.add(range);
|
||||
}
|
||||
}
|
||||
|
||||
joy_devices.add(joy);
|
||||
|
||||
final int device_id = id;
|
||||
final String name = joy.name;
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.joyconnectionchanged(id, true, name);
|
||||
GodotLib.joyconnectionchanged(device_id, true, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceRemoved(int deviceId) {
|
||||
final int id = find_joy_device(deviceId);
|
||||
joy_devices.remove(id);
|
||||
final int device_id = find_joy_device(deviceId);
|
||||
|
||||
// Check if the evice has not been already removed
|
||||
if (device_id > -1) {
|
||||
joy_devices.remove(device_id);
|
||||
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.joyconnectionchanged(id, false, "");
|
||||
GodotLib.joyconnectionchanged(device_id, false, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceChanged(int deviceId) {
|
||||
|
@ -264,15 +281,18 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
if ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) {
|
||||
|
||||
final int button = get_godot_button(keyCode);
|
||||
final int device = find_joy_device(event.getDeviceId());
|
||||
final int device_id = find_joy_device(event.getDeviceId());
|
||||
|
||||
// Check if the device exists
|
||||
if (device_id > -1) {
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.joybutton(device, button, false);
|
||||
GodotLib.joybutton(device_id, button, false);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
final int chr = event.getUnicodeChar(0);
|
||||
queueEvent(new Runnable() {
|
||||
|
@ -282,6 +302,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
return super.onKeyUp(keyCode, event);
|
||||
};
|
||||
|
||||
|
@ -306,18 +327,20 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
|
||||
if (event.getRepeatCount() > 0) // ignore key echo
|
||||
return true;
|
||||
final int button = get_godot_button(keyCode);
|
||||
final int device = find_joy_device(event.getDeviceId());
|
||||
|
||||
//Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device));
|
||||
final int button = get_godot_button(keyCode);
|
||||
final int device_id = find_joy_device(event.getDeviceId());
|
||||
|
||||
// Check if the device exists
|
||||
if (device_id > -1) {
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GodotLib.joybutton(device, button, true);
|
||||
GodotLib.joybutton(device_id, button, true);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
||||
}
|
||||
} else {
|
||||
final int chr = event.getUnicodeChar(0);
|
||||
queueEvent(new Runnable() {
|
||||
|
@ -327,6 +350,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
|
@ -336,12 +360,14 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
|
||||
final int device_id = find_joy_device(event.getDeviceId());
|
||||
|
||||
// Check if the device exists
|
||||
if (device_id > -1) {
|
||||
joystick joy = joy_devices.get(device_id);
|
||||
|
||||
for (int i = 0; i < joy.axes.size(); i++) {
|
||||
InputDevice.MotionRange range = joy.axes.get(i);
|
||||
final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
|
||||
//Log.e(TAG, String.format("axis event: %d, value %f", i, value));
|
||||
final int idx = i;
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
|
@ -354,7 +380,6 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
for (int i = 0; i < joy.hats.size(); i += 2) {
|
||||
final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
|
||||
final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis()));
|
||||
//Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY));
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -363,6 +388,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
|
|||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return super.onGenericMotionEvent(event);
|
||||
|
|
|
@ -37,14 +37,14 @@ def configure(env):
|
|||
## Build type
|
||||
|
||||
if (env["target"] == "release"):
|
||||
env.Prepend(CCFLAGS=['-O3', '-ffast-math'])
|
||||
env.Prepend(CCFLAGS=['-O3'])
|
||||
if (env["debug_symbols"] == "yes"):
|
||||
env.Prepend(CCFLAGS=['-g1'])
|
||||
if (env["debug_symbols"] == "full"):
|
||||
env.Prepend(CCFLAGS=['-g2'])
|
||||
|
||||
elif (env["target"] == "release_debug"):
|
||||
env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
|
||||
env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
|
||||
if (env["debug_symbols"] == "yes"):
|
||||
env.Prepend(CCFLAGS=['-g1'])
|
||||
if (env["debug_symbols"] == "full"):
|
||||
|
|
|
@ -47,7 +47,7 @@ def configure(env):
|
|||
|
||||
if (env["target"].startswith("release")):
|
||||
env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1'])
|
||||
env.Append(CPPFLAGS=['-O2', '-ftree-vectorize', '-fomit-frame-pointer', '-ffast-math', '-funsafe-math-optimizations'])
|
||||
env.Append(CPPFLAGS=['-O2', '-ftree-vectorize', '-fomit-frame-pointer'])
|
||||
env.Append(LINKFLAGS=['-O2'])
|
||||
|
||||
if env["target"] == "release_debug":
|
||||
|
|
|
@ -85,7 +85,8 @@ Rect2 _get_ios_window_safe_area(float p_window_width, float p_window_height) {
|
|||
}
|
||||
ERR_FAIL_COND_V(insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0,
|
||||
Rect2(0, 0, p_window_width, p_window_height));
|
||||
return Rect2(insets.left, insets.top, p_window_width - insets.right - insets.left, p_window_height - insets.bottom - insets.top);
|
||||
UIEdgeInsets window_insets = UIEdgeInsetsMake(_points_to_pixels(insets.top), _points_to_pixels(insets.left), _points_to_pixels(insets.bottom), _points_to_pixels(insets.right));
|
||||
return Rect2(window_insets.left, window_insets.top, p_window_width - window_insets.right - window_insets.left, p_window_height - window_insets.bottom - window_insets.top);
|
||||
}
|
||||
|
||||
bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue