Merge remote-tracking branch 'upstream/master' into x11-window-management
This commit is contained in:
commit
a13e180052
|
@ -19,6 +19,9 @@ tools/editor/register_exporters.cpp
|
|||
tools/editor/doc_data_compressed.h
|
||||
tools/editor/editor_icons.cpp
|
||||
-fpic
|
||||
.fscache
|
||||
make.bat
|
||||
log.txt
|
||||
|
||||
# Android specific
|
||||
platform/android/java/local.properties
|
||||
|
|
|
@ -487,7 +487,7 @@ struct test_27_data {
|
|||
|
||||
bool test_27() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 26: begins_with\n");
|
||||
OS::get_singleton()->print("\n\nTest 27: begins_with\n");
|
||||
test_27_data tc[] = {
|
||||
{"res://foobar", "res://", true},
|
||||
{"res", "res://", false},
|
||||
|
@ -504,11 +504,348 @@ bool test_27() {
|
|||
}
|
||||
if (!state) {
|
||||
OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n");
|
||||
break;
|
||||
}
|
||||
};
|
||||
return state;
|
||||
};
|
||||
|
||||
|
||||
bool test_28() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 28: sprintf\n");
|
||||
|
||||
bool success, state = true;
|
||||
char output_format[] = "\tTest:\t%ls => %ls (%s)\n";
|
||||
String format, output;
|
||||
Array args;
|
||||
|
||||
// %%
|
||||
format = "fish %% frog";
|
||||
args.clear();
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish % frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
//////// INTS
|
||||
|
||||
// Int
|
||||
format = "fish %d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 5 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int left padded with zeroes.
|
||||
format = "fish %05d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 00005 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int left padded with spaces.
|
||||
format = "fish %5d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 5 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int right padded with spaces.
|
||||
format = "fish %-5d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 5 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int with sign (positive).
|
||||
format = "fish %+d frog";
|
||||
args.clear();
|
||||
args.push_back(5);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish +5 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Negative int.
|
||||
format = "fish %d frog";
|
||||
args.clear();
|
||||
args.push_back(-5);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish -5 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Hex (lower)
|
||||
format = "fish %x frog";
|
||||
args.clear();
|
||||
args.push_back(45);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 2d frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Hex (upper)
|
||||
format = "fish %X frog";
|
||||
args.clear();
|
||||
args.push_back(45);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 2D frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Octal
|
||||
format = "fish %o frog";
|
||||
args.clear();
|
||||
args.push_back(99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 143 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
////// REALS
|
||||
|
||||
// Real
|
||||
format = "fish %f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99.990000 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real left-padded
|
||||
format = "fish %11f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99.990000 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real right-padded
|
||||
format = "fish %-11f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99.990000 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real given int.
|
||||
format = "fish %f frog";
|
||||
args.clear();
|
||||
args.push_back(99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99.000000 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with sign (positive).
|
||||
format = "fish %+f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish +99.990000 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with 1 decimals.
|
||||
format = "fish %.1f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 100.0 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with 12 decimals.
|
||||
format = "fish %.12f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99.990000000000 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Real with no decimals.
|
||||
format = "fish %.f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 100 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
/////// Strings.
|
||||
|
||||
// String
|
||||
format = "fish %s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish cheese frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// String left-padded
|
||||
format = "fish %10s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish cheese frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// String right-padded
|
||||
format = "fish %-10s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish cheese frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
///// Characters
|
||||
|
||||
// Character as string.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back("A");
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish A frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Character as int.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back(65);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish A frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
///// Dynamic width
|
||||
|
||||
// String dynamic width
|
||||
format = "fish %*s frog";
|
||||
args.clear();
|
||||
args.push_back(10);
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish cheese frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Int dynamic width
|
||||
format = "fish %*d frog";
|
||||
args.clear();
|
||||
args.push_back(10);
|
||||
args.push_back(99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Float dynamic width
|
||||
format = "fish %*.*f frog";
|
||||
args.clear();
|
||||
args.push_back(10);
|
||||
args.push_back(3);
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == String("fish 99.990 frog"));
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
///// Errors
|
||||
|
||||
// More formats than arguments.
|
||||
format = "fish %s %s frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// More arguments than formats.
|
||||
format = "fish %s frog";
|
||||
args.clear();
|
||||
args.push_back("hello");
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Incomplete format.
|
||||
format = "fish %10";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Bad character in format string
|
||||
format = "fish %&f frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Too many decimals.
|
||||
format = "fish %2.2.2f frog";
|
||||
args.clear();
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// * not a number
|
||||
format = "fish %*f frog";
|
||||
args.clear();
|
||||
args.push_back("cheese");
|
||||
args.push_back(99.99);
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Character too long.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back("sc");
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
// Character bad type.
|
||||
format = "fish %c frog";
|
||||
args.clear();
|
||||
args.push_back(Array());
|
||||
output = format.sprintf(args);
|
||||
success = (output == "");
|
||||
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
|
||||
if (!success) state = false;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
typedef bool (*TestFunc)(void);
|
||||
|
||||
TestFunc test_funcs[] = {
|
||||
|
@ -540,6 +877,7 @@ TestFunc test_funcs[] = {
|
|||
test_25,
|
||||
test_26,
|
||||
test_27,
|
||||
test_28,
|
||||
0
|
||||
|
||||
};
|
||||
|
|
|
@ -273,7 +273,7 @@ Error HTTPClient::poll(){
|
|||
while(true) {
|
||||
uint8_t byte;
|
||||
int rec=0;
|
||||
Error err = connection->get_partial_data(&byte,1,rec);
|
||||
Error err = _get_http_data(&byte,1,rec);
|
||||
if (err!=OK) {
|
||||
close();
|
||||
status=STATUS_CONNECTION_ERROR;
|
||||
|
@ -417,7 +417,7 @@ ByteArray HTTPClient::read_response_body_chunk() {
|
|||
//reading len
|
||||
uint8_t b;
|
||||
int rec=0;
|
||||
err = connection->get_partial_data(&b,1,rec);
|
||||
err = _get_http_data(&b,1,rec);
|
||||
|
||||
if (rec==0)
|
||||
break;
|
||||
|
@ -471,7 +471,7 @@ ByteArray HTTPClient::read_response_body_chunk() {
|
|||
} else {
|
||||
|
||||
int rec=0;
|
||||
err = connection->get_partial_data(&chunk[chunk.size()-chunk_left],chunk_left,rec);
|
||||
err = _get_http_data(&chunk[chunk.size()-chunk_left],chunk_left,rec);
|
||||
if (rec==0) {
|
||||
break;
|
||||
}
|
||||
|
@ -502,18 +502,23 @@ ByteArray HTTPClient::read_response_body_chunk() {
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
int to_read = MIN(body_left,read_chunk_size);
|
||||
ByteArray ret;
|
||||
ret.resize(MAX(body_left,tmp_read.size()));
|
||||
ret.resize(to_read);
|
||||
ByteArray::Write w = ret.write();
|
||||
int _offset = 0;
|
||||
while (body_left > 0) {
|
||||
ByteArray::Write r = tmp_read.write();
|
||||
while (to_read > 0) {
|
||||
int rec=0;
|
||||
err = connection->get_partial_data(r.ptr(),MIN(body_left,tmp_read.size()),rec);
|
||||
err = _get_http_data(w.ptr()+_offset,to_read,rec);
|
||||
if (rec>0) {
|
||||
copymem(w.ptr()+_offset,r.ptr(),rec);
|
||||
body_left-=rec;
|
||||
to_read-=rec;
|
||||
_offset += rec;
|
||||
} else {
|
||||
if (to_read>0) //ended up reading less
|
||||
ret.resize(_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (body_left==0) {
|
||||
|
@ -557,6 +562,20 @@ bool HTTPClient::is_blocking_mode_enabled() const{
|
|||
return blocking;
|
||||
}
|
||||
|
||||
Error HTTPClient::_get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received) {
|
||||
|
||||
if (blocking) {
|
||||
|
||||
Error err = connection->get_data(p_buffer,p_bytes);
|
||||
if (err==OK)
|
||||
r_received=p_bytes;
|
||||
else
|
||||
r_received=0;
|
||||
return err;
|
||||
} else {
|
||||
return connection->get_partial_data(p_buffer,p_bytes,r_received);
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPClient::_bind_methods() {
|
||||
|
||||
|
@ -574,6 +593,7 @@ void HTTPClient::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_response_headers_as_dictionary"),&HTTPClient::_get_response_headers_as_dictionary);
|
||||
ObjectTypeDB::bind_method(_MD("get_response_body_length"),&HTTPClient::get_response_body_length);
|
||||
ObjectTypeDB::bind_method(_MD("read_response_body_chunk"),&HTTPClient::read_response_body_chunk);
|
||||
ObjectTypeDB::bind_method(_MD("set_read_chunk_size","bytes"),&HTTPClient::set_read_chunk_size);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_blocking_mode","enabled"),&HTTPClient::set_blocking_mode);
|
||||
ObjectTypeDB::bind_method(_MD("is_blocking_mode_enabled"),&HTTPClient::is_blocking_mode_enabled);
|
||||
|
@ -664,6 +684,11 @@ void HTTPClient::_bind_methods() {
|
|||
|
||||
}
|
||||
|
||||
void HTTPClient::set_read_chunk_size(int p_size) {
|
||||
ERR_FAIL_COND(p_size<256 || p_size>(1<<24));
|
||||
read_chunk_size=p_size;
|
||||
}
|
||||
|
||||
HTTPClient::HTTPClient(){
|
||||
|
||||
tcp_connection = StreamPeerTCP::create_ref();
|
||||
|
@ -677,7 +702,7 @@ HTTPClient::HTTPClient(){
|
|||
response_num=0;
|
||||
ssl=false;
|
||||
blocking=false;
|
||||
tmp_read.resize(4096);
|
||||
read_chunk_size=4096;
|
||||
}
|
||||
|
||||
HTTPClient::~HTTPClient(){
|
||||
|
|
|
@ -157,7 +157,10 @@ private:
|
|||
static void _bind_methods();
|
||||
StringArray _get_response_headers();
|
||||
Dictionary _get_response_headers_as_dictionary();
|
||||
ByteArray tmp_read;
|
||||
int read_chunk_size;
|
||||
|
||||
Error _get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
@ -185,6 +188,7 @@ public:
|
|||
void set_blocking_mode(bool p_enable); //useful mostly if running in a thread
|
||||
bool is_blocking_mode_enabled() const;
|
||||
|
||||
void set_read_chunk_size(int p_size);
|
||||
|
||||
Error poll();
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ void ResourceImportMetadata::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("set_editor","name"),&ResourceImportMetadata::set_editor);
|
||||
ObjectTypeDB::bind_method(_MD("get_editor"),&ResourceImportMetadata::get_editor);
|
||||
ObjectTypeDB::bind_method(_MD("add_source","path","md5"),&ResourceImportMetadata::add_source);
|
||||
ObjectTypeDB::bind_method(_MD("add_source","path","md5"),&ResourceImportMetadata::add_source, "");
|
||||
ObjectTypeDB::bind_method(_MD("get_source_path","idx"),&ResourceImportMetadata::get_source_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_source_md5","idx"),&ResourceImportMetadata::get_source_md5);
|
||||
ObjectTypeDB::bind_method(_MD("remove_source","idx"),&ResourceImportMetadata::remove_source);
|
||||
|
|
296
core/ustring.cpp
296
core/ustring.cpp
|
@ -34,6 +34,7 @@
|
|||
#include "io/md5.h"
|
||||
#include "ucaps.h"
|
||||
#include "color.h"
|
||||
#include "variant.h"
|
||||
#define MAX_DIGITS 6
|
||||
#define UPPERCASE(m_c) (((m_c)>='a' && (m_c)<='z')?((m_c)-('a'-'A')):(m_c))
|
||||
#define LOWERCASE(m_c) (((m_c)>='A' && (m_c)<='Z')?((m_c)+('a'-'A')):(m_c))
|
||||
|
@ -981,7 +982,7 @@ String String::num(double p_num,int p_decimals) {
|
|||
|
||||
}
|
||||
|
||||
String String::num_int64(int64_t p_num) {
|
||||
String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
|
||||
|
||||
bool sign=p_num<0;
|
||||
int64_t num=ABS(p_num);
|
||||
|
@ -990,7 +991,7 @@ String String::num_int64(int64_t p_num) {
|
|||
|
||||
int chars=0;
|
||||
do {
|
||||
n/=10;
|
||||
n/=base;
|
||||
chars++;
|
||||
} while(n);
|
||||
|
||||
|
@ -1002,8 +1003,15 @@ String String::num_int64(int64_t p_num) {
|
|||
c[chars]=0;
|
||||
n=num;
|
||||
do {
|
||||
c[--chars]='0'+(n%10);
|
||||
n/=10;
|
||||
int mod = n%base;
|
||||
if (mod >= 10) {
|
||||
char a = (capitalize_hex ? 'A' : 'a');
|
||||
c[--chars]=a+(mod - 10);
|
||||
} else {
|
||||
c[--chars]='0'+mod;
|
||||
}
|
||||
|
||||
n/=base;
|
||||
} while(n);
|
||||
|
||||
if (sign)
|
||||
|
@ -3518,4 +3526,284 @@ String rtoss(double p_val) {
|
|||
return String::num_scientific(p_val);
|
||||
}
|
||||
|
||||
// Right-pad with a character.
|
||||
String String::rpad(int min_length, const String& character) const {
|
||||
String s = *this;
|
||||
int padding = min_length - s.length();
|
||||
if (padding > 0) {
|
||||
for (int i = 0; i < padding; i++) s = s + character;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
// Left-pad with a character.
|
||||
String String::lpad(int min_length, const String& character) const {
|
||||
String s = *this;
|
||||
int padding = min_length - s.length();
|
||||
if (padding > 0) {
|
||||
for (int i = 0; i < padding; i++) s = character + s;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// sprintf is implemented in GDScript via:
|
||||
// "fish %s pie" % "frog"
|
||||
// "fish %s %d pie" % ["frog", 12]
|
||||
String String::sprintf(const Array& values) const {
|
||||
|
||||
String formatted;
|
||||
CharType* self = (CharType*)c_str();
|
||||
int num_items = values.size();
|
||||
bool in_format = false;
|
||||
int value_index = 0;
|
||||
int min_chars;
|
||||
int min_decimals;
|
||||
bool in_decimals;
|
||||
bool pad_with_zeroes;
|
||||
bool left_justified;
|
||||
bool show_sign;
|
||||
|
||||
|
||||
for (; *self; self++) {
|
||||
const CharType c = *self;
|
||||
|
||||
if (in_format) { // We have % - lets see what else we get.
|
||||
switch (c) {
|
||||
case '%': { // Replace %% with %
|
||||
formatted += chr(c);
|
||||
in_format = false;
|
||||
break;
|
||||
}
|
||||
case 'd': // Integer (signed)
|
||||
case 'o': // Octal
|
||||
case 'x': // Hexadecimal (lowercase)
|
||||
case 'X': { // Hexadecimal (uppercase)
|
||||
if (value_index >= values.size()) {
|
||||
ERR_EXPLAIN("not enough arguments for format string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
if (!values[value_index].is_num()) {
|
||||
ERR_EXPLAIN("a number is required");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
int64_t value = values[value_index];
|
||||
int base;
|
||||
bool capitalize = false;
|
||||
switch (c) {
|
||||
case 'd': base = 10; break;
|
||||
case 'o': base = 8; break;
|
||||
case 'x': base = 16; break;
|
||||
case 'X': base = 16; capitalize = true; break;
|
||||
}
|
||||
// Get basic number.
|
||||
String str = String::num_int64(value, base, capitalize);
|
||||
|
||||
// Sign.
|
||||
if (show_sign && value >= 0) {
|
||||
str = str.insert(0, "+");
|
||||
}
|
||||
|
||||
// Padding.
|
||||
String pad_char = pad_with_zeroes ? String("0") : String(" ");
|
||||
if (left_justified) {
|
||||
str = str.rpad(min_chars, pad_char);
|
||||
} else {
|
||||
str = str.lpad(min_chars, pad_char);
|
||||
}
|
||||
|
||||
formatted += str;
|
||||
++value_index;
|
||||
in_format = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'f': { // Float
|
||||
if (value_index >= values.size()) {
|
||||
ERR_EXPLAIN("not enough arguments for format string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
if (!values[value_index].is_num()) {
|
||||
ERR_EXPLAIN("a number is required");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
double value = values[value_index];
|
||||
String str = String::num(value, min_decimals);
|
||||
|
||||
// Pad decimals out.
|
||||
str = str.pad_decimals(min_decimals);
|
||||
|
||||
// Show sign
|
||||
if (show_sign && value >= 0) {
|
||||
str = str.insert(0, "+");
|
||||
}
|
||||
|
||||
// Padding
|
||||
if (left_justified) {
|
||||
str = str.rpad(min_chars);
|
||||
} else {
|
||||
str = str.lpad(min_chars);
|
||||
}
|
||||
|
||||
formatted += str;
|
||||
++value_index;
|
||||
in_format = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case 's': { // String
|
||||
if (value_index >= values.size()) {
|
||||
ERR_EXPLAIN("not enough arguments for format string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
String str = values[value_index];
|
||||
// Padding.
|
||||
if (left_justified) {
|
||||
str = str.rpad(min_chars);
|
||||
} else {
|
||||
str = str.lpad(min_chars);
|
||||
}
|
||||
|
||||
formatted += str;
|
||||
++value_index;
|
||||
in_format = false;
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
if (value_index >= values.size()) {
|
||||
ERR_EXPLAIN("not enough arguments for format string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
// Convert to character.
|
||||
String str;
|
||||
if (values[value_index].is_num()) {
|
||||
int value = values[value_index];
|
||||
if (value < 0) {
|
||||
ERR_EXPLAIN("unsigned byte integer is lower than maximum")
|
||||
ERR_FAIL_V("");
|
||||
} else if (value > 255) {
|
||||
ERR_EXPLAIN("unsigned byte integer is greater than maximum")
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
str = chr(values[value_index]);
|
||||
} else if (values[value_index].get_type() == Variant::STRING) {
|
||||
str = values[value_index];
|
||||
if (str.length() != 1) {
|
||||
ERR_EXPLAIN("%c requires number or single-character string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
} else {
|
||||
ERR_EXPLAIN("%c requires number or single-character string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
// Padding.
|
||||
if (left_justified) {
|
||||
str = str.rpad(min_chars);
|
||||
} else {
|
||||
str = str.lpad(min_chars);
|
||||
}
|
||||
|
||||
formatted += str;
|
||||
++value_index;
|
||||
in_format = false;
|
||||
break;
|
||||
}
|
||||
case '-': { // Left justify
|
||||
left_justified = true;
|
||||
break;
|
||||
}
|
||||
case '+': { // Show + if positive.
|
||||
show_sign = true;
|
||||
break;
|
||||
}
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9': {
|
||||
int n = c - '0';
|
||||
if (in_decimals) {
|
||||
min_decimals *= 10;
|
||||
min_decimals += n;
|
||||
} else {
|
||||
if (c == '0' && min_chars == 0) {
|
||||
pad_with_zeroes = true;
|
||||
} else {
|
||||
min_chars *= 10;
|
||||
min_chars += n;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '.': { // Float separtor.
|
||||
if (in_decimals) {
|
||||
ERR_EXPLAIN("too many decimal points in format");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
in_decimals = true;
|
||||
min_decimals = 0; // We want to add the value manually.
|
||||
break;
|
||||
}
|
||||
|
||||
case '*': { // Dyanmic width, based on value.
|
||||
if (value_index >= values.size()) {
|
||||
ERR_EXPLAIN("not enough arguments for format string");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
if (!values[value_index].is_num()) {
|
||||
ERR_EXPLAIN("* wants number");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
int size = values[value_index];
|
||||
|
||||
if (in_decimals) {
|
||||
min_decimals = size;
|
||||
} else {
|
||||
min_chars = size;
|
||||
}
|
||||
|
||||
++value_index;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ERR_EXPLAIN("unsupported format character");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
}
|
||||
} else { // Not in format string.
|
||||
switch (c) {
|
||||
case '%':
|
||||
in_format = true;
|
||||
// Back to defaults:
|
||||
min_chars = 0;
|
||||
min_decimals = 6;
|
||||
pad_with_zeroes = false;
|
||||
left_justified = false;
|
||||
show_sign = false;
|
||||
in_decimals = false;
|
||||
break;
|
||||
default:
|
||||
formatted += chr(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_format) {
|
||||
ERR_EXPLAIN("incomplete format");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
if (value_index != values.size()) {
|
||||
ERR_EXPLAIN("not all arguments converted during string formatting");
|
||||
ERR_FAIL_V("");
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "typedefs.h"
|
||||
#include "vector.h"
|
||||
#include "array.h"
|
||||
|
||||
/**
|
||||
@author red <red@killy>
|
||||
|
@ -127,10 +128,13 @@ public:
|
|||
String insert(int p_at_pos,String p_string) const;
|
||||
String pad_decimals(int p_digits) const;
|
||||
String pad_zeros(int p_digits) const;
|
||||
String lpad(int min_length,const String& character=" ") const;
|
||||
String rpad(int min_length,const String& character=" ") const;
|
||||
String sprintf(const Array& values) const;
|
||||
static String num(double p_num,int p_decimals=-1);
|
||||
static String num_scientific(double p_num);
|
||||
static String num_real(double p_num);
|
||||
static String num_int64(int64_t p_num);
|
||||
static String num_int64(int64_t p_num,int base=10,bool capitalize_hex=false);
|
||||
static String chr(CharType p_char);
|
||||
static String md5(const uint8_t *p_md5);
|
||||
bool is_numeric() const;
|
||||
|
@ -203,7 +207,7 @@ public:
|
|||
String xml_unescape() const;
|
||||
String c_escape() const;
|
||||
String c_unescape() const;
|
||||
|
||||
|
||||
String percent_encode() const;
|
||||
String percent_decode() const;
|
||||
|
||||
|
|
|
@ -736,6 +736,20 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
|
|||
}
|
||||
#endif
|
||||
_RETURN( p_a._data._int % p_b._data._int );
|
||||
|
||||
} else if (p_a.type==STRING) {
|
||||
const String *str=reinterpret_cast<const String*>(p_a._data._mem);
|
||||
|
||||
if (p_b.type==ARRAY) {
|
||||
// e.g. "frog %s %d" % ["fish", 12]
|
||||
const Array *arr=reinterpret_cast<const Array*>(p_b._data._mem);
|
||||
_RETURN(str->sprintf(*arr));
|
||||
} else {
|
||||
// e.g. "frog %d" % 12
|
||||
Array arr;
|
||||
arr.push_back(p_b);
|
||||
_RETURN(str->sprintf(arr));
|
||||
}
|
||||
}
|
||||
|
||||
r_valid=false;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
::res://::1412302385
|
||||
WWT-01.png::ImageTexture::1412126473::
|
||||
WWT-02.png::ImageTexture::1412126474::
|
||||
WWT-03.png::ImageTexture::1412126474::
|
||||
WWT-04.png::ImageTexture::1412126474::
|
||||
WWT-05.png::ImageTexture::1412126474::
|
||||
WWT-06.png::ImageTexture::1412126474::
|
||||
WWT-07.png::ImageTexture::1412126474::
|
||||
WWT-08.png::ImageTexture::1412126474::
|
||||
WWT-09.png::ImageTexture::1412126474::
|
||||
WWT-10.png::ImageTexture::1412126474::
|
||||
WWT-11.png::ImageTexture::1412126475::
|
||||
WWT-12.png::ImageTexture::1412126475::
|
||||
WWT-13.png::ImageTexture::1412126475::
|
||||
WWT-14.png::ImageTexture::1412126475::
|
||||
WWT-15.png::ImageTexture::1412126475::
|
||||
WWT-16.png::ImageTexture::1412126475::
|
||||
WWT-17.png::ImageTexture::1412126475::
|
||||
WWT-18.png::ImageTexture::1412126475::
|
||||
WWT-19.png::ImageTexture::1412126476::
|
||||
WWT-20.png::ImageTexture::1412126476::
|
||||
WWT-21.png::ImageTexture::1412126476::
|
||||
WWT-22.png::ImageTexture::1412126476::
|
||||
WWT-23.png::ImageTexture::1412126476::
|
||||
WWT-24.png::ImageTexture::1412126476::
|
||||
WWT-25.png::ImageTexture::1412126476::
|
||||
WWT-26.png::ImageTexture::1412126476::
|
||||
map.scn::PackedScene::1412127344::
|
||||
tiles.scn::PackedScene::1412126994::
|
||||
tileset.res::TileSet::1412127001::
|
||||
troll.gd::GDScript::1412302377::
|
||||
troll.png::ImageTexture::1412302385::
|
||||
troll.scn::PackedScene::1412302380::
|
|
@ -1,4 +0,0 @@
|
|||
::res://::1421147952
|
||||
icon.png::ImageTexture::1420046079::
|
||||
new_scene_poly_with_holes.scn::PackedScene::1421147952::
|
||||
polygonpathfinder.gd::GDScript::1421146502::
|
File diff suppressed because one or more lines are too long
|
@ -4038,8 +4038,16 @@ void RasterizerGLES2::render_target_set_size(RID p_render_target,int p_width,int
|
|||
glGenTextures(1, &rt->color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
if (rt->texture_ptr->flags&VS::TEXTURE_FLAG_FILTER) {
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
|
||||
|
@ -5494,13 +5502,15 @@ Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Materia
|
|||
base = surf->array_local;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
bool can_copy_to_local=surf->local_stride * surf->array_len <= skinned_buffer_size;
|
||||
if (p_morphs && surf->stride * surf->array_len > skinned_buffer_size)
|
||||
can_copy_to_local=false;
|
||||
|
||||
|
||||
if (!can_copy_to_local)
|
||||
skeleton_valid=false;
|
||||
|
||||
|
||||
/* compute morphs */
|
||||
|
||||
|
||||
if (p_morphs && surf->morph_target_count && can_copy_to_local) {
|
||||
|
||||
|
||||
|
@ -9581,9 +9591,6 @@ void RasterizerGLES2::init() {
|
|||
//glClearDepth(1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
skinned_buffer_size = GLOBAL_DEF("rasterizer/skinned_buffer_size",DEFAULT_SKINNED_BUFFER_SIZE);
|
||||
skinned_buffer = memnew_arr( uint8_t, skinned_buffer_size );
|
||||
|
||||
glGenTextures(1, &white_tex);
|
||||
unsigned char whitetexdata[8*8*3];
|
||||
for(int i=0;i<8*8*3;i++) {
|
||||
|
@ -9759,7 +9766,6 @@ void RasterizerGLES2::init() {
|
|||
void RasterizerGLES2::finish() {
|
||||
|
||||
|
||||
memdelete_arr(skinned_buffer);
|
||||
}
|
||||
|
||||
int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) {
|
||||
|
@ -10039,10 +10045,29 @@ RasterizerGLES2* RasterizerGLES2::get_singleton() {
|
|||
return _singleton;
|
||||
};
|
||||
|
||||
int RasterizerGLES2::RenderList::max_elements=RenderList::DEFAULT_MAX_ELEMENTS;
|
||||
|
||||
RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,bool p_default_fragment_lighting,bool p_use_reload_hooks) {
|
||||
|
||||
_singleton = this;
|
||||
|
||||
RenderList::max_elements=GLOBAL_DEF("rasterizer/max_render_elements",(int)RenderList::DEFAULT_MAX_ELEMENTS);
|
||||
if (RenderList::max_elements>64000)
|
||||
RenderList::max_elements=64000;
|
||||
if (RenderList::max_elements<1024)
|
||||
RenderList::max_elements=1024;
|
||||
|
||||
opaque_render_list.init();
|
||||
alpha_render_list.init();
|
||||
|
||||
skinned_buffer_size = GLOBAL_DEF("rasterizer/skeleton_buffer_size_kb",DEFAULT_SKINNED_BUFFER_SIZE);
|
||||
if (skinned_buffer_size<256)
|
||||
skinned_buffer_size=256;
|
||||
if (skinned_buffer_size>16384)
|
||||
skinned_buffer_size=16384;
|
||||
skinned_buffer_size*=1024;
|
||||
skinned_buffer = memnew_arr( uint8_t, skinned_buffer_size );
|
||||
|
||||
keep_copies=p_keep_ram_copy;
|
||||
use_reload_hooks=p_use_reload_hooks;
|
||||
pack_arrays=p_compress_arrays;
|
||||
|
@ -10086,6 +10111,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo
|
|||
|
||||
RasterizerGLES2::~RasterizerGLES2() {
|
||||
|
||||
memdelete_arr(skinned_buffer);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
|
||||
MAX_SCENE_LIGHTS=2048,
|
||||
LIGHT_SPOT_BIT=0x80,
|
||||
DEFAULT_SKINNED_BUFFER_SIZE = 2048 * 1024, // 10k vertices
|
||||
DEFAULT_SKINNED_BUFFER_SIZE = 2048, // 10k vertices
|
||||
MAX_HW_LIGHTS = 1,
|
||||
};
|
||||
|
||||
|
@ -827,15 +827,18 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
GLuint gui_quad_buffer;
|
||||
|
||||
|
||||
|
||||
struct RenderList {
|
||||
|
||||
enum {
|
||||
MAX_ELEMENTS=4096,
|
||||
DEFAULT_MAX_ELEMENTS=4096,
|
||||
MAX_LIGHTS=4,
|
||||
SORT_FLAG_SKELETON=1,
|
||||
SORT_FLAG_INSTANCING=2,
|
||||
};
|
||||
|
||||
static int max_elements;
|
||||
|
||||
struct Element {
|
||||
|
||||
|
||||
|
@ -868,8 +871,8 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
};
|
||||
|
||||
|
||||
Element _elements[MAX_ELEMENTS];
|
||||
Element *elements[MAX_ELEMENTS];
|
||||
Element *_elements;
|
||||
Element **elements;
|
||||
int element_count;
|
||||
|
||||
void clear() {
|
||||
|
@ -1004,17 +1007,28 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
}
|
||||
_FORCE_INLINE_ Element* add_element() {
|
||||
|
||||
if (element_count>MAX_ELEMENTS)
|
||||
if (element_count>=max_elements)
|
||||
return NULL;
|
||||
elements[element_count]=&_elements[element_count];
|
||||
return elements[element_count++];
|
||||
}
|
||||
|
||||
RenderList() {
|
||||
void init() {
|
||||
|
||||
element_count = 0;
|
||||
for (int i=0;i<MAX_ELEMENTS;i++)
|
||||
elements=memnew_arr(Element*,max_elements);
|
||||
_elements=memnew_arr(Element,max_elements);
|
||||
for (int i=0;i<max_elements;i++)
|
||||
elements[i]=&_elements[i]; // assign elements
|
||||
|
||||
}
|
||||
|
||||
RenderList() {
|
||||
|
||||
}
|
||||
~RenderList() {
|
||||
memdelete_arr(elements);
|
||||
memdelete_arr(_elements);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -50,11 +50,16 @@
|
|||
#ifdef ANDROID_ENABLED
|
||||
#include "platform/android/ifaddrs_android.h"
|
||||
#else
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
IP_Address IP_Unix::_resolve_hostname(const String& p_hostname) {
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
#include "stream_peer_tcp_posix.h"
|
||||
#include "packet_peer_udp_posix.h"
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
@ -305,7 +307,17 @@ Error OS_Unix::execute(const String& p_path, const List<String>& p_arguments,boo
|
|||
args.push_back((char*)cs[i].get_data());// shitty C cast
|
||||
args.push_back(0);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if(p_path.find("/")) {
|
||||
// exec name contains path so use it
|
||||
execv(p_path.utf8().get_data(),&args[0]);
|
||||
}else{
|
||||
// use program name and search through PATH to find it
|
||||
execvp(getprogname(),&args[0]);
|
||||
}
|
||||
#else
|
||||
execv(p_path.utf8().get_data(),&args[0]);
|
||||
#endif
|
||||
// still alive? something failed..
|
||||
fprintf(stderr,"**ERROR** OS_Unix::execute - Could not create child process while executing: %s\n",p_path.utf8().get_data());
|
||||
abort();
|
||||
|
@ -421,6 +433,12 @@ String OS_Unix::get_executable_path() const {
|
|||
return OS::get_executable_path();
|
||||
}
|
||||
return b;
|
||||
#elif defined(__FreeBSD__)
|
||||
char resolved_path[MAXPATHLEN];
|
||||
|
||||
realpath(OS::get_executable_path().utf8().get_data(), resolved_path);
|
||||
|
||||
return String(resolved_path);
|
||||
#else
|
||||
ERR_PRINT("Warning, don't know how to obtain executable path on this OS! Please override this function properly.");
|
||||
return OS::get_executable_path();
|
||||
|
|
|
@ -51,7 +51,7 @@ String GDScriptLanguage::get_template(const String& p_class_name, const String&
|
|||
"# var a=2\n"+
|
||||
"# var b=\"textvar\"\n\n"+
|
||||
"func _ready():\n"+
|
||||
"\t# Initalization here\n"+
|
||||
"\t# Initialization here\n"+
|
||||
"\tpass\n"+
|
||||
"\n"+
|
||||
"\n";
|
||||
|
|
|
@ -84,13 +84,11 @@ static int frame_count = 0;
|
|||
switch (frame_count) {
|
||||
|
||||
case 0: {
|
||||
|
||||
int backingWidth;
|
||||
int backingHeight;
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
||||
|
||||
iphone_main(backingWidth, backingHeight, gargc, gargv);
|
||||
int backingWidth;
|
||||
int backingHeight;
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
||||
|
||||
|
||||
OS::VideoMode vm;
|
||||
vm.fullscreen = true;
|
||||
|
@ -198,6 +196,13 @@ static int frame_count = 0;
|
|||
//glView.autoresizesSubviews = YES;
|
||||
//[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
|
||||
|
||||
int backingWidth;
|
||||
int backingHeight;
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
|
||||
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
|
||||
|
||||
iphone_main(backingWidth, backingHeight, gargc, gargv);
|
||||
|
||||
view_controller = [[ViewController alloc] init];
|
||||
view_controller.view = glView;
|
||||
window.rootViewController = view_controller;
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#import <MediaPlayer/MediaPlayer.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#define USE_CADISPLAYLINK 1 //iOS version 3.1+ is required
|
||||
|
||||
@protocol GLViewDelegate;
|
||||
|
||||
@interface GLView : UIView<UIKeyInput>
|
||||
|
@ -51,8 +53,14 @@
|
|||
// OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist)
|
||||
GLuint depthRenderbuffer;
|
||||
|
||||
#if USE_CADISPLAYLINK
|
||||
// CADisplayLink available on 3.1+ synchronizes the animation timer & drawing with the refresh rate of the display, only supports animation intervals of 1/60 1/30 & 1/15
|
||||
CADisplayLink *displayLink;
|
||||
#else
|
||||
// An animation timer that, when animation is started, will periodically call -drawView at the given rate.
|
||||
NSTimer *animationTimer;
|
||||
#endif
|
||||
|
||||
NSTimeInterval animationInterval;
|
||||
|
||||
// Delegate to do our drawing, called by -drawView, which can be called manually or via the animation timer.
|
||||
|
|
|
@ -413,7 +413,19 @@ static void clear_touches() {
|
|||
return;
|
||||
active = TRUE;
|
||||
printf("start animation!\n");
|
||||
#if USE_CADISPLAYLINK
|
||||
// Approximate frame rate
|
||||
// assumes device refreshes at 60 fps
|
||||
int frameInterval = (int) floor(animationInterval * 60.0f);
|
||||
|
||||
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)];
|
||||
[displayLink setFrameInterval:frameInterval];
|
||||
|
||||
// Setup DisplayLink in main thread
|
||||
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
||||
#else
|
||||
animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
|
||||
#endif
|
||||
|
||||
if (video_playing)
|
||||
{
|
||||
|
@ -427,8 +439,13 @@ static void clear_touches() {
|
|||
return;
|
||||
active = FALSE;
|
||||
printf("******** stop animation!\n");
|
||||
#if USE_CADISPLAYLINK
|
||||
[displayLink invalidate];
|
||||
displayLink = nil;
|
||||
#else
|
||||
[animationTimer invalidate];
|
||||
animationTimer = nil;
|
||||
#endif
|
||||
clear_touches();
|
||||
|
||||
if (video_playing)
|
||||
|
@ -441,7 +458,11 @@ static void clear_touches() {
|
|||
{
|
||||
animationInterval = interval;
|
||||
|
||||
#if USE_CADISPLAYLINK
|
||||
if(displayLink)
|
||||
#else
|
||||
if(animationTimer)
|
||||
#endif
|
||||
{
|
||||
[self stopAnimation];
|
||||
[self startAnimation];
|
||||
|
@ -451,6 +472,17 @@ static void clear_touches() {
|
|||
// Updates the OpenGL view when the timer fires
|
||||
- (void)drawView
|
||||
{
|
||||
#if USE_CADISPLAYLINK
|
||||
// Pause the CADisplayLink to avoid recursion
|
||||
[displayLink setPaused: YES];
|
||||
|
||||
// Process all input events
|
||||
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource);
|
||||
|
||||
// We are good to go, resume the CADisplayLink
|
||||
[displayLink setPaused: NO];
|
||||
#endif
|
||||
|
||||
if (!active) {
|
||||
printf("draw view not active!\n");
|
||||
return;
|
||||
|
|
|
@ -22,7 +22,7 @@ def get_opts():
|
|||
return [
|
||||
('ISIMPLATFORM', 'name of the iphone platform', 'iPhoneSimulator'),
|
||||
('ISIMPATH', 'the path to iphone toolchain', '/Applications/Xcode.app/Contents/Developer/Platforms/${ISIMPLATFORM}.platform'),
|
||||
('ISIMSDK', 'path to the iphone SDK', '$ISIMPATH/Developer/SDKs/${ISIMPLATFORM}7.1.sdk'),
|
||||
('ISIMSDK', 'path to the iphone SDK', '$ISIMPATH/Developer/SDKs/${ISIMPLATFORM}.sdk'),
|
||||
('game_center', 'Support for game center', 'yes'),
|
||||
('store_kit', 'Support for in-app store', 'yes'),
|
||||
('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'),
|
||||
|
|
|
@ -593,10 +593,11 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
|||
|
||||
ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
|
||||
|
||||
// Make sure we don't include modifiers for the modifier key itself.
|
||||
KeyEvent ke;
|
||||
ke.mod_state.shift=shift_mem;
|
||||
ke.mod_state.alt=alt_mem;
|
||||
ke.mod_state.control=control_mem;
|
||||
ke.mod_state.shift= (wParam != VK_SHIFT) ? shift_mem : false;
|
||||
ke.mod_state.alt= (! (wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false;
|
||||
ke.mod_state.control= (wParam != VK_CONTROL) ? control_mem : false;
|
||||
ke.mod_state.meta=meta_mem;
|
||||
ke.uMsg=uMsg;
|
||||
|
||||
|
|
|
@ -76,24 +76,23 @@ def configure(env):
|
|||
else:
|
||||
env["bits"]="32"
|
||||
|
||||
|
||||
env.Append(CPPPATH=['#platform/x11'])
|
||||
if (env["use_llvm"]=="yes"):
|
||||
env["CC"]="clang"
|
||||
env["CXX"]="clang++"
|
||||
env["LD"]="clang++"
|
||||
if (env["use_sanitizer"]=="yes"):
|
||||
env.Append(CXXFLAGS=['-fsanitize=address','-fno-omit-frame-pointer'])
|
||||
env.Append(LINKFLAGS=['-fsanitize=address'])
|
||||
env.extra_suffix=".llvms"
|
||||
else:
|
||||
env.extra_suffix=".llvm"
|
||||
if 'clang++' not in env['CXX']:
|
||||
env["CC"]="clang"
|
||||
env["CXX"]="clang++"
|
||||
env["LD"]="clang++"
|
||||
env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
|
||||
env.extra_suffix=".llvm"
|
||||
|
||||
if (env["colored"]=="yes"):
|
||||
if sys.stdout.isatty():
|
||||
env.Append(CXXFLAGS=["-fcolor-diagnostics"])
|
||||
|
||||
|
||||
|
||||
if (env["use_sanitizer"]=="yes"):
|
||||
env.Append(CXXFLAGS=['-fsanitize=address','-fno-omit-frame-pointer'])
|
||||
env.Append(LINKFLAGS=['-fsanitize=address'])
|
||||
env.extra_suffix+="s"
|
||||
|
||||
#if (env["tools"]=="no"):
|
||||
# #no tools suffix
|
||||
|
@ -147,11 +146,6 @@ def configure(env):
|
|||
env.Append(LINKFLAGS=['-m64','-L/usr/lib/i686-linux-gnu'])
|
||||
|
||||
|
||||
if (env["CXX"]=="clang++"):
|
||||
env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
|
||||
env["CC"]="clang"
|
||||
env["LD"]="clang++"
|
||||
|
||||
import methods
|
||||
|
||||
env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
|
||||
|
|
|
@ -810,6 +810,23 @@ void CanvasItem::_shader_changed() {
|
|||
}
|
||||
#endif
|
||||
|
||||
void CanvasItem::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
if (p_idx==0 && shader.is_valid() && (p_function.operator String()=="get_shader_param" || p_function.operator String()=="set_shader_param")) {
|
||||
|
||||
List<PropertyInfo> pl;
|
||||
shader->get_param_list(&pl);
|
||||
for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
|
||||
r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\"");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Node::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
|
||||
void CanvasItem::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_sort_children"),&CanvasItem::_sort_children);
|
||||
|
@ -845,7 +862,7 @@ void CanvasItem::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity);
|
||||
ObjectTypeDB::bind_method(_MD("get_self_opacity"),&CanvasItem::get_self_opacity);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_behind_parent","enabe"),&CanvasItem::set_draw_behind_parent);
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_behind_parent","enable"),&CanvasItem::set_draw_behind_parent);
|
||||
ObjectTypeDB::bind_method(_MD("is_draw_behind_parent_enabled"),&CanvasItem::is_draw_behind_parent_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top);
|
||||
|
@ -882,6 +899,10 @@ void CanvasItem::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_use_parent_shader","enable"),&CanvasItem::set_use_parent_shader);
|
||||
ObjectTypeDB::bind_method(_MD("get_use_parent_shader"),&CanvasItem::get_use_parent_shader);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItem::set_shader_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItem::get_shader_param);
|
||||
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_draw"));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") );
|
||||
|
|
|
@ -221,6 +221,8 @@ public:
|
|||
void set_shader_param(const StringName& p_param,const Variant& p_value);
|
||||
Variant get_shader_param(const StringName& p_param) const;
|
||||
|
||||
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
CanvasItem();
|
||||
~CanvasItem();
|
||||
};
|
||||
|
|
|
@ -604,7 +604,7 @@ Vector3 Camera::project_position(const Point2& p_point) const {
|
|||
|
||||
Vector2 point;
|
||||
point.x = (p_point.x/viewport_size.x) * 2.0 - 1.0;
|
||||
point.y = (p_point.y/viewport_size.y) * 2.0 - 1.0;
|
||||
point.y = (1.0-(p_point.y/viewport_size.y)) * 2.0 - 1.0;
|
||||
point*=vp_size;
|
||||
|
||||
Vector3 p(point.x,point.y,-near);
|
||||
|
|
|
@ -582,7 +582,7 @@ void ShaderMaterial::get_argument_options(const StringName& p_function,int p_idx
|
|||
List<PropertyInfo> pl;
|
||||
shader->get_param_list(&pl);
|
||||
for (List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
|
||||
r_options->push_back("\""+E->get().name.replace("shader_param/","")+"\"");
|
||||
r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -525,24 +525,32 @@ bool PolygonPathFinder::is_point_inside(const Vector2& p_point) const {
|
|||
|
||||
Vector2 PolygonPathFinder::get_closest_point(const Vector2& p_point) const {
|
||||
|
||||
int closest_idx=-1;
|
||||
float closest_dist=1e20;
|
||||
for(int i=0;i<points.size()-2;i++) {
|
||||
Vector2 closest_point;
|
||||
|
||||
for (Set<Edge>::Element *E=edges.front();E;E=E->next()) {
|
||||
|
||||
const Edge& e=E->get();
|
||||
Vector2 seg[2]={
|
||||
points[e.points[0]].pos,
|
||||
points[e.points[1]].pos
|
||||
};
|
||||
|
||||
|
||||
Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point,seg);
|
||||
float d = p_point.distance_squared_to(closest);
|
||||
|
||||
float d = p_point.distance_squared_to(points[i].pos);
|
||||
if (d<closest_dist) {
|
||||
closest_dist=d;
|
||||
closest_idx=i;
|
||||
closest_point=closest;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(closest_dist==1e20,Vector2());
|
||||
|
||||
ERR_FAIL_COND_V(closest_idx==-1,Vector2());
|
||||
|
||||
return points[closest_idx].pos;
|
||||
return closest_point;
|
||||
}
|
||||
|
||||
|
||||
Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2& p_from, const Vector2& p_to) const {
|
||||
|
||||
Vector<Vector2> inters;
|
||||
|
|
|
@ -85,6 +85,12 @@ void StyleBox::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("draw"),&StyleBox::draw);
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "content_margin/left", PROPERTY_HINT_RANGE,"-1,2048,1" ), _SCS("set_default_margin"),_SCS("get_default_margin"), MARGIN_LEFT );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "content_margin/right", PROPERTY_HINT_RANGE,"-1,2048,1" ), _SCS("set_default_margin"),_SCS("get_default_margin"), MARGIN_RIGHT );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "content_margin/top", PROPERTY_HINT_RANGE,"-1,2048,1" ), _SCS("set_default_margin"),_SCS("get_default_margin"), MARGIN_TOP);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "content_margin/bottom", PROPERTY_HINT_RANGE,"-1,2048,1" ), _SCS("set_default_margin"),_SCS("get_default_margin"), MARGIN_BOTTOM );
|
||||
|
||||
|
||||
}
|
||||
|
||||
StyleBox::StyleBox() {
|
||||
|
|
|
@ -935,21 +935,21 @@ float CubeMap::get_lossy_storage_quality() const {
|
|||
|
||||
bool CubeMap::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
if (p_name=="side/left")
|
||||
if (p_name=="side/left") {
|
||||
set_side(SIDE_LEFT,p_value);
|
||||
if (p_name=="side/right")
|
||||
} else if (p_name=="side/right") {
|
||||
set_side(SIDE_RIGHT,p_value);
|
||||
if (p_name=="side/bottom")
|
||||
} else if (p_name=="side/bottom") {
|
||||
set_side(SIDE_BOTTOM,p_value);
|
||||
if (p_name=="side/top")
|
||||
} else if (p_name=="side/top") {
|
||||
set_side(SIDE_TOP,p_value);
|
||||
if (p_name=="side/front")
|
||||
} else if (p_name=="side/front") {
|
||||
set_side(SIDE_FRONT,p_value);
|
||||
if (p_name=="side/back")
|
||||
} else if (p_name=="side/back") {
|
||||
set_side(SIDE_BACK,p_value);
|
||||
else if (p_name=="flags")
|
||||
} else if (p_name=="flags") {
|
||||
set_flags(p_value);
|
||||
else if (p_name=="storage") {
|
||||
} else if (p_name=="storage") {
|
||||
storage=Storage(p_value.operator int());
|
||||
} else if (p_name=="lossy_quality") {
|
||||
lossy_storage_quality=p_value;
|
||||
|
@ -962,25 +962,25 @@ bool CubeMap::_set(const StringName& p_name, const Variant& p_value) {
|
|||
|
||||
bool CubeMap::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
if (p_name=="side/left")
|
||||
if (p_name=="side/left") {
|
||||
r_ret=get_side(SIDE_LEFT);
|
||||
if (p_name=="side/right")
|
||||
} else if (p_name=="side/right") {
|
||||
r_ret=get_side(SIDE_RIGHT);
|
||||
if (p_name=="side/bottom")
|
||||
} else if (p_name=="side/bottom") {
|
||||
r_ret=get_side(SIDE_BOTTOM);
|
||||
if (p_name=="side/top")
|
||||
} else if (p_name=="side/top") {
|
||||
r_ret=get_side(SIDE_TOP);
|
||||
if (p_name=="side/front")
|
||||
} else if (p_name=="side/front") {
|
||||
r_ret=get_side(SIDE_FRONT);
|
||||
if (p_name=="side/back")
|
||||
} else if (p_name=="side/back") {
|
||||
r_ret=get_side(SIDE_BACK);
|
||||
else if (p_name=="flags")
|
||||
} else if (p_name=="flags") {
|
||||
r_ret= flags;
|
||||
else if (p_name=="storage")
|
||||
} else if (p_name=="storage") {
|
||||
r_ret= storage;
|
||||
else if (p_name=="lossy_quality")
|
||||
} else if (p_name=="lossy_quality") {
|
||||
r_ret= lossy_storage_quality;
|
||||
else
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1141,10 +1141,36 @@ EditorImportExport* EditorImportExport::singleton=NULL;
|
|||
|
||||
void EditorImportExport::add_import_plugin(const Ref<EditorImportPlugin>& p_plugin) {
|
||||
|
||||
// Need to make sure the name is unique if we are going to lookup by it
|
||||
ERR_FAIL_COND(by_idx.has(p_plugin->get_name()));
|
||||
|
||||
by_idx[ p_plugin->get_name() ]=plugins.size();
|
||||
plugins.push_back(p_plugin);
|
||||
}
|
||||
|
||||
void EditorImportExport::remove_import_plugin(const Ref<EditorImportPlugin>& p_plugin) {
|
||||
|
||||
String plugin_name = p_plugin->get_name();
|
||||
|
||||
// Keep the indices the same
|
||||
// Find the index of the target plugin
|
||||
ERR_FAIL_COND(!by_idx.has(plugin_name));
|
||||
int idx = by_idx[plugin_name];
|
||||
int last_idx = plugins.size() - 1;
|
||||
|
||||
// Swap the last plugin and the target one
|
||||
SWAP(plugins[idx], plugins[last_idx]);
|
||||
|
||||
// Update the index of the old last one
|
||||
by_idx[plugins[idx]->get_name()] = idx;
|
||||
|
||||
// Remove the target plugin's by_idx entry
|
||||
by_idx.erase(plugin_name);
|
||||
|
||||
// Erase the plugin
|
||||
plugins.remove(last_idx);
|
||||
}
|
||||
|
||||
int EditorImportExport::get_import_plugin_count() const{
|
||||
|
||||
return plugins.size();
|
||||
|
|
|
@ -270,6 +270,7 @@ public:
|
|||
static EditorImportExport* get_singleton() { return singleton; }
|
||||
|
||||
void add_import_plugin(const Ref<EditorImportPlugin>& p_plugin);
|
||||
void remove_import_plugin(const Ref<EditorImportPlugin>& p_plugin);
|
||||
int get_import_plugin_count() const;
|
||||
Ref<EditorImportPlugin> get_import_plugin(int p_idx) const;
|
||||
Ref<EditorImportPlugin> get_import_plugin_by_name(const String& p_string) const;
|
||||
|
|
|
@ -336,6 +336,19 @@ void EditorNode::_vp_resized() {
|
|||
|
||||
}
|
||||
|
||||
void EditorNode::_rebuild_import_menu()
|
||||
{
|
||||
PopupMenu* p = import_menu->get_popup();
|
||||
p->clear();
|
||||
p->add_item("Sub-Scene", FILE_IMPORT_SUBSCENE);
|
||||
p->add_separator();
|
||||
for (int i = 0; i < editor_import_export->get_import_plugin_count(); i++) {
|
||||
p->add_item(editor_import_export->get_import_plugin(i)->get_visible_name(), IMPORT_PLUGIN_BASE + i);
|
||||
}
|
||||
p->add_separator();
|
||||
p->add_item("Re-Import..", SETTINGS_IMPORT);
|
||||
}
|
||||
|
||||
void EditorNode::_node_renamed() {
|
||||
|
||||
if (property_editor)
|
||||
|
@ -1967,6 +1980,25 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
|||
log->add_message("REDO: "+action);
|
||||
|
||||
} break;
|
||||
|
||||
case EDIT_REVERT: {
|
||||
|
||||
Node *scene = get_edited_scene();
|
||||
|
||||
if (!scene)
|
||||
break;
|
||||
|
||||
if (unsaved_cache && !p_confirmed) {
|
||||
confirmation->get_ok()->set_text("Revert");
|
||||
confirmation->set_text("This action cannot be undone. Revert anyway?");
|
||||
confirmation->popup_centered(Size2(300,70));
|
||||
break;
|
||||
}
|
||||
|
||||
Error err = load_scene(scene->get_filename());
|
||||
|
||||
} break;
|
||||
|
||||
#if 0
|
||||
case NODE_EXTERNAL_INSTANCE: {
|
||||
|
||||
|
@ -2388,6 +2420,19 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
|
|||
}
|
||||
|
||||
|
||||
void EditorNode::add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
|
||||
|
||||
editor_import_export->add_import_plugin(p_editor_import);
|
||||
_rebuild_import_menu();
|
||||
}
|
||||
|
||||
void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
|
||||
|
||||
editor_import_export->remove_import_plugin(p_editor_import);
|
||||
_rebuild_import_menu();
|
||||
}
|
||||
|
||||
|
||||
void EditorNode::set_edited_scene(Node *p_scene) {
|
||||
|
||||
if (edited_scene) {
|
||||
|
@ -3152,6 +3197,9 @@ void EditorNode::_bind_methods() {
|
|||
ObjectTypeDB::bind_method("_sources_changed",&EditorNode::_sources_changed);
|
||||
ObjectTypeDB::bind_method("_fs_changed",&EditorNode::_fs_changed);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin);
|
||||
ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin);
|
||||
ObjectTypeDB::bind_method(_MD("get_gui_base"), &EditorNode::get_gui_base);
|
||||
|
||||
ADD_SIGNAL( MethodInfo("play_pressed") );
|
||||
ADD_SIGNAL( MethodInfo("pause_pressed") );
|
||||
|
@ -3469,6 +3517,8 @@ EditorNode::EditorNode() {
|
|||
p->add_separator();
|
||||
p->add_item("Project Settings",RUN_SETTINGS);
|
||||
p->add_separator();
|
||||
p->add_item("Revert Scene",EDIT_REVERT);
|
||||
p->add_separator();
|
||||
p->add_item("Quit to Project List",RUN_PROJECT_MANAGER,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_Q);
|
||||
p->add_item("Quit",FILE_QUIT,KEY_MASK_CMD+KEY_Q);
|
||||
|
||||
|
@ -3513,8 +3563,6 @@ EditorNode::EditorNode() {
|
|||
left_menu_hb->add_child( import_menu );
|
||||
|
||||
p=import_menu->get_popup();
|
||||
p->add_item("Sub-Scene",FILE_IMPORT_SUBSCENE);
|
||||
p->add_separator();
|
||||
p->connect("item_pressed",this,"_menu_option");
|
||||
|
||||
export_button = memnew( ToolButton );
|
||||
|
@ -3552,7 +3600,7 @@ EditorNode::EditorNode() {
|
|||
play_button->set_icon(gui_base->get_icon("MainPlay","EditorIcons"));
|
||||
play_button->set_focus_mode(Control::FOCUS_NONE);
|
||||
play_button->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY));
|
||||
play_button->set_tooltip("Start the scene (F5).");
|
||||
play_button->set_tooltip("Play the project (F5).");
|
||||
|
||||
|
||||
|
||||
|
@ -4023,11 +4071,6 @@ EditorNode::EditorNode() {
|
|||
editor_import_export->add_import_plugin( Ref<EditorSampleImportPlugin>( memnew(EditorSampleImportPlugin(this))));
|
||||
editor_import_export->add_import_plugin( Ref<EditorTranslationImportPlugin>( memnew(EditorTranslationImportPlugin(this))));
|
||||
|
||||
|
||||
for(int i=0;i<editor_import_export->get_import_plugin_count();i++) {
|
||||
import_menu->get_popup()->add_item(editor_import_export->get_import_plugin(i)->get_visible_name(),IMPORT_PLUGIN_BASE+i);
|
||||
}
|
||||
|
||||
editor_import_export->add_export_plugin( Ref<EditorTextureExportPlugin>( memnew(EditorTextureExportPlugin)));
|
||||
|
||||
add_editor_plugin( memnew( CanvasItemEditorPlugin(this) ) );
|
||||
|
@ -4072,9 +4115,7 @@ EditorNode::EditorNode() {
|
|||
circle_step_frame=OS::get_singleton()->get_frames_drawn();;
|
||||
circle_step=0;
|
||||
|
||||
|
||||
import_menu->get_popup()->add_separator();
|
||||
import_menu->get_popup()->add_item("Re-Import..",SETTINGS_IMPORT);
|
||||
_rebuild_import_menu();
|
||||
|
||||
editor_plugin_screen=NULL;
|
||||
editor_plugin_over=NULL;
|
||||
|
|
|
@ -127,6 +127,7 @@ class EditorNode : public Node {
|
|||
FILE_EXTERNAL_OPEN_SCENE,
|
||||
EDIT_UNDO,
|
||||
EDIT_REDO,
|
||||
EDIT_REVERT,
|
||||
RESOURCE_NEW,
|
||||
RESOURCE_LOAD,
|
||||
RESOURCE_SAVE,
|
||||
|
@ -339,6 +340,8 @@ class EditorNode : public Node {
|
|||
void _show_messages();
|
||||
void _vp_resized();
|
||||
|
||||
void _rebuild_import_menu();
|
||||
|
||||
void _save_scene(String p_file);
|
||||
|
||||
|
||||
|
@ -420,6 +423,9 @@ public:
|
|||
static void add_editor_plugin(EditorPlugin *p_editor);
|
||||
static void remove_editor_plugin(EditorPlugin *p_editor);
|
||||
|
||||
void add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
|
||||
void remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
|
||||
|
||||
|
||||
void edit_node(Node *p_node);
|
||||
void edit_resource(const Ref<Resource>& p_resource);
|
||||
|
|
|
@ -631,7 +631,10 @@ bool ScriptEditor::_test_script_times_on_disk() {
|
|||
|
||||
|
||||
if (!all_ok)
|
||||
disk_changed->call_deferred("popup_centered_ratio",0.5);
|
||||
if (bool(EDITOR_DEF("text_editor/auto_reload_changed_scripts",false)))
|
||||
script_editor->_reload_scripts();
|
||||
else
|
||||
disk_changed->call_deferred("popup_centered_ratio",0.5);
|
||||
|
||||
return all_ok;
|
||||
}
|
||||
|
@ -1806,6 +1809,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
|
|||
|
||||
script_editor->hide();
|
||||
|
||||
EDITOR_DEF("text_editor/auto_reload_changed_scripts",false);
|
||||
EDITOR_DEF("external_editor/use_external_editor",false);
|
||||
EDITOR_DEF("external_editor/exec_path","");
|
||||
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"external_editor/exec_path",PROPERTY_HINT_GLOBAL_FILE));
|
||||
|
|
|
@ -79,10 +79,22 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
|||
//accept->get_cancel()->hide();
|
||||
accept->get_ok()->set_text("Ugh");
|
||||
accept->set_text(String("Error loading scene from ")+p_file);
|
||||
accept->popup_centered(Size2(300,70));;
|
||||
accept->popup_centered(Size2(300,70));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If the scene hasn't been saved yet a cyclical dependency cannot exist.
|
||||
if (edited_scene->get_filename()!="") {
|
||||
|
||||
if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) {
|
||||
|
||||
accept->get_ok()->set_text("Ok");
|
||||
accept->set_text(String("Cannot instance the scene '")+p_file+String("' because the current scene exists within one of its' nodes."));
|
||||
accept->popup_centered(Size2(300,90));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
instanced_scene->generate_instance_state();
|
||||
instanced_scene->set_filename( Globals::get_singleton()->localize_path(p_file) );
|
||||
|
||||
|
@ -100,6 +112,25 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
|||
|
||||
}
|
||||
|
||||
bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) {
|
||||
int childCount = p_desired_node->get_child_count();
|
||||
|
||||
if (p_desired_node->get_filename()==p_target_scene_path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i=0;i<childCount;i++) {
|
||||
Node* child=p_desired_node->get_child(i);
|
||||
|
||||
if(_cyclical_dependency_exists(p_target_scene_path,child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static String _get_name_num_separator() {
|
||||
switch(EditorSettings::get_singleton()->get("scenetree_editor/duplicate_node_name_num_separator").operator int()) {
|
||||
case 0: return "";
|
||||
|
|
|
@ -102,6 +102,7 @@ class SceneTreeDock : public VBoxContainer {
|
|||
void _load_request(const String& p_path);
|
||||
void _script_open_request(const Ref<Script>& p_script);
|
||||
|
||||
bool _cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node);
|
||||
|
||||
void _node_selected();
|
||||
void _node_renamed();
|
||||
|
|
|
@ -212,8 +212,8 @@ class DaeExporter:
|
|||
imgid = self.new_id("image")
|
||||
|
||||
if (not os.path.isfile(imgpath)):
|
||||
if img_tmp_path.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")):
|
||||
imgpath="images/"+os.path.basename(img_tmp_path)
|
||||
if imgpath.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")):
|
||||
imgpath="images/"+os.path.basename(imgpath)
|
||||
else:
|
||||
imgpath="images/"+image.name+".png"
|
||||
|
||||
|
|
Loading…
Reference in New Issue