Merge branch 'master' of github.com:okamstudio/godot
Conflicts: drivers/SCsub platform/x11/detect.py platform/x11/os_x11.h
This commit is contained in:
commit
4ab1bcde35
@ -10,11 +10,6 @@ The editor, language and APIs are feature rich, yet simple to learn, allowing yo
|
||||
Godot has been developed by Juan Linietsky and Ariel Manzur for several years, and was born as an in-house engine, used to publish several work-for-hire titles.
|
||||
Development is sponsored by OKAM Studio (http://www.okamstudio.com).
|
||||
|
||||
### Godot is BETA. Collaborate!!
|
||||
|
||||
Having been developed as in-house means that the user experience may still not be ideal for everyone. The features needed to make a great game are there, but we really need your help to fix all the rough edges and improve usability (via feedback and/or code contributions).
|
||||
We know we are close to having an awesome, open source, game engine with nothing to envy from the best commercial offerings, but we can't do this alone. This is why Godot is now open source, so everyone can help us reach this goal.
|
||||
|
||||
### Documentation
|
||||
|
||||
Documentation has been moved to the [GitHub Wiki](https://github.com/okamstudio/godot/wiki).
|
||||
|
@ -12,9 +12,9 @@ Ref<ResourceInteractiveLoader> _ResourceLoader::load_interactive(const String& p
|
||||
return ResourceLoader::load_interactive(p_path,p_type_hint);
|
||||
}
|
||||
|
||||
RES _ResourceLoader::load(const String &p_path,const String& p_type_hint) {
|
||||
RES _ResourceLoader::load(const String &p_path,const String& p_type_hint, bool p_no_cache) {
|
||||
|
||||
RES ret = ResourceLoader::load(p_path,p_type_hint);
|
||||
RES ret = ResourceLoader::load(p_path,p_type_hint, p_no_cache);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ void _ResourceLoader::_bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("load_interactive:ResourceInteractiveLoader","path","type_hint"),&_ResourceLoader::load_interactive,DEFVAL(""));
|
||||
ObjectTypeDB::bind_method(_MD("load:Resource","path","type_hint"),&_ResourceLoader::load,DEFVAL(""));
|
||||
ObjectTypeDB::bind_method(_MD("load:Resource","path","type_hint", "p_no_cache"),&_ResourceLoader::load,DEFVAL(""), DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_recognized_extensions_for_type","type"),&_ResourceLoader::get_recognized_extensions_for_type);
|
||||
ObjectTypeDB::bind_method(_MD("set_abort_on_missing_resources","abort"),&_ResourceLoader::set_abort_on_missing_resources);
|
||||
ObjectTypeDB::bind_method(_MD("get_dependencies"),&_ResourceLoader::get_dependencies);
|
||||
@ -1121,6 +1121,7 @@ String _File::get_as_text() const {
|
||||
text+=l+"\n";
|
||||
l = get_line();
|
||||
}
|
||||
text+=l;
|
||||
|
||||
return text;
|
||||
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
|
||||
static _ResourceLoader *get_singleton() { return singleton; }
|
||||
Ref<ResourceInteractiveLoader> load_interactive(const String& p_path,const String& p_type_hint="");
|
||||
RES load(const String &p_path,const String& p_type_hint="");
|
||||
RES load(const String &p_path,const String& p_type_hint="", bool p_no_cache = false);
|
||||
DVector<String> get_recognized_extensions_for_type(const String& p_type);
|
||||
void set_abort_on_missing_resources(bool p_abort);
|
||||
StringArray get_dependencies(const String& p_path);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "http_client.h"
|
||||
#include "io/stream_peer_ssl.h"
|
||||
|
||||
VARIANT_ENUM_CAST(HTTPClient::Status);
|
||||
|
||||
Error HTTPClient::connect_url(const String& p_url) {
|
||||
|
||||
return OK;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "os/semaphore.h"
|
||||
#include "hash_map.h"
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST(IP::ResolverStatus);
|
||||
|
||||
/************* RESOLVER ******************/
|
||||
|
||||
|
@ -30,9 +30,11 @@
|
||||
#include "print_string.h"
|
||||
//#define DEBUG_XML
|
||||
|
||||
VARIANT_ENUM_CAST(XMLParser::NodeType);
|
||||
|
||||
static bool _equalsn(const CharType* str1, const CharType* str2, int len) {
|
||||
int i;
|
||||
for(i=0; str1[i] && str2[i] && i < len; ++i)
|
||||
for(i=0; i < len && str1[i] && str2[i] ; ++i)
|
||||
if (str1[i] != str2[i])
|
||||
return false;
|
||||
|
||||
|
@ -136,7 +136,10 @@ public:
|
||||
|
||||
static int b;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0603) || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // windows 8 phone?
|
||||
b = (int)((a>0.0f) ? (a + 0.5f):(a -0.5f));
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1800
|
||||
__asm fld a
|
||||
__asm fistp b
|
||||
/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||
@ -147,6 +150,7 @@ public:
|
||||
"fistpl %0 \n\t"
|
||||
: "=m" (b)
|
||||
: "m" (a));*/
|
||||
|
||||
#else
|
||||
b=lrintf(a); //assuming everything but msvc 2012 or earlier has lrint
|
||||
#endif
|
||||
|
@ -87,7 +87,9 @@ Vector<StringName> MethodBind::get_argument_names() const {
|
||||
|
||||
|
||||
void MethodBind::set_default_arguments(const Vector<Variant>& p_defargs) {
|
||||
default_arguments=p_defargs; default_argument_count=default_arguments.size();
|
||||
default_arguments=p_defargs;
|
||||
default_argument_count=default_arguments.size();
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
@ -1694,6 +1694,11 @@ void ObjectDB::debug_objects(DebugFunc p_func) {
|
||||
}
|
||||
|
||||
|
||||
void Object::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
|
||||
}
|
||||
|
||||
int ObjectDB::get_object_count() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
|
@ -583,6 +583,7 @@ public:
|
||||
|
||||
virtual void get_translatable_strings(List<String> *p_strings) const;
|
||||
|
||||
virtual void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
StringName XL_MESSAGE(const StringName& p_message) const; //translate message (internationalization)
|
||||
StringName tr(const StringName& p_message) const; //translate message (alternative)
|
||||
|
@ -805,12 +805,25 @@ void ObjectTypeDB::add_virtual_method(const StringName& p_type,const MethodInfo&
|
||||
|
||||
}
|
||||
|
||||
void ObjectTypeDB::get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods ) {
|
||||
void ObjectTypeDB::get_virtual_methods(const StringName& p_type, List<MethodInfo> * p_methods , bool p_no_inheritance) {
|
||||
|
||||
ERR_FAIL_COND(!types.has(p_type));
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
*p_methods=types[p_type].virtual_methods;
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
TypeInfo *check=type;
|
||||
while(check) {
|
||||
|
||||
for(List<MethodInfo>::Element *E=check->virtual_methods.front();E;E=E->next()) {
|
||||
p_methods->push_back(E->get());
|
||||
}
|
||||
|
||||
if (p_no_inheritance)
|
||||
return;
|
||||
check=check->inherits_ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ public:
|
||||
static MethodBind *get_method(StringName p_type, StringName p_name);
|
||||
|
||||
static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method );
|
||||
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods );
|
||||
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
|
||||
|
||||
static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
|
||||
static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
|
||||
|
@ -110,6 +110,7 @@ void register_core_types() {
|
||||
|
||||
|
||||
ObjectTypeDB::register_type<Reference>();
|
||||
ObjectTypeDB::register_type<WeakRef>();
|
||||
ObjectTypeDB::register_type<ResourceImportMetadata>();
|
||||
ObjectTypeDB::register_type<Resource>();
|
||||
ObjectTypeDB::register_type<FuncRef>();
|
||||
|
@ -144,7 +144,7 @@ public:
|
||||
virtual bool has_named_classes() const=0;
|
||||
virtual int find_function(const String& p_function,const String& p_code) const=0;
|
||||
virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const=0;
|
||||
virtual Error complete_keyword(const String& p_code, int p_line, const String& p_base_path, const String& p_keyword, List<String>* r_options) { return ERR_UNAVAILABLE; }
|
||||
virtual Error complete_code(const String& p_code, const String& p_base_path, Object*p_owner,List<String>* r_options,String& r_call_hint) { return ERR_UNAVAILABLE; }
|
||||
virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const=0;
|
||||
|
||||
/* DEBUGGER FUNCTIONS */
|
||||
|
126
core/variant.cpp
126
core/variant.cpp
@ -2631,3 +2631,129 @@ Variant Variant::call(const StringName& p_method,VARIANT_ARG_DECLARE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
String Variant::get_construct_string() const {
|
||||
|
||||
switch( type ) {
|
||||
|
||||
case NIL: return "null";
|
||||
case BOOL: return _data._bool ? "true" : "false";
|
||||
case INT: return String::num(_data._int);
|
||||
case REAL: return String::num(_data._real);
|
||||
case STRING: return "\""+*reinterpret_cast<const String*>(_data._mem)+"\"";
|
||||
case VECTOR2: return "Vector2("+operator Vector2()+")";
|
||||
case RECT2: return "Rect2("+operator Rect2()+")";
|
||||
case MATRIX32: return "Matrix32("+operator Matrix32()+")";
|
||||
case VECTOR3: return "Vector3("+operator Vector3()+")";
|
||||
case PLANE: return "Plane("+operator Plane()+")";
|
||||
//case QUAT:
|
||||
case _AABB: return "AABB("+operator AABB()+")";
|
||||
case QUAT: return "Quat("+operator Quat()+")";
|
||||
case MATRIX3: return "Matrix3("+operator Matrix3()+")";
|
||||
case TRANSFORM: return "Transform("+operator Transform()+")";
|
||||
case NODE_PATH: return "@\""+operator NodePath()+"\"";
|
||||
case INPUT_EVENT: return "InputEvent()";
|
||||
case COLOR: return "Color("+String::num( operator Color().r)+","+String::num( operator Color().g)+","+String::num( operator Color().b)+","+String::num( operator Color().a)+")" ;
|
||||
case DICTIONARY: {
|
||||
|
||||
const Dictionary &d =*reinterpret_cast<const Dictionary*>(_data._mem);
|
||||
//const String *K=NULL;
|
||||
String str="{";
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
|
||||
Vector<_VariantStrPair> pairs;
|
||||
|
||||
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
_VariantStrPair sp;
|
||||
sp.key=E->get().get_construct_string();
|
||||
sp.value=d[E->get()].get_construct_string();
|
||||
pairs.push_back(sp);
|
||||
}
|
||||
|
||||
pairs.sort();
|
||||
|
||||
for(int i=0;i<pairs.size();i++) {
|
||||
if (i>0)
|
||||
str+=", ";
|
||||
str+="("+pairs[i].key+":"+pairs[i].value+")";
|
||||
}
|
||||
str+="}";
|
||||
|
||||
return str;
|
||||
} break;
|
||||
case VECTOR3_ARRAY: {
|
||||
|
||||
DVector<Vector3> vec = operator DVector<Vector3>();
|
||||
String str="[";
|
||||
for(int i=0;i<vec.size();i++) {
|
||||
|
||||
if (i>0)
|
||||
str+=", ";
|
||||
str+=Variant( vec[i] ).get_construct_string();
|
||||
}
|
||||
return str+"]";
|
||||
} break;
|
||||
case STRING_ARRAY: {
|
||||
|
||||
DVector<String> vec = operator DVector<String>();
|
||||
String str="[";
|
||||
for(int i=0;i<vec.size();i++) {
|
||||
|
||||
if (i>0)
|
||||
str+=", ";
|
||||
str=str+=Variant( vec[i] ).get_construct_string();
|
||||
}
|
||||
return str+"]";
|
||||
} break;
|
||||
case INT_ARRAY: {
|
||||
|
||||
DVector<int> vec = operator DVector<int>();
|
||||
String str="[";
|
||||
for(int i=0;i<vec.size();i++) {
|
||||
|
||||
if (i>0)
|
||||
str+=", ";
|
||||
str=str+itos(vec[i]);
|
||||
}
|
||||
return str+"]";
|
||||
} break;
|
||||
case REAL_ARRAY: {
|
||||
|
||||
DVector<real_t> vec = operator DVector<real_t>();
|
||||
String str="[";
|
||||
for(int i=0;i<vec.size();i++) {
|
||||
|
||||
if (i>0)
|
||||
str+=", ";
|
||||
str=str+rtos(vec[i]);
|
||||
}
|
||||
return str+"]";
|
||||
} break;
|
||||
case ARRAY: {
|
||||
|
||||
Array arr = operator Array();
|
||||
String str="[";
|
||||
for (int i=0; i<arr.size(); i++) {
|
||||
if (i)
|
||||
str+=", ";
|
||||
str += arr[i].get_construct_string();
|
||||
};
|
||||
return str+"]";
|
||||
|
||||
} break;
|
||||
case OBJECT: {
|
||||
|
||||
if (_get_obj().obj)
|
||||
return _get_obj().obj->get_type()+".new()";
|
||||
else
|
||||
return "null";
|
||||
|
||||
} break;
|
||||
default: {
|
||||
return "["+get_type_name(type)+"]";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -167,14 +167,18 @@ public:
|
||||
static String get_type_name(Variant::Type p_type);
|
||||
static bool can_convert(Type p_type_from,Type p_type_to);
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
static Type get_type_for() {
|
||||
|
||||
GetSimpleType<T> t;
|
||||
Variant v(t.type);
|
||||
return v.get_type();
|
||||
Type r = v.get_type();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
bool is_ref() const;
|
||||
_FORCE_INLINE_ bool is_num() const { return type==INT || type==REAL; };
|
||||
_FORCE_INLINE_ bool is_array() const { return type>=ARRAY; };
|
||||
@ -415,6 +419,8 @@ public:
|
||||
static bool has_numeric_constant(Variant::Type p_type, const StringName& p_value);
|
||||
static int get_numeric_constant_value(Variant::Type p_type, const StringName& p_value);
|
||||
|
||||
String get_construct_string() const;
|
||||
|
||||
void operator=(const Variant& p_variant); // only this is enough for all the other types
|
||||
Variant(const Variant& p_variant);
|
||||
_FORCE_INLINE_ Variant() { type=NIL; }
|
||||
|
@ -757,6 +757,11 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
|
||||
r_ret=Quat(*p_args[0],*p_args[1],*p_args[2],*p_args[3]);
|
||||
}
|
||||
|
||||
static void Quat_init2(Variant& r_ret,const Variant** p_args) {
|
||||
|
||||
r_ret=Quat(((Vector3)(*p_args[0])),((float)(*p_args[1])));
|
||||
}
|
||||
|
||||
static void Color_init1(Variant& r_ret,const Variant** p_args) {
|
||||
|
||||
r_ret=Color(*p_args[0],*p_args[1],*p_args[2],*p_args[3]);
|
||||
@ -1509,6 +1514,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
|
||||
_VariantCall::add_constructor(_VariantCall::Plane_init3,Variant::PLANE,"normal",Variant::VECTOR3,"d",Variant::REAL);
|
||||
|
||||
_VariantCall::add_constructor(_VariantCall::Quat_init1,Variant::QUAT,"x",Variant::REAL,"y",Variant::REAL,"z",Variant::REAL,"w",Variant::REAL);
|
||||
_VariantCall::add_constructor(_VariantCall::Quat_init2,Variant::QUAT,"axis",Variant::VECTOR3,"angle",Variant::REAL);
|
||||
|
||||
_VariantCall::add_constructor(_VariantCall::Color_init1,Variant::COLOR,"r",Variant::REAL,"g",Variant::REAL,"b",Variant::REAL,"a",Variant::REAL);
|
||||
_VariantCall::add_constructor(_VariantCall::Color_init2,Variant::COLOR,"r",Variant::REAL,"g",Variant::REAL,"b",Variant::REAL);
|
||||
|
@ -9,7 +9,7 @@ var gray_mat = FixedMaterial.new()
|
||||
|
||||
var selected=false
|
||||
|
||||
func _input_event(event,pos,normal,shape):
|
||||
func _input_event(camera,event,pos,normal,shape):
|
||||
if (event.type==InputEvent.MOUSE_BUTTON and event.pressed):
|
||||
if (not selected):
|
||||
get_node("mesh").set_material_override(gray_mat)
|
||||
|
@ -112,8 +112,8 @@ func reset_tween():
|
||||
tween.interpolate_property(sprite, "transform/rot", 360, 0, 2, state.trans, state.eases, 2)
|
||||
|
||||
if get_node("modes/callback").is_pressed():
|
||||
tween.interpolate_callback(self, "on_callback", 0.5, "0.5 second's after")
|
||||
tween.interpolate_callback(self, "on_callback", 1.2, "1.2 second's after")
|
||||
tween.interpolate_callback(self, 0.5, "on_callback", "0.5 second's after")
|
||||
tween.interpolate_callback(self, 0.2, "on_callback", "1.2 second's after")
|
||||
|
||||
if get_node("modes/follow").is_pressed():
|
||||
follow.show()
|
||||
|
@ -8,6 +8,7 @@ Export('env')
|
||||
SConscript('unix/SCsub');
|
||||
SConscript('alsa/SCsub');
|
||||
SConscript('ao/SCsub');
|
||||
SConscript('pulseaudio/SCsub');
|
||||
SConscript('windows/SCsub');
|
||||
SConscript('gles2/SCsub');
|
||||
SConscript('gles1/SCsub');
|
||||
|
@ -162,7 +162,7 @@ CPLoader::Error CPLoader_S3M::load_sample(CPSample *p_sample) {
|
||||
p_sample->set_default_volume(def_volume);
|
||||
p_sample->set_name(name);
|
||||
|
||||
char scrs[4];
|
||||
char scrs[5];
|
||||
file->get_byte_array((uint8_t*)scrs,4);
|
||||
scrs[4]=0;
|
||||
|
||||
|
@ -1021,6 +1021,16 @@ void RasterizerGLES1::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RasterizerGLES1::shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture) {
|
||||
|
||||
}
|
||||
|
||||
RID RasterizerGLES1::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const {
|
||||
|
||||
return RID();
|
||||
}
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
|
||||
|
@ -875,6 +875,9 @@ public:
|
||||
|
||||
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
|
||||
|
||||
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
|
||||
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
virtual RID material_create();
|
||||
|
@ -1539,6 +1539,29 @@ void RasterizerGLES2::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_
|
||||
|
||||
}
|
||||
|
||||
void RasterizerGLES2::shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture) {
|
||||
|
||||
Shader *shader=shader_owner.get(p_shader);
|
||||
ERR_FAIL_COND(!shader);
|
||||
ERR_FAIL_COND(!texture_owner.owns(p_texture));
|
||||
|
||||
if (p_texture.is_valid())
|
||||
shader->default_textures[p_name]=p_texture;
|
||||
else
|
||||
shader->default_textures.erase(p_name);
|
||||
|
||||
}
|
||||
|
||||
RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
|
||||
const Shader *shader=shader_owner.get(p_shader);
|
||||
|
||||
const Map<StringName,RID>::Element *E=shader->default_textures.find(p_name);
|
||||
if (!E)
|
||||
return RID();
|
||||
return E->get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
@ -4991,9 +5014,26 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
|
||||
Texture *t=NULL;
|
||||
if (rid.is_valid()) {
|
||||
|
||||
|
||||
t=texture_owner.get(rid);
|
||||
if (!t)
|
||||
if (!t) {
|
||||
E->get().value=RID(); //nullify, invalid texture
|
||||
rid=RID();
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!rid.is_valid()) {
|
||||
//use from default textures
|
||||
Map<StringName,RID>::Element *F=p_material->shader_cache->default_textures.find(E->key());
|
||||
if (F) {
|
||||
t=texture_owner.get(F->get());
|
||||
if (!t) {
|
||||
p_material->shader_cache->default_textures.erase(E->key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5020,6 +5060,13 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
|
||||
|
||||
}
|
||||
|
||||
for (Map<StringName,RID>::Element *E=p_material->shader_cache->default_textures.front();E;E=E->next()) {
|
||||
if (p_material->shader_params.has(E->key()))
|
||||
continue;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (p_material->shader_cache->has_texscreen && framebuffer.active) {
|
||||
material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
|
||||
material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_TEX,texcoord);
|
||||
|
@ -195,6 +195,7 @@ class RasterizerGLES2 : public Rasterizer {
|
||||
Map<StringName,ShaderLanguage::Uniform> uniforms;
|
||||
StringName first_texture;
|
||||
|
||||
Map<StringName,RID> default_textures;
|
||||
|
||||
SelfList<Shader> dirty_list;
|
||||
|
||||
@ -1255,6 +1256,8 @@ public:
|
||||
|
||||
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
|
||||
|
||||
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
|
||||
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
|
@ -1230,7 +1230,7 @@ LIGHT_SHADER_CODE
|
||||
|
||||
vec3 ambient = const_light_mult*ambient_light*diffuse.rgb;
|
||||
# if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT)
|
||||
ambient*=diffuse_interp.a; //attenuation affects ambient too
|
||||
// ambient*=diffuse_interp.a; //attenuation affects ambient too
|
||||
|
||||
# endif
|
||||
|
||||
|
@ -275,7 +275,7 @@ void AudioStreamMPC::stop() {
|
||||
}
|
||||
bool AudioStreamMPC::is_playing() const {
|
||||
|
||||
return active;
|
||||
return active || (get_total() - get_todo() -1 > 0);
|
||||
}
|
||||
|
||||
void AudioStreamMPC::set_paused(bool p_paused) {
|
||||
|
@ -341,7 +341,11 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
|
||||
# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */
|
||||
# define CVT_PTR(ptr) (ptr)
|
||||
# define CVT_PTR_NOCHECK(ptr) (ptr)
|
||||
# define png_strlen lstrlenA
|
||||
# ifdef WINRT_ENABLED
|
||||
# define png_strlen strlen
|
||||
# else
|
||||
# define png_strlen lstrlenA
|
||||
# endif
|
||||
# define png_memcmp memcmp
|
||||
# define png_memcpy CopyMemory
|
||||
# define png_memset memset
|
||||
|
5
drivers/pulseaudio/SCsub
Normal file
5
drivers/pulseaudio/SCsub
Normal file
@ -0,0 +1,5 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
|
||||
Export('env')
|
194
drivers/pulseaudio/audio_driver_pulseaudio.cpp
Normal file
194
drivers/pulseaudio/audio_driver_pulseaudio.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
/*************************************************************************/
|
||||
/* audio_driver_alsa.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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 "audio_driver_pulseaudio.h"
|
||||
|
||||
#ifdef PULSEAUDIO_ENABLED
|
||||
|
||||
#include <pulse/error.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
Error AudioDriverPulseAudio::init() {
|
||||
|
||||
active = false;
|
||||
thread_exited = false;
|
||||
exit_thread = false;
|
||||
pcm_open = false;
|
||||
samples_in = NULL;
|
||||
samples_out = NULL;
|
||||
|
||||
mix_rate = 44100;
|
||||
output_format = OUTPUT_STEREO;
|
||||
channels = 2;
|
||||
|
||||
pa_sample_spec spec;
|
||||
spec.format = PA_SAMPLE_S16LE;
|
||||
spec.channels = channels;
|
||||
spec.rate = mix_rate;
|
||||
|
||||
int error_code;
|
||||
pulse = pa_simple_new(NULL, // default server
|
||||
"Godot", // application name
|
||||
PA_STREAM_PLAYBACK,
|
||||
NULL, // default device
|
||||
"Sound", // stream description
|
||||
&spec,
|
||||
NULL, // use default channel map
|
||||
NULL, // use default buffering attributes
|
||||
&error_code
|
||||
);
|
||||
|
||||
if (pulse == NULL) {
|
||||
|
||||
fprintf(stderr, "PulseAudio ERR: %s\n", pa_strerror(error_code));\
|
||||
ERR_FAIL_COND_V(pulse == NULL, ERR_CANT_OPEN);
|
||||
}
|
||||
|
||||
int latency = GLOBAL_DEF("audio/output_latency", 25);
|
||||
buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
|
||||
|
||||
samples_in = memnew_arr(int32_t, buffer_size * channels);
|
||||
samples_out = memnew_arr(int16_t, buffer_size * channels);
|
||||
|
||||
mutex = Mutex::create();
|
||||
thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void AudioDriverPulseAudio::thread_func(void* p_udata) {
|
||||
|
||||
AudioDriverPulseAudio* ad = (AudioDriverPulseAudio*)p_udata;
|
||||
|
||||
while (!ad->exit_thread) {
|
||||
|
||||
if (!ad->active) {
|
||||
|
||||
for (unsigned int i=0; i < ad->buffer_size * ad->channels; i++) {
|
||||
|
||||
ad->samples_out[i] = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ad->lock();
|
||||
|
||||
ad->audio_server_process(ad->buffer_size, ad->samples_in);
|
||||
|
||||
ad->unlock();
|
||||
|
||||
for (unsigned int i=0; i < ad->buffer_size * ad->channels;i ++) {
|
||||
|
||||
ad->samples_out[i] = ad->samples_in[i] >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
// pa_simple_write always consumes the entire buffer
|
||||
|
||||
int error_code;
|
||||
int byte_size = ad->buffer_size * sizeof(int16_t) * ad->channels;
|
||||
if (pa_simple_write(ad->pulse, ad->samples_out, byte_size, &error_code) < 0) {
|
||||
|
||||
// can't recover here
|
||||
fprintf(stderr, "PulseAudio failed and can't recover: %s\n", pa_strerror(error_code));
|
||||
ad->active = false;
|
||||
ad->exit_thread = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ad->thread_exited = true;
|
||||
}
|
||||
|
||||
void AudioDriverPulseAudio::start() {
|
||||
|
||||
active = true;
|
||||
}
|
||||
|
||||
int AudioDriverPulseAudio::get_mix_rate() const {
|
||||
|
||||
return mix_rate;
|
||||
}
|
||||
|
||||
AudioDriverSW::OutputFormat AudioDriverPulseAudio::get_output_format() const {
|
||||
|
||||
return output_format;
|
||||
}
|
||||
|
||||
void AudioDriverPulseAudio::lock() {
|
||||
|
||||
if (!thread || !mutex)
|
||||
return;
|
||||
mutex->lock();
|
||||
}
|
||||
|
||||
void AudioDriverPulseAudio::unlock() {
|
||||
|
||||
if (!thread || !mutex)
|
||||
return;
|
||||
mutex->unlock();
|
||||
}
|
||||
|
||||
void AudioDriverPulseAudio::finish() {
|
||||
|
||||
if (!thread)
|
||||
return;
|
||||
|
||||
exit_thread = true;
|
||||
Thread::wait_to_finish(thread);
|
||||
|
||||
if (pulse)
|
||||
pa_simple_free(pulse);
|
||||
|
||||
if (samples_in) {
|
||||
memdelete_arr(samples_in);
|
||||
memdelete_arr(samples_out);
|
||||
};
|
||||
|
||||
memdelete(thread);
|
||||
if (mutex) {
|
||||
memdelete(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
|
||||
thread = NULL;
|
||||
}
|
||||
|
||||
AudioDriverPulseAudio::AudioDriverPulseAudio() {
|
||||
|
||||
mutex = NULL;
|
||||
thread = NULL;
|
||||
pulse = NULL;
|
||||
}
|
||||
|
||||
AudioDriverPulseAudio::~AudioDriverPulseAudio() {
|
||||
|
||||
}
|
||||
|
||||
#endif
|
79
drivers/pulseaudio/audio_driver_pulseaudio.h
Normal file
79
drivers/pulseaudio/audio_driver_pulseaudio.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*************************************************************************/
|
||||
/* audio_driver_pulseaudio.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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 "servers/audio/audio_server_sw.h"
|
||||
|
||||
#ifdef PULSEAUDIO_ENABLED
|
||||
|
||||
#include "core/os/thread.h"
|
||||
#include "core/os/mutex.h"
|
||||
|
||||
#include <pulse/simple.h>
|
||||
|
||||
class AudioDriverPulseAudio : public AudioDriverSW {
|
||||
|
||||
Thread* thread;
|
||||
Mutex* mutex;
|
||||
|
||||
pa_simple* pulse;
|
||||
|
||||
int32_t* samples_in;
|
||||
int16_t* samples_out;
|
||||
|
||||
static void thread_func(void* p_udata);
|
||||
|
||||
unsigned int mix_rate;
|
||||
OutputFormat output_format;
|
||||
|
||||
unsigned int buffer_size;
|
||||
int channels;
|
||||
|
||||
bool active;
|
||||
bool thread_exited;
|
||||
mutable bool exit_thread;
|
||||
bool pcm_open;
|
||||
|
||||
public:
|
||||
|
||||
const char* get_name() const {
|
||||
return "PulseAudio";
|
||||
};
|
||||
|
||||
virtual Error init();
|
||||
virtual void start();
|
||||
virtual int get_mix_rate() const;
|
||||
virtual OutputFormat get_output_format() const;
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
virtual void finish();
|
||||
|
||||
AudioDriverPulseAudio();
|
||||
~AudioDriverPulseAudio();
|
||||
};
|
||||
|
||||
#endif
|
@ -78,6 +78,9 @@ else:
|
||||
if env["platform"] == "android":
|
||||
env_theora.Append(CPPFLAGS=["-D_ANDROID"])
|
||||
|
||||
if env["platform"] == "winrt":
|
||||
env_theora.Append(CPPFLAGS=["-D_WINRT"])
|
||||
|
||||
env_theora.Append(CPPPATH=["#drivers/theoraplayer/include/theoraplayer", "#drivers/theoraplayer/src/YUV", "#drivers/theoraplayer/src/YUV/libyuv/include", "#drivers/theoraplayer/src/Theora", "#drivers/theoraplayer/src/AVFoundation"])
|
||||
|
||||
objs = []
|
||||
|
@ -28,7 +28,7 @@
|
||||
/*************************************************************************/
|
||||
#include "ip_unix.h"
|
||||
|
||||
#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED)
|
||||
#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) && !defined(WINRT_ENABLED)
|
||||
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
|
@ -332,6 +332,12 @@ Error OS_Unix::execute(const String& p_path, const List<String>& p_arguments,boo
|
||||
Error OS_Unix::kill(const ProcessID& p_pid) {
|
||||
|
||||
int ret = ::kill(p_pid,SIGKILL);
|
||||
if (!ret) {
|
||||
//avoid zombie process
|
||||
int st;
|
||||
::waitpid(p_pid,&st,0);
|
||||
|
||||
}
|
||||
return ret?ERR_INVALID_PARAMETER:OK;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
|
||||
|
||||
/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
|
||||
* 64 bit compiler */
|
||||
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE)
|
||||
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE) && !defined(WINDOWSPHONE_ENABLED)
|
||||
# define VORBIS_FPU_CONTROL
|
||||
|
||||
typedef ogg_int16_t vorbis_fpu_control;
|
||||
|
@ -106,6 +106,7 @@ String DirAccessWindows::get_next() {
|
||||
return name;
|
||||
} else {
|
||||
|
||||
#ifndef WINRT_ENABLED
|
||||
_cisdir=(p->fu.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
String name=p->f.cFileName;
|
||||
@ -117,7 +118,8 @@ String DirAccessWindows::get_next() {
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,6 +360,7 @@ bool DirAccessWindows::dir_exists(String p_dir) {
|
||||
return (fileAttr&FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
} else {
|
||||
#ifndef WINRT_ENABLED
|
||||
DWORD fileAttr;
|
||||
|
||||
fileAttr = GetFileAttributesExA(p_dir.ascii().get_data(), GetFileExInfoStandard, &fileInfo);
|
||||
@ -366,8 +369,8 @@ bool DirAccessWindows::dir_exists(String p_dir) {
|
||||
|
||||
return (fileAttr&FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@ void FileAccessWindows::check_errors() const {
|
||||
Error FileAccessWindows::_open(const String& p_filename, int p_mode_flags) {
|
||||
|
||||
String filename=fix_path(p_filename);
|
||||
|
||||
if (f)
|
||||
close();
|
||||
|
||||
|
@ -147,6 +147,7 @@ void Main::print_help(const char* p_binary) {
|
||||
OS::get_singleton()->print(", ");
|
||||
OS::get_singleton()->print("%s",OS::get_singleton()->get_audio_driver_name(i));
|
||||
}
|
||||
OS::get_singleton()->print(")\n");
|
||||
OS::get_singleton()->print("\t-rthread <mode>\t : Render Thread Mode ('unsafe', 'safe', 'separate).");
|
||||
OS::get_singleton()->print(")\n");
|
||||
OS::get_singleton()->print("\t-s,-script [script] : Run a script.\n");
|
||||
|
30
makefile
30
makefile
@ -1,30 +0,0 @@
|
||||
#*************************************************************************/
|
||||
#* This file is part of: */
|
||||
#* GODOT ENGINE */
|
||||
#* http://www.godotengine.org */
|
||||
#*************************************************************************/
|
||||
# Simple makefile to give support for external C/C++ IDEs */
|
||||
#*************************************************************************/
|
||||
|
||||
# Default build
|
||||
all: debug
|
||||
|
||||
# Release Build
|
||||
release:
|
||||
scons target="release" bin/godot
|
||||
|
||||
# Profile Build
|
||||
profile:
|
||||
scons target="profile" bin/godot
|
||||
|
||||
# Debug Build
|
||||
debug:
|
||||
# Debug information (code size gets severely affected):
|
||||
# g: Default (same as g2)
|
||||
# g0: no debug info
|
||||
# g1: minimal info
|
||||
# g3: maximal info
|
||||
scons target="debug" CCFLAGS="-g" bin/godot
|
||||
|
||||
clean:
|
||||
scons -c bin/godot
|
@ -1168,6 +1168,7 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *
|
||||
codegen.current_line=0;
|
||||
codegen.call_max=0;
|
||||
codegen.debug_stack=ScriptDebugger::get_singleton()!=NULL;
|
||||
Vector<StringName> argnames;
|
||||
|
||||
int stack_level=0;
|
||||
|
||||
@ -1175,6 +1176,9 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *
|
||||
for(int i=0;i<p_func->arguments.size();i++) {
|
||||
int idx = i;
|
||||
codegen.add_stack_identifier(p_func->arguments[i],i);
|
||||
#ifdef TOOLS_ENABLED
|
||||
argnames.push_back(p_func->arguments[i]);
|
||||
#endif
|
||||
}
|
||||
stack_level=p_func->arguments.size();
|
||||
}
|
||||
@ -1249,6 +1253,9 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *
|
||||
if (p_func)
|
||||
gdfunc->_static=p_func->_static;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
gdfunc->arg_names=argnames;
|
||||
#endif
|
||||
//constants
|
||||
if (codegen.constant_map.size()) {
|
||||
gdfunc->_constant_count=codegen.constant_map.size();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,19 +30,6 @@
|
||||
#include "print_string.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "os/file_access.h"
|
||||
/* TODO:
|
||||
|
||||
*Property reduce constant expressions
|
||||
*Implement missing operators in variant?
|
||||
*constructor
|
||||
*/
|
||||
|
||||
/*
|
||||
todo:
|
||||
fix post ++,--
|
||||
make sure ++,-- don't work on constant expressions
|
||||
seems passing parent node as param is not needed
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
T* GDParser::alloc_node() {
|
||||
@ -116,14 +103,20 @@ bool GDParser::_enter_indent_block(BlockNode* p_block) {
|
||||
}
|
||||
}
|
||||
|
||||
bool GDParser::_parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_static) {
|
||||
bool GDParser::_parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_static,bool p_can_codecomplete) {
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
tokenizer->advance();
|
||||
} else {
|
||||
|
||||
int argidx=0;
|
||||
|
||||
while(true) {
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
_make_completable_call(argidx);
|
||||
completion_node=p_parent;
|
||||
}
|
||||
|
||||
Node*arg = _parse_expression(p_parent,p_static);
|
||||
if (!arg)
|
||||
@ -144,6 +137,7 @@ bool GDParser::_parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_stat
|
||||
}
|
||||
|
||||
tokenizer->advance();
|
||||
argidx++;
|
||||
} else {
|
||||
// something is broken
|
||||
_set_error("Expected ',' or ')'");
|
||||
@ -158,6 +152,48 @@ bool GDParser::_parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_stat
|
||||
}
|
||||
|
||||
|
||||
void GDParser::_make_completable_call(int p_arg) {
|
||||
|
||||
completion_cursor=StringName();
|
||||
completion_type=COMPLETION_CALL_ARGUMENTS;
|
||||
completion_class=current_class;
|
||||
completion_function=current_function;
|
||||
completion_line=tokenizer->get_token_line();
|
||||
completion_argument=p_arg;
|
||||
completion_block=current_block;
|
||||
tokenizer->advance();
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GDParser::_get_completable_identifier(CompletionType p_type,StringName& identifier) {
|
||||
|
||||
identifier=StringName();
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
|
||||
identifier=tokenizer->get_token_identifier();
|
||||
tokenizer->advance();
|
||||
}
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
|
||||
completion_cursor=identifier;
|
||||
completion_type=p_type;
|
||||
completion_class=current_class;
|
||||
completion_function=current_function;
|
||||
completion_line=tokenizer->get_token_line();
|
||||
completion_block=current_block;
|
||||
tokenizer->advance();
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
|
||||
identifier=identifier.operator String() + tokenizer->get_token_identifier().operator String();
|
||||
tokenizer->advance();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_allow_assign) {
|
||||
|
||||
@ -199,6 +235,9 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
|
||||
tokenizer->advance();
|
||||
expr=subexpr;
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
tokenizer->advance();
|
||||
continue; //no point in cursor in the middle of expression
|
||||
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_CONSTANT) {
|
||||
|
||||
@ -327,12 +366,19 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
|
||||
Variant::Type bi_type = tokenizer->get_token_type();
|
||||
tokenizer->advance(2);
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
|
||||
|
||||
StringName identifier;
|
||||
|
||||
if (_get_completable_identifier(COMPLETION_BUILT_IN_TYPE_CONSTANT,identifier)) {
|
||||
|
||||
completion_built_in_constant=bi_type;
|
||||
}
|
||||
|
||||
if (identifier==StringName()) {
|
||||
|
||||
_set_error("Built-in type constant expected after '.'");
|
||||
return NULL;
|
||||
}
|
||||
StringName identifier = tokenizer->get_token_identifier();
|
||||
if (!Variant::has_numeric_constant(bi_type,identifier)) {
|
||||
|
||||
_set_error("Static constant '"+identifier.operator String()+"' not present in built-in type "+Variant::get_type_name(bi_type)+".");
|
||||
@ -342,7 +388,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
ConstantNode *cn = alloc_node<ConstantNode>();
|
||||
cn->value=Variant::get_numeric_constant_value(bi_type,identifier);
|
||||
expr=cn;
|
||||
tokenizer->advance();
|
||||
|
||||
|
||||
} else if (tokenizer->get_token(1)==GDTokenizer::TK_PARENTHESIS_OPEN && (tokenizer->get_token()==GDTokenizer::TK_BUILT_IN_TYPE || tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER || tokenizer->get_token()==GDTokenizer::TK_BUILT_IN_FUNC)) {
|
||||
//function or constructor
|
||||
@ -355,23 +401,35 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
TypeNode *tn = alloc_node<TypeNode>();
|
||||
tn->vtype=tokenizer->get_token_type();
|
||||
op->arguments.push_back(tn);
|
||||
tokenizer->advance(2);
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_BUILT_IN_FUNC) {
|
||||
|
||||
BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>();
|
||||
bn->function=tokenizer->get_token_built_in_func();
|
||||
op->arguments.push_back(bn);
|
||||
tokenizer->advance(2);
|
||||
} else {
|
||||
|
||||
SelfNode *self = alloc_node<SelfNode>();
|
||||
op->arguments.push_back(self);
|
||||
|
||||
StringName identifier;
|
||||
if (_get_completable_identifier(COMPLETION_FUNCTION,identifier)) {
|
||||
|
||||
}
|
||||
|
||||
IdentifierNode* id = alloc_node<IdentifierNode>();
|
||||
id->name=tokenizer->get_token_identifier();
|
||||
id->name=identifier;
|
||||
op->arguments.push_back(id);
|
||||
tokenizer->advance(1);
|
||||
}
|
||||
|
||||
tokenizer->advance(2);
|
||||
if (!_parse_arguments(op,op->arguments,p_static))
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
_make_completable_call(0);
|
||||
completion_node=op;
|
||||
|
||||
}
|
||||
if (!_parse_arguments(op,op->arguments,p_static,true))
|
||||
return NULL;
|
||||
|
||||
expr=op;
|
||||
@ -380,25 +438,27 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
//identifier (reference)
|
||||
|
||||
const ClassNode* cln = static_cast<const ClassNode*>(get_parse_tree());
|
||||
bool bfn = false;
|
||||
StringName idn( tokenizer->get_token_identifier() );
|
||||
bool bfn = false;
|
||||
StringName identifier;
|
||||
if (_get_completable_identifier(COMPLETION_IDENTIFIER,identifier)) {
|
||||
|
||||
for( int i=0; i<cln->constant_expressions.size(); ++i ) {
|
||||
}
|
||||
|
||||
if( cln->constant_expressions[i].identifier == idn ) {
|
||||
tokenizer->advance();
|
||||
expr = cln->constant_expressions[i].expression;
|
||||
bfn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( int i=0; i<cln->constant_expressions.size(); ++i ) {
|
||||
|
||||
if( !bfn ) {
|
||||
IdentifierNode *id = alloc_node<IdentifierNode>();
|
||||
id->name = idn;
|
||||
tokenizer->advance();
|
||||
expr = id;
|
||||
}
|
||||
if( cln->constant_expressions[i].identifier == identifier ) {
|
||||
|
||||
expr = cln->constant_expressions[i].expression;
|
||||
bfn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bfn ) {
|
||||
IdentifierNode *id = alloc_node<IdentifierNode>();
|
||||
id->name = identifier;
|
||||
expr = id;
|
||||
}
|
||||
|
||||
} else if (/*tokenizer->get_token()==GDTokenizer::TK_OP_ADD ||*/ tokenizer->get_token()==GDTokenizer::TK_OP_SUB || tokenizer->get_token()==GDTokenizer::TK_OP_NOT || tokenizer->get_token()==GDTokenizer::TK_OP_BIT_INVERT) {
|
||||
|
||||
@ -600,7 +660,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
|
||||
expr=dict;
|
||||
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_PERIOD && tokenizer->get_token(1)==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token(2)==GDTokenizer::TK_PARENTHESIS_OPEN) {
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_PERIOD && (tokenizer->get_token(1)==GDTokenizer::TK_IDENTIFIER || tokenizer->get_token(1)==GDTokenizer::TK_CURSOR) && tokenizer->get_token(2)==GDTokenizer::TK_PARENTHESIS_OPEN) {
|
||||
// parent call
|
||||
|
||||
tokenizer->advance(); //goto identifier
|
||||
@ -611,12 +671,16 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
/*SelfNode *self = alloc_node<SelfNode>();
|
||||
op->arguments.push_back(self);
|
||||
forbidden for now */
|
||||
StringName identifier;
|
||||
if (_get_completable_identifier(COMPLETION_PARENT_FUNCTION,identifier)) {
|
||||
//indexing stuff
|
||||
}
|
||||
|
||||
IdentifierNode* id = alloc_node<IdentifierNode>();
|
||||
id->name=tokenizer->get_token_identifier();
|
||||
IdentifierNode *id = alloc_node<IdentifierNode>();
|
||||
id->name=identifier;
|
||||
op->arguments.push_back(id);
|
||||
|
||||
tokenizer->advance(2);
|
||||
tokenizer->advance(1);
|
||||
if (!_parse_arguments(op,op->arguments,p_static))
|
||||
return NULL;
|
||||
|
||||
@ -651,7 +715,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
|
||||
//indexing using "."
|
||||
|
||||
if (tokenizer->get_token(1)!=GDTokenizer::TK_IDENTIFIER && tokenizer->get_token(1)!=GDTokenizer::TK_BUILT_IN_FUNC ) {
|
||||
if (tokenizer->get_token(1)!=GDTokenizer::TK_CURSOR && tokenizer->get_token(1)!=GDTokenizer::TK_IDENTIFIER && tokenizer->get_token(1)!=GDTokenizer::TK_BUILT_IN_FUNC ) {
|
||||
_set_error("Expected identifier as member");
|
||||
return NULL;
|
||||
} else if (tokenizer->get_token(2)==GDTokenizer::TK_PARENTHESIS_OPEN) {
|
||||
@ -659,37 +723,67 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
OperatorNode * op = alloc_node<OperatorNode>();
|
||||
op->op=OperatorNode::OP_CALL;
|
||||
|
||||
tokenizer->advance();
|
||||
|
||||
IdentifierNode * id = alloc_node<IdentifierNode>();
|
||||
if (tokenizer->get_token(1)==GDTokenizer::TK_BUILT_IN_FUNC ) {
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_BUILT_IN_FUNC ) {
|
||||
//small hack so built in funcs don't obfuscate methods
|
||||
|
||||
id->name=GDFunctions::get_func_name(tokenizer->get_token_built_in_func(1));
|
||||
id->name=GDFunctions::get_func_name(tokenizer->get_token_built_in_func());
|
||||
tokenizer->advance();
|
||||
|
||||
} else {
|
||||
id->name=tokenizer->get_token_identifier(1);
|
||||
StringName identifier;
|
||||
if (_get_completable_identifier(COMPLETION_METHOD,identifier)) {
|
||||
completion_node=op;
|
||||
//indexing stuff
|
||||
}
|
||||
|
||||
id->name=identifier;
|
||||
}
|
||||
|
||||
op->arguments.push_back(expr); // call what
|
||||
op->arguments.push_back(id); // call func
|
||||
//get arguments
|
||||
tokenizer->advance(3);
|
||||
if (!_parse_arguments(op,op->arguments,p_static))
|
||||
tokenizer->advance(1);
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
_make_completable_call(0);
|
||||
completion_node=op;
|
||||
|
||||
}
|
||||
if (!_parse_arguments(op,op->arguments,p_static,true))
|
||||
return NULL;
|
||||
expr=op;
|
||||
|
||||
} else {
|
||||
//simple indexing!
|
||||
|
||||
|
||||
OperatorNode * op = alloc_node<OperatorNode>();
|
||||
op->op=OperatorNode::OP_INDEX_NAMED;
|
||||
tokenizer->advance();
|
||||
|
||||
|
||||
StringName identifier;
|
||||
if (_get_completable_identifier(COMPLETION_INDEX,identifier)) {
|
||||
|
||||
if (identifier==StringName()) {
|
||||
identifier="@temp"; //so it parses allright
|
||||
}
|
||||
completion_node=op;
|
||||
|
||||
//indexing stuff
|
||||
}
|
||||
|
||||
IdentifierNode * id = alloc_node<IdentifierNode>();
|
||||
id->name=tokenizer->get_token_identifier(1);
|
||||
id->name=identifier;
|
||||
|
||||
op->arguments.push_back(expr);
|
||||
op->arguments.push_back(id);
|
||||
|
||||
expr=op;
|
||||
|
||||
tokenizer->advance(2);
|
||||
|
||||
}
|
||||
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_BRACKET_OPEN) {
|
||||
@ -1442,6 +1536,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
cf_if->arguments.push_back(condition);
|
||||
|
||||
cf_if->body = alloc_node<BlockNode>();
|
||||
cf_if->body->parent_block=p_block;
|
||||
p_block->sub_blocks.push_back(cf_if->body);
|
||||
|
||||
if (!_enter_indent_block(cf_if->body)) {
|
||||
@ -1449,7 +1544,10 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
return;
|
||||
}
|
||||
|
||||
current_block=cf_if->body;
|
||||
_parse_block(cf_if->body,p_static);
|
||||
current_block=p_block;
|
||||
|
||||
if (error_set)
|
||||
return;
|
||||
p_block->statements.push_back(cf_if);
|
||||
@ -1476,6 +1574,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
tokenizer->advance();
|
||||
|
||||
cf_if->body_else=alloc_node<BlockNode>();
|
||||
cf_if->body_else->parent_block=p_block;
|
||||
p_block->sub_blocks.push_back(cf_if->body_else);
|
||||
|
||||
ControlFlowNode *cf_else = alloc_node<ControlFlowNode>();
|
||||
@ -1491,6 +1590,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
cf_if->body_else->statements.push_back(cf_else);
|
||||
cf_if=cf_else;
|
||||
cf_if->body=alloc_node<BlockNode>();
|
||||
cf_if->body->parent_block=p_block;
|
||||
p_block->sub_blocks.push_back(cf_if->body);
|
||||
|
||||
|
||||
@ -1499,7 +1599,9 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
return;
|
||||
}
|
||||
|
||||
current_block=cf_else->body;
|
||||
_parse_block(cf_else->body,p_static);
|
||||
current_block=p_block;
|
||||
if (error_set)
|
||||
return;
|
||||
|
||||
@ -1515,13 +1617,16 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
|
||||
tokenizer->advance();
|
||||
cf_if->body_else=alloc_node<BlockNode>();
|
||||
cf_if->body_else->parent_block=p_block;
|
||||
p_block->sub_blocks.push_back(cf_if->body_else);
|
||||
|
||||
if (!_enter_indent_block(cf_if->body_else)) {
|
||||
p_block->end_line=tokenizer->get_token_line();
|
||||
return;
|
||||
}
|
||||
current_block=cf_if->body_else;
|
||||
_parse_block(cf_if->body_else,p_static);
|
||||
current_block=p_block;
|
||||
if (error_set)
|
||||
return;
|
||||
|
||||
@ -1548,6 +1653,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
cf_while->arguments.push_back(condition);
|
||||
|
||||
cf_while->body = alloc_node<BlockNode>();
|
||||
cf_while->body->parent_block=p_block;
|
||||
p_block->sub_blocks.push_back(cf_while->body);
|
||||
|
||||
if (!_enter_indent_block(cf_while->body)) {
|
||||
@ -1555,7 +1661,9 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
return;
|
||||
}
|
||||
|
||||
current_block=cf_while->body;
|
||||
_parse_block(cf_while->body,p_static);
|
||||
current_block=p_block;
|
||||
if (error_set)
|
||||
return;
|
||||
p_block->statements.push_back(cf_while);
|
||||
@ -1592,6 +1700,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
cf_for->arguments.push_back(container);
|
||||
|
||||
cf_for->body = alloc_node<BlockNode>();
|
||||
cf_for->body->parent_block=p_block;
|
||||
p_block->sub_blocks.push_back(cf_for->body);
|
||||
|
||||
if (!_enter_indent_block(cf_for->body)) {
|
||||
@ -1599,7 +1708,10 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
return;
|
||||
}
|
||||
|
||||
current_block=cf_for->body;
|
||||
_parse_block(cf_for->body,p_static);
|
||||
current_block=p_block;
|
||||
|
||||
if (error_set)
|
||||
return;
|
||||
p_block->statements.push_back(cf_for);
|
||||
@ -1865,7 +1977,9 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
|
||||
ClassNode *newclass = alloc_node<ClassNode>();
|
||||
newclass->initializer = alloc_node<BlockNode>();
|
||||
newclass->initializer->parent_class=newclass;
|
||||
newclass->name=name;
|
||||
newclass->owner=p_class;
|
||||
|
||||
p_class->subclasses.push_back(newclass);
|
||||
|
||||
@ -1882,7 +1996,9 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
_set_error("Indented block expected.");
|
||||
return;
|
||||
}
|
||||
current_class=newclass;
|
||||
_parse_class(newclass);
|
||||
current_class=p_class;
|
||||
|
||||
} break;
|
||||
/* this is for functions....
|
||||
@ -2020,6 +2136,7 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
tokenizer->advance();
|
||||
|
||||
BlockNode *block = alloc_node<BlockNode>();
|
||||
block->parent_class=p_class;
|
||||
|
||||
if (name=="_init") {
|
||||
|
||||
@ -2095,8 +2212,12 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
p_class->functions.push_back(function);
|
||||
|
||||
|
||||
_parse_block(block,_static);
|
||||
current_function=function;
|
||||
function->body=block;
|
||||
current_block=block;
|
||||
_parse_block(block,_static);
|
||||
current_block=NULL;
|
||||
|
||||
//arguments
|
||||
} break;
|
||||
case GDTokenizer::TK_PR_EXPORT: {
|
||||
@ -2401,7 +2522,9 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
}
|
||||
|
||||
member.identifier=tokenizer->get_token_identifier();
|
||||
member.expression=NULL;
|
||||
member._export.name=member.identifier;
|
||||
member.line=tokenizer->get_token_line();
|
||||
tokenizer->advance();
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_OP_ASSIGN) {
|
||||
@ -2417,6 +2540,8 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
if (!subexpr)
|
||||
return;
|
||||
|
||||
member.expression=subexpr;
|
||||
|
||||
if (autoexport) {
|
||||
if (subexpr->type==Node::TYPE_ARRAY) {
|
||||
|
||||
@ -2608,6 +2733,8 @@ Error GDParser::_parse(const String& p_base_path) {
|
||||
//assume class
|
||||
ClassNode *main_class = alloc_node<ClassNode>();
|
||||
main_class->initializer = alloc_node<BlockNode>();
|
||||
main_class->initializer->parent_class=main_class;
|
||||
current_class=main_class;
|
||||
|
||||
_parse_class(main_class);
|
||||
|
||||
@ -2625,6 +2752,15 @@ Error GDParser::_parse(const String& p_base_path) {
|
||||
|
||||
Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path, const String &p_self_path) {
|
||||
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
completion_class=NULL;
|
||||
completion_function=NULL;
|
||||
completion_block=NULL;
|
||||
current_block=NULL;
|
||||
current_class=NULL;
|
||||
current_function=NULL;
|
||||
|
||||
self_path=p_self_path;
|
||||
GDTokenizerBuffer *tb = memnew( GDTokenizerBuffer );
|
||||
tb->set_code_buffer(p_bytecode);
|
||||
@ -2638,6 +2774,16 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p
|
||||
|
||||
Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path) {
|
||||
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
completion_class=NULL;
|
||||
completion_function=NULL;
|
||||
completion_block=NULL;
|
||||
current_block=NULL;
|
||||
current_class=NULL;
|
||||
|
||||
current_function=NULL;
|
||||
|
||||
self_path=p_self_path;
|
||||
GDTokenizerText *tt = memnew( GDTokenizerText );
|
||||
tt->set_code(p_code);
|
||||
@ -2667,6 +2813,16 @@ void GDParser::clear() {
|
||||
head=NULL;
|
||||
list=NULL;
|
||||
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
completion_class=NULL;
|
||||
completion_function=NULL;
|
||||
completion_block=NULL;
|
||||
current_block=NULL;
|
||||
current_class=NULL;
|
||||
|
||||
current_function=NULL;
|
||||
|
||||
validating=false;
|
||||
error_set=false;
|
||||
tab_level.clear();
|
||||
@ -2680,6 +2836,52 @@ void GDParser::clear() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
GDParser::CompletionType GDParser::get_completion_type() {
|
||||
|
||||
return completion_type;
|
||||
}
|
||||
|
||||
StringName GDParser::get_completion_cursor() {
|
||||
|
||||
return completion_cursor;
|
||||
}
|
||||
|
||||
int GDParser::get_completion_line() {
|
||||
|
||||
return completion_line;
|
||||
}
|
||||
|
||||
Variant::Type GDParser::get_completion_built_in_constant(){
|
||||
|
||||
return completion_built_in_constant;
|
||||
}
|
||||
|
||||
GDParser::Node *GDParser::get_completion_node(){
|
||||
|
||||
return completion_node;
|
||||
}
|
||||
|
||||
GDParser::BlockNode *GDParser::get_completion_block() {
|
||||
|
||||
return completion_block;
|
||||
}
|
||||
|
||||
GDParser::ClassNode *GDParser::get_completion_class(){
|
||||
|
||||
return completion_class;
|
||||
}
|
||||
|
||||
GDParser::FunctionNode *GDParser::get_completion_function(){
|
||||
|
||||
return completion_function;
|
||||
}
|
||||
|
||||
int GDParser::get_completion_argument_index() {
|
||||
|
||||
return completion_argument;
|
||||
}
|
||||
|
||||
GDParser::GDParser() {
|
||||
|
||||
head=NULL;
|
||||
|
@ -84,6 +84,8 @@ public:
|
||||
StringName identifier;
|
||||
StringName setter;
|
||||
StringName getter;
|
||||
int line;
|
||||
Node *expression;
|
||||
};
|
||||
struct Constant {
|
||||
StringName identifier;
|
||||
@ -96,10 +98,11 @@ public:
|
||||
Vector<FunctionNode*> functions;
|
||||
Vector<FunctionNode*> static_functions;
|
||||
BlockNode *initializer;
|
||||
ClassNode *owner;
|
||||
//Vector<Node*> initializers;
|
||||
int end_line;
|
||||
|
||||
ClassNode() { tool=false; type=TYPE_CLASS; extends_used=false; end_line=-1;}
|
||||
ClassNode() { tool=false; type=TYPE_CLASS; extends_used=false; end_line=-1; owner=NULL;}
|
||||
};
|
||||
|
||||
|
||||
@ -118,6 +121,8 @@ public:
|
||||
|
||||
struct BlockNode : public Node {
|
||||
|
||||
ClassNode *parent_class;
|
||||
BlockNode *parent_block;
|
||||
Map<StringName,int> locals;
|
||||
List<Node*> statements;
|
||||
Vector<StringName> variables;
|
||||
@ -126,7 +131,7 @@ public:
|
||||
//the following is useful for code completion
|
||||
List<BlockNode*> sub_blocks;
|
||||
int end_line;
|
||||
BlockNode() { type=TYPE_BLOCK; end_line=-1;}
|
||||
BlockNode() { type=TYPE_BLOCK; end_line=-1; parent_block=NULL; parent_class=NULL; }
|
||||
};
|
||||
|
||||
struct TypeNode : public Node {
|
||||
@ -349,6 +354,18 @@ public:
|
||||
};
|
||||
*/
|
||||
|
||||
enum CompletionType {
|
||||
COMPLETION_NONE,
|
||||
COMPLETION_BUILT_IN_TYPE_CONSTANT,
|
||||
COMPLETION_FUNCTION,
|
||||
COMPLETION_IDENTIFIER,
|
||||
COMPLETION_PARENT_FUNCTION,
|
||||
COMPLETION_METHOD,
|
||||
COMPLETION_CALL_ARGUMENTS,
|
||||
COMPLETION_INDEX,
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -375,12 +392,31 @@ private:
|
||||
String base_path;
|
||||
String self_path;
|
||||
|
||||
|
||||
ClassNode *current_class;
|
||||
FunctionNode *current_function;
|
||||
BlockNode *current_block;
|
||||
|
||||
bool _get_completable_identifier(CompletionType p_type,StringName& identifier);
|
||||
void _make_completable_call(int p_arg);
|
||||
|
||||
CompletionType completion_type;
|
||||
StringName completion_cursor;
|
||||
bool completion_static;
|
||||
Variant::Type completion_built_in_constant;
|
||||
Node *completion_node;
|
||||
ClassNode *completion_class;
|
||||
FunctionNode *completion_function;
|
||||
BlockNode *completion_block;
|
||||
int completion_line;
|
||||
int completion_argument;
|
||||
|
||||
PropertyInfo current_export;
|
||||
|
||||
void _set_error(const String& p_error, int p_line=-1, int p_column=-1);
|
||||
|
||||
|
||||
bool _parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_static);
|
||||
bool _parse_arguments(Node* p_parent, Vector<Node*>& p_args, bool p_static, bool p_can_codecomplete=false);
|
||||
bool _enter_indent_block(BlockNode *p_block=NULL);
|
||||
bool _parse_newline();
|
||||
Node* _parse_expression(Node *p_parent,bool p_static,bool p_allow_assign=false);
|
||||
@ -404,6 +440,19 @@ public:
|
||||
|
||||
const Node *get_parse_tree() const;
|
||||
|
||||
//completion info
|
||||
|
||||
CompletionType get_completion_type();
|
||||
StringName get_completion_cursor();
|
||||
int get_completion_line();
|
||||
Variant::Type get_completion_built_in_constant();
|
||||
Node *get_completion_node();
|
||||
ClassNode *get_completion_class();
|
||||
BlockNode *get_completion_block();
|
||||
FunctionNode *get_completion_function();
|
||||
int get_completion_argument_index();
|
||||
|
||||
|
||||
void clear();
|
||||
GDParser();
|
||||
~GDParser();
|
||||
|
@ -1440,8 +1440,8 @@ GDInstance* GDScript::_create_instance(const Variant** p_args,int p_argcount,Obj
|
||||
|
||||
if (err.error!=Variant::CallError::CALL_OK) {
|
||||
instance->script=Ref<GDScript>();
|
||||
instance->owner->set_script_instance(NULL);
|
||||
instances.erase(p_owner);
|
||||
memdelete(instance);
|
||||
ERR_FAIL_COND_V(err.error!=Variant::CallError::CALL_OK, NULL); //error consrtucting
|
||||
}
|
||||
|
||||
@ -1756,6 +1756,7 @@ bool GDScript::_update_exports() {
|
||||
return changed;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void GDScript::update_exports() {
|
||||
|
@ -129,6 +129,10 @@ friend class GDCompiler;
|
||||
const char*_func_cname;
|
||||
#endif
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Vector<StringName> arg_names;
|
||||
#endif
|
||||
|
||||
List<StackDebug> stack_debug;
|
||||
|
||||
_FORCE_INLINE_ Variant *_get_variant(int p_address,GDInstance *p_instance,GDScript *p_script,Variant &self,Variant *p_stack,String& r_error) const;
|
||||
@ -169,6 +173,19 @@ public:
|
||||
_FORCE_INLINE_ bool is_empty() const { return _code_size==0; }
|
||||
|
||||
int get_argument_count() const { return _argument_count; }
|
||||
StringName get_argument_name(int p_idx) const {
|
||||
#ifdef TOOLS_ENABLED
|
||||
ERR_FAIL_INDEX_V(p_idx,arg_names.size(),StringName());
|
||||
return arg_names[p_idx];
|
||||
#endif
|
||||
return StringName();
|
||||
|
||||
}
|
||||
Variant get_default_argument(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx,default_arguments.size(),Variant());
|
||||
return default_arguments[p_idx];
|
||||
}
|
||||
|
||||
Variant call(GDInstance *p_instance,const Variant **p_args, int p_argcount,Variant::CallError& r_err,CallState *p_state=NULL);
|
||||
|
||||
GDFunction();
|
||||
@ -293,6 +310,7 @@ protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
bool is_valid() const { return valid; }
|
||||
|
||||
const Map<StringName,Ref<GDScript> >& get_subclasses() const { return subclasses; }
|
||||
const Map<StringName,Variant >& get_constants() const { return constants; }
|
||||
@ -488,7 +506,7 @@ public:
|
||||
virtual bool has_named_classes() const;
|
||||
virtual int find_function(const String& p_function,const String& p_code) const;
|
||||
virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const;
|
||||
virtual Error complete_keyword(const String& p_code, int p_line, const String& p_base_path,const String& p_keyword, List<String>* r_options);
|
||||
virtual Error complete_code(const String& p_code, const String& p_base_path, Object*p_owner,List<String>* r_options,String& r_call_hint);
|
||||
virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const;
|
||||
|
||||
/* DEBUGGER FUNCTIONS */
|
||||
|
@ -110,7 +110,8 @@ const char* GDTokenizer::token_names[TK_MAX]={
|
||||
"':'",
|
||||
"'\\n'",
|
||||
"Error",
|
||||
"EOF"};
|
||||
"EOF",
|
||||
"Cursor"};
|
||||
|
||||
const char *GDTokenizer::get_token_name(Token p_token) {
|
||||
|
||||
@ -648,6 +649,9 @@ void GDTokenizerText::_advance() {
|
||||
}
|
||||
|
||||
} break;
|
||||
case 0xFFFF: {
|
||||
_make_token(TK_CURSOR);
|
||||
} break;
|
||||
default: {
|
||||
|
||||
if (_is_number(GETCHAR(0)) || (GETCHAR(0)=='.' && _is_number(GETCHAR(1)))) {
|
||||
|
@ -118,6 +118,7 @@ public:
|
||||
TK_NEWLINE,
|
||||
TK_ERROR,
|
||||
TK_EOF,
|
||||
TK_CURSOR, //used for code completion
|
||||
TK_MAX
|
||||
};
|
||||
|
||||
|
@ -438,8 +438,26 @@ public class GodotIO {
|
||||
|
||||
try {
|
||||
Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri);
|
||||
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(p_uri));
|
||||
activity.startActivity(myIntent);
|
||||
String path = p_uri;
|
||||
String type="";
|
||||
if (path.startsWith("/")) {
|
||||
//absolute path to filesystem, prepend file://
|
||||
path="file://"+path;
|
||||
if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) {
|
||||
|
||||
type="image/*";
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
if (!type.equals("")) {
|
||||
intent.setDataAndType(Uri.parse(path), type);
|
||||
} else {
|
||||
intent.setData(Uri.parse(path));
|
||||
}
|
||||
|
||||
activity.startActivity(intent);
|
||||
return 0;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
|
||||
|
@ -1398,6 +1398,7 @@ void OS_Windows::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
OS::VideoMode OS_Windows::get_video_mode(int p_screen) const {
|
||||
|
||||
return video_mode;
|
||||
|
@ -8,4 +8,4 @@ files = [
|
||||
'os_winrt.cpp',
|
||||
]
|
||||
|
||||
env.Program('#bin/godot_rt', files)
|
||||
env.Program('#bin/godot', files)
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "app.h"
|
||||
|
||||
#include "main/main.h"
|
||||
#include "core/os/dir_access.h"
|
||||
#include "core/os/file_access.h"
|
||||
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
@ -70,8 +72,9 @@ void App::Initialize(CoreApplicationView^ applicationView)
|
||||
}
|
||||
|
||||
// Called when the CoreWindow object is created (or re-created).
|
||||
void App::SetWindow(CoreWindow^ window)
|
||||
void App::SetWindow(CoreWindow^ p_window)
|
||||
{
|
||||
window = p_window;
|
||||
window->VisibilityChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
|
||||
|
||||
@ -89,23 +92,230 @@ void App::SetWindow(CoreWindow^ window)
|
||||
pointerVisualizationSettings->IsBarrelButtonFeedbackEnabled = false;
|
||||
#endif
|
||||
|
||||
// The CoreWindow has been created, so EGL can be initialized.
|
||||
|
||||
window->PointerPressed +=
|
||||
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerPressed);
|
||||
|
||||
window->PointerMoved +=
|
||||
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerMoved);
|
||||
|
||||
window->PointerReleased +=
|
||||
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerReleased);
|
||||
|
||||
//window->PointerWheelChanged +=
|
||||
// ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerWheelChanged);
|
||||
|
||||
|
||||
|
||||
char* args[] = {"-path", "game", NULL};
|
||||
Main::setup("winrt", 2, args, false);
|
||||
|
||||
// The CoreWindow has been created, so EGL can be initialized.
|
||||
ContextEGL* context = memnew(ContextEGL(window));
|
||||
os->set_gl_context(context);
|
||||
UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height));
|
||||
UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height));
|
||||
|
||||
Main::setup2();
|
||||
}
|
||||
|
||||
static int _get_button(Windows::UI::Input::PointerPoint ^pt) {
|
||||
|
||||
using namespace Windows::UI::Input;
|
||||
|
||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
return BUTTON_LEFT;
|
||||
#else
|
||||
switch (pt->Properties->PointerUpdateKind)
|
||||
{
|
||||
case PointerUpdateKind::LeftButtonPressed:
|
||||
case PointerUpdateKind::LeftButtonReleased:
|
||||
return BUTTON_LEFT;
|
||||
|
||||
case PointerUpdateKind::RightButtonPressed:
|
||||
case PointerUpdateKind::RightButtonReleased:
|
||||
return BUTTON_RIGHT;
|
||||
|
||||
case PointerUpdateKind::MiddleButtonPressed:
|
||||
case PointerUpdateKind::MiddleButtonReleased:
|
||||
return BUTTON_MIDDLE;
|
||||
|
||||
case PointerUpdateKind::XButton1Pressed:
|
||||
case PointerUpdateKind::XButton1Released:
|
||||
return BUTTON_WHEEL_UP;
|
||||
|
||||
case PointerUpdateKind::XButton2Pressed:
|
||||
case PointerUpdateKind::XButton2Released:
|
||||
return BUTTON_WHEEL_DOWN;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static bool _is_touch(Windows::UI::Input::PointerPoint ^pointerPoint) {
|
||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
return true;
|
||||
#else
|
||||
using namespace Windows::Devices::Input;
|
||||
switch (pointerPoint->PointerDevice->PointerDeviceType) {
|
||||
case PointerDeviceType::Touch:
|
||||
case PointerDeviceType::Pen:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static Windows::Foundation::Point _get_pixel_position(CoreWindow^ window, Windows::Foundation::Point rawPosition, OS* os) {
|
||||
|
||||
Windows::Foundation::Point outputPosition;
|
||||
|
||||
// Compute coordinates normalized from 0..1.
|
||||
// If the coordinates need to be sized to the SDL window,
|
||||
// we'll do that after.
|
||||
#if 1 || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
|
||||
outputPosition.X = rawPosition.X / window->Bounds.Width;
|
||||
outputPosition.Y = rawPosition.Y / window->Bounds.Height;
|
||||
#else
|
||||
switch (DisplayProperties::CurrentOrientation)
|
||||
{
|
||||
case DisplayOrientations::Portrait:
|
||||
outputPosition.X = rawPosition.X / window->Bounds.Width;
|
||||
outputPosition.Y = rawPosition.Y / window->Bounds.Height;
|
||||
break;
|
||||
case DisplayOrientations::PortraitFlipped:
|
||||
outputPosition.X = 1.0f - (rawPosition.X / window->Bounds.Width);
|
||||
outputPosition.Y = 1.0f - (rawPosition.Y / window->Bounds.Height);
|
||||
break;
|
||||
case DisplayOrientations::Landscape:
|
||||
outputPosition.X = rawPosition.Y / window->Bounds.Height;
|
||||
outputPosition.Y = 1.0f - (rawPosition.X / window->Bounds.Width);
|
||||
break;
|
||||
case DisplayOrientations::LandscapeFlipped:
|
||||
outputPosition.X = 1.0f - (rawPosition.Y / window->Bounds.Height);
|
||||
outputPosition.Y = rawPosition.X / window->Bounds.Width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
OS::VideoMode vm = os->get_video_mode();
|
||||
outputPosition.X *= vm.width;
|
||||
outputPosition.Y *= vm.height;
|
||||
|
||||
return outputPosition;
|
||||
};
|
||||
|
||||
static int _get_finger(uint32_t p_touch_id) {
|
||||
|
||||
return p_touch_id % 31; // for now
|
||||
};
|
||||
|
||||
void App::pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args, bool p_pressed) {
|
||||
|
||||
Windows::UI::Input::PointerPoint ^point = args->CurrentPoint;
|
||||
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
|
||||
int but = _get_button(point);
|
||||
if (_is_touch(point)) {
|
||||
|
||||
InputEvent event;
|
||||
event.type = InputEvent::SCREEN_TOUCH;
|
||||
event.device = 0;
|
||||
event.screen_touch.pressed = p_pressed;
|
||||
event.screen_touch.x = pos.X;
|
||||
event.screen_touch.y = pos.Y;
|
||||
event.screen_touch.index = _get_finger(point->PointerId);
|
||||
|
||||
last_touch_x[event.screen_touch.index] = pos.X;
|
||||
last_touch_y[event.screen_touch.index] = pos.Y;
|
||||
|
||||
os->input_event(event);
|
||||
if (event.screen_touch.index != 0)
|
||||
return;
|
||||
|
||||
}; // fallthrought of sorts
|
||||
|
||||
InputEvent event;
|
||||
event.type = InputEvent::MOUSE_BUTTON;
|
||||
event.device = 0;
|
||||
event.mouse_button.pressed = p_pressed;
|
||||
event.mouse_button.button_index = but;
|
||||
event.mouse_button.x = pos.X;
|
||||
event.mouse_button.y = pos.Y;
|
||||
event.mouse_button.global_x = pos.X;
|
||||
event.mouse_button.global_y = pos.Y;
|
||||
|
||||
last_touch_x[31] = pos.X;
|
||||
last_touch_y[31] = pos.Y;
|
||||
|
||||
os->input_event(event);
|
||||
};
|
||||
|
||||
|
||||
void App::OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
|
||||
pointer_event(sender, args, true);
|
||||
};
|
||||
|
||||
|
||||
void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
|
||||
pointer_event(sender, args, false);
|
||||
};
|
||||
|
||||
void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
|
||||
|
||||
Windows::UI::Input::PointerPoint ^point = args->CurrentPoint;
|
||||
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
|
||||
|
||||
if (_is_touch(point)) {
|
||||
|
||||
InputEvent event;
|
||||
event.type = InputEvent::SCREEN_DRAG;
|
||||
event.device = 0;
|
||||
event.screen_drag.x = pos.X;
|
||||
event.screen_drag.y = pos.Y;
|
||||
event.screen_drag.index = _get_finger(point->PointerId);
|
||||
event.screen_drag.relative_x = event.screen_drag.x - last_touch_x[event.screen_drag.index];
|
||||
event.screen_drag.relative_y = event.screen_drag.y - last_touch_y[event.screen_drag.index];
|
||||
|
||||
os->input_event(event);
|
||||
if (event.screen_drag.index != 0)
|
||||
return;
|
||||
|
||||
}; // fallthrought of sorts
|
||||
|
||||
InputEvent event;
|
||||
event.type = InputEvent::MOUSE_MOTION;
|
||||
event.device = 0;
|
||||
event.mouse_motion.x = pos.X;
|
||||
event.mouse_motion.y = pos.Y;
|
||||
event.mouse_motion.global_x = pos.X;
|
||||
event.mouse_motion.global_y = pos.Y;
|
||||
event.mouse_motion.relative_x = pos.X - last_touch_x[31];
|
||||
event.mouse_motion.relative_y = pos.Y - last_touch_y[31];
|
||||
|
||||
os->input_event(event);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Initializes scene resources
|
||||
void App::Load(Platform::String^ entryPoint)
|
||||
{
|
||||
char** args = {NULL};
|
||||
Main::setup("winrt", 0, args);
|
||||
//char* args[] = {"-test", "render", NULL};
|
||||
//Main::setup("winrt", 2, args);
|
||||
}
|
||||
|
||||
// This method is called after the window becomes active.
|
||||
void App::Run()
|
||||
{
|
||||
|
||||
if (Main::start())
|
||||
os->run();
|
||||
}
|
||||
@ -147,16 +357,29 @@ void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ ar
|
||||
// On Windows Phone 8.1, the window size changes when the device is rotated.
|
||||
// The default framebuffer will not be automatically resized when this occurs.
|
||||
// It is therefore up to the app to handle rotation-specific logic in its rendering code.
|
||||
//os->screen_size_changed();
|
||||
UpdateWindowSize(args->Size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::UpdateWindowSize(Size size)
|
||||
{
|
||||
/*
|
||||
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||
Size pixelSize(ConvertDipsToPixels(size.Width, currentDisplayInformation->LogicalDpi), ConvertDipsToPixels(size.Height, currentDisplayInformation->LogicalDpi));
|
||||
float dpi;
|
||||
#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
|
||||
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||
dpi = currentDisplayInformation->LogicalDpi;
|
||||
#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
dpi = DisplayProperties::LogicalDpi;
|
||||
#endif
|
||||
Size pixelSize(ConvertDipsToPixels(size.Width, dpi), ConvertDipsToPixels(size.Height, dpi));
|
||||
|
||||
mWindowWidth = static_cast<GLsizei>(pixelSize.Width);
|
||||
mWindowHeight = static_cast<GLsizei>(pixelSize.Height);
|
||||
*/
|
||||
|
||||
OS::VideoMode vm;
|
||||
vm.width = mWindowWidth;
|
||||
vm.height = mWindowHeight;
|
||||
vm.fullscreen = true;
|
||||
vm.resizable = false;
|
||||
os->set_video_mode(vm);
|
||||
}
|
||||
|
@ -32,6 +32,12 @@ namespace $ext_safeprojectname$
|
||||
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
|
||||
void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
|
||||
|
||||
void pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args, bool p_pressed);
|
||||
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
||||
void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
||||
void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
||||
|
||||
|
||||
void UpdateWindowSize(Windows::Foundation::Size size);
|
||||
void InitializeEGL(Windows::UI::Core::CoreWindow^ window);
|
||||
void CleanupEGL();
|
||||
@ -45,7 +51,11 @@ namespace $ext_safeprojectname$
|
||||
EGLContext mEglContext;
|
||||
EGLSurface mEglSurface;
|
||||
|
||||
CoreWindow^ window;
|
||||
OSWinrt* os;
|
||||
};
|
||||
|
||||
int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
|
||||
int last_touch_y[32];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
import os
|
||||
|
||||
import sys
|
||||
import string
|
||||
|
||||
|
||||
def is_active():
|
||||
@ -29,48 +30,121 @@ def get_flags():
|
||||
def configure(env):
|
||||
|
||||
env.Append(CPPPATH=['#platform/winrt', '#platform/winrt/include'])
|
||||
arch = ""
|
||||
|
||||
env['OBJSUFFIX'] = ".rt" + env['OBJSUFFIX']
|
||||
env['LIBSUFFIX'] = ".rt" + env['LIBSUFFIX']
|
||||
if os.getenv('PLATFORM') == "ARM":
|
||||
|
||||
env.Append(LIBPATH=['#platform/winrt/x64/lib'])
|
||||
# compiler commandline
|
||||
# debug: /Yu"pch.h" /MP /GS /analyze- /W3 /wd"4453" /wd"28204" /Zc:wchar_t /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.WindowsPhone\" /I"Generated Files\" /I"ARM\Debug\" /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.Shared\" /ZW:nostdlib /Zi /Gm- /Od /sdl /Fd"ARM\Debug\vc120.pdb" /fp:precise /D "PSAPI_VERSION=2" /D "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" /D "_UITHREADCTXT_SUPPORT=0" /D "_UNICODE" /D "UNICODE" /D "_DEBUG" /errorReport:prompt /WX- /Zc:forScope /RTC1 /ZW /Gd /Oy- /MDd /Fa"ARM\Debug\" /EHsc /nologo /Fo"ARM\Debug\" /Fp"ARM\Debug\App2.WindowsPhone.pch"
|
||||
# release: /Yu"pch.h" /MP /GS /GL /analyze- /W3 /wd"4453" /wd"28204" /Gy /Zc:wchar_t /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.WindowsPhone\" /I"Generated Files\" /I"ARM\Release\" /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.Shared\" /ZW:nostdlib /Zi /Gm- /O2 /sdl /Fd"ARM\Release\vc120.pdb" /fp:precise /D "PSAPI_VERSION=2" /D "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" /D "_UITHREADCTXT_SUPPORT=0" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /ZW /Gd /Oy- /Oi /MD /Fa"ARM\Release\" /EHsc /nologo /Fo"ARM\Release\" /Fp"ARM\Release\App2.WindowsPhone.pch"
|
||||
|
||||
if (env["target"]=="release"):
|
||||
# linker commandline
|
||||
# debug: /OUT:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.WindowsPhone.exe" /MANIFEST:NO /NXCOMPAT /PDB:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.WindowsPhone.pdb" /DYNAMICBASE "WindowsPhoneCore.lib" "RuntimeObject.lib" "PhoneAppModelHost.lib" /DEBUG /MACHINE:ARM /NODEFAULTLIB:"kernel32.lib" /NODEFAULTLIB:"ole32.lib" /WINMD /APPCONTAINER /INCREMENTAL /PGD:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.WindowsPhone.pgd" /WINMDFILE:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.winmd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"ARM\Debug\App2.WindowsPhone.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
|
||||
# release: /OUT:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.WindowsPhone.exe" /MANIFEST:NO /LTCG /NXCOMPAT /PDB:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.WindowsPhone.pdb" /DYNAMICBASE "WindowsPhoneCore.lib" "RuntimeObject.lib" "PhoneAppModelHost.lib" /DEBUG /MACHINE:ARM /NODEFAULTLIB:"kernel32.lib" /NODEFAULTLIB:"ole32.lib" /WINMD /APPCONTAINER /OPT:REF /PGD:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.WindowsPhone.pgd" /WINMDFILE:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.winmd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"ARM\Release\App2.WindowsPhone.exe.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
|
||||
|
||||
env.Append(CCFLAGS=['/O2'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
|
||||
env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
|
||||
arch = "arm"
|
||||
|
||||
elif (env["target"]=="test"):
|
||||
env.Append(LINKFLAGS=['/INCREMENTAL:NO', '/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', "WindowsPhoneCore.lib", "RuntimeObject.lib", "PhoneAppModelHost.lib", "/DEBUG", "/MACHINE:ARM", '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"', '/WINMD', '/APPCONTAINER', '/MANIFESTUAC:NO', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1'])
|
||||
env.Append(LIBPATH=['#platform/winrt/ARM/lib'])
|
||||
|
||||
env.Append(CCFLAGS=['/O2','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
|
||||
env.Append(CCFLAGS=string.split('/MP /GS /wd"4453" /wd"28204" /analyze- /Zc:wchar_t /Zi /Gm- /Od /fp:precise /fp:precise /D "PSAPI_VERSION=2" /D "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" /DWINDOWSPHONE_ENABLED /D "_UITHREADCTXT_SUPPORT=0" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /RTC1 /Gd /EHsc /nologo'))
|
||||
env.Append(CXXFLAGS=string.split('/ZW'))
|
||||
|
||||
elif (env["target"]=="debug"):
|
||||
if (env["target"]=="release"):
|
||||
|
||||
env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO','/O1'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
|
||||
env.Append(LINKFLAGS=['/DEBUG'])
|
||||
env.Append(CCFLAGS=['/O2'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
|
||||
|
||||
elif (env["target"]=="profile"):
|
||||
elif (env["target"]=="test"):
|
||||
|
||||
env.Append(CCFLAGS=['-g','-pg'])
|
||||
env.Append(LINKFLAGS=['-pg'])
|
||||
env.Append(CCFLAGS=['/O2','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
|
||||
|
||||
env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/EHsc'])
|
||||
env.Append(CXXFLAGS=['/TP', '/ZW'])
|
||||
env.Append(CPPFLAGS=['/DMSVC', '/GR', ])
|
||||
#env.Append(CCFLAGS=['/I'+os.getenv("WindowsSdkDir")+"/Include"])
|
||||
elif (env["target"]=="debug"):
|
||||
|
||||
env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
|
||||
env.Append(LINKFLAGS=['/DEBUG', '/D_DEBUG'])
|
||||
|
||||
elif (env["target"]=="profile"):
|
||||
|
||||
env.Append(CCFLAGS=['-g','-pg'])
|
||||
env.Append(LINKFLAGS=['-pg'])
|
||||
|
||||
|
||||
env['ENV'] = os.environ;
|
||||
# fix environment for windows phone 8.1
|
||||
env['ENV']['WINDOWSPHONEKITDIR'] = env['ENV']['WINDOWSPHONEKITDIR'].replace("8.0", "8.1") # wtf
|
||||
env['ENV']['INCLUDE'] = env['ENV']['INCLUDE'].replace("8.0", "8.1")
|
||||
env['ENV']['LIB'] = env['ENV']['LIB'].replace("8.0", "8.1")
|
||||
env['ENV']['PATH'] = env['ENV']['PATH'].replace("8.0", "8.1")
|
||||
env['ENV']['LIBPATH'] = env['ENV']['LIBPATH'].replace("8.0\\Windows Metadata", "8.1\\References\\CommonConfiguration\\Neutral")
|
||||
|
||||
else:
|
||||
|
||||
arch = "x64"
|
||||
env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', "kernel32.lib", '/MACHINE:X64', '/WINMD', '/APPCONTAINER', '/MANIFESTUAC:NO', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1'])
|
||||
|
||||
env.Append(LIBPATH=['#platform/winrt/x64/lib'])
|
||||
|
||||
|
||||
if (env["target"]=="release"):
|
||||
|
||||
env.Append(CCFLAGS=['/O2'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
|
||||
env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
|
||||
|
||||
elif (env["target"]=="test"):
|
||||
|
||||
env.Append(CCFLAGS=['/O2','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
|
||||
|
||||
elif (env["target"]=="debug"):
|
||||
|
||||
env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
|
||||
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
|
||||
env.Append(LINKFLAGS=['/DEBUG', '/D_DEBUG'])
|
||||
|
||||
elif (env["target"]=="profile"):
|
||||
|
||||
env.Append(CCFLAGS=['-g','-pg'])
|
||||
env.Append(LINKFLAGS=['-pg'])
|
||||
|
||||
|
||||
env.Append(CCFLAGS=string.split('/MP /GS /wd"4453" /wd"28204" /Zc:wchar_t /Gm- /Od /fp:precise /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /EHsc /nologo'))
|
||||
env.Append(CXXFLAGS=string.split('/ZW'))
|
||||
env.Append(CCFLAGS=['/AI', os.environ['VCINSTALLDIR']+'\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR']+'\\References\\CommonConfiguration\\Neutral'])
|
||||
env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP', '/D_WIN32_WINNT=0x0603', '/DNTDDI_VERSION=0x06030000'])
|
||||
|
||||
env['ENV'] = os.environ;
|
||||
|
||||
|
||||
env["PROGSUFFIX"]="."+arch+env["PROGSUFFIX"]
|
||||
env["OBJSUFFIX"]="."+arch+env["OBJSUFFIX"]
|
||||
env["LIBSUFFIX"]="."+arch+env["LIBSUFFIX"]
|
||||
|
||||
|
||||
#env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/EHsc'])
|
||||
#env.Append(CXXFLAGS=['/TP', '/ZW'])
|
||||
#env.Append(CPPFLAGS=['/DMSVC', '/GR', ])
|
||||
##env.Append(CCFLAGS=['/I'+os.getenv("WindowsSdkDir")+"/Include"])
|
||||
env.Append(CCFLAGS=['/DWINRT_ENABLED'])
|
||||
env.Append(CCFLAGS=['/DWINDOWS_ENABLED'])
|
||||
env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP', '/D_WIN32_WINNT=0x0603', '/DNTDDI_VERSION=0x06030000'])
|
||||
env.Append(CCFLAGS=['/DRTAUDIO_ENABLED'])
|
||||
#env.Append(CCFLAGS=['/DWIN32'])
|
||||
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
|
||||
|
||||
env.Append(CCFLAGS=['/DGLES2_ENABLED'])
|
||||
#env.Append(CCFLAGS=['/DGLES1_ENABLED'])
|
||||
env.Append(LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI', 'wsock32', 'shell32','advapi32'])
|
||||
|
||||
LIBS=[
|
||||
#'winmm',
|
||||
'libEGL',
|
||||
'libGLESv2',
|
||||
'libANGLE',
|
||||
#'kernel32','ole32','user32', 'advapi32'
|
||||
]
|
||||
env.Append(LINKFLAGS=[p+".lib" for p in LIBS])
|
||||
|
||||
import methods
|
||||
env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
|
||||
@ -78,6 +152,5 @@ def configure(env):
|
||||
env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
|
||||
env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
|
||||
|
||||
env['ENV'] = os.environ;
|
||||
|
||||
|
||||
#/c/Program Files (x86)/Windows Phone Kits/8.1/lib/ARM/WindowsPhoneCore.lib
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "gl_context_egl.h"
|
||||
|
||||
#include "EGL/eglext.h"
|
||||
|
||||
using namespace Platform;
|
||||
|
||||
void ContextEGL::release_current() {
|
||||
@ -22,6 +24,14 @@ int ContextEGL::get_window_height() {
|
||||
return height;
|
||||
};
|
||||
|
||||
void ContextEGL::reset() {
|
||||
|
||||
cleanup();
|
||||
|
||||
window = CoreWindow::GetForCurrentThread();
|
||||
initialize();
|
||||
};
|
||||
|
||||
void ContextEGL::swap_buffers() {
|
||||
|
||||
if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE)
|
||||
@ -63,7 +73,23 @@ Error ContextEGL::initialize() {
|
||||
|
||||
try {
|
||||
|
||||
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
const EGLint displayAttributes[] =
|
||||
{
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
|
||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
|
||||
|
||||
if (!eglGetPlatformDisplayEXT)
|
||||
{
|
||||
throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT");
|
||||
}
|
||||
|
||||
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
|
||||
|
||||
if (display == EGL_NO_DISPLAY)
|
||||
{
|
||||
throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display");
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
virtual void swap_buffers();
|
||||
|
||||
virtual Error initialize();
|
||||
void reset();
|
||||
|
||||
void cleanup();
|
||||
|
||||
|
@ -432,31 +432,38 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||
#define EGL_ANGLE_direct3d_display 1
|
||||
#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
|
||||
#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
|
||||
#define EGL_D3D11_FL9_3_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-4)
|
||||
#endif /* EGL_ANGLE_direct3d_display */
|
||||
|
||||
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
|
||||
|
||||
#ifndef EGL_ANGLE_surface_d3d_render_to_back_buffer
|
||||
#define EGL_ANGLE_surface_d3d_render_to_back_buffer 1
|
||||
#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B
|
||||
#define EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER 0x320C
|
||||
#endif /* EGL_ANGLE_surface_d3d_render_to_back_buffer */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3205
|
||||
#endif /* EGL_ANGLE_platform_angle */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_d3d
|
||||
#define EGL_ANGLE_platform_angle_d3d 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
|
||||
#endif /* EGL_ANGLE_platform_angle_d3d */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_opengl
|
||||
#define EGL_ANGLE_platform_angle_opengl 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
|
||||
#endif /* EGL_ANGLE_platform_angle_opengl */
|
||||
|
||||
#ifndef EGL_ARM_pixmap_multisample_discard
|
||||
|
@ -76,12 +76,12 @@
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
|
||||
#if defined(WINAPI_FAMILY) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
|
||||
#include <inspectable.h>
|
||||
typedef IInspectable* EGLNativeWindowType;
|
||||
#else
|
||||
typedef HWND EGLNativeWindowType;
|
||||
#endif // defined(WINAPI_FAMILY) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
#endif
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
|
@ -27,6 +27,10 @@
|
||||
|
||||
#include "KHR/khrplatform.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
@ -39,20 +43,20 @@ typedef unsigned int GLenum;
|
||||
}
|
||||
|
||||
// Must be included after GLenum proxy typedef
|
||||
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
|
||||
#include "ShaderVars.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 129
|
||||
#define ANGLE_SH_VERSION 132
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
SH_WEBGL_SPEC = 0x8B41,
|
||||
|
||||
SH_GLES3_SPEC = 0x8B86,
|
||||
SH_WEBGL2_SPEC = 0x8B87,
|
||||
|
||||
// The CSS Shaders spec is a subset of the WebGL spec.
|
||||
//
|
||||
// In both CSS vertex and fragment shaders, ANGLE:
|
||||
@ -84,31 +88,6 @@ typedef enum {
|
||||
SH_HLSL11_OUTPUT = 0x8B48
|
||||
} ShShaderOutput;
|
||||
|
||||
typedef enum {
|
||||
SH_PRECISION_HIGHP = 0x5001,
|
||||
SH_PRECISION_MEDIUMP = 0x5002,
|
||||
SH_PRECISION_LOWP = 0x5003,
|
||||
SH_PRECISION_UNDEFINED = 0
|
||||
} ShPrecisionType;
|
||||
|
||||
typedef enum {
|
||||
SH_INFO_LOG_LENGTH = 0x8B84,
|
||||
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
|
||||
SH_ACTIVE_UNIFORMS = 0x8B86,
|
||||
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
|
||||
SH_ACTIVE_ATTRIBUTES = 0x8B89,
|
||||
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
|
||||
SH_VARYINGS = 0x8BBB,
|
||||
SH_VARYING_MAX_LENGTH = 0x8BBC,
|
||||
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
|
||||
SH_NAME_MAX_LENGTH = 0x6001,
|
||||
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
|
||||
SH_HASHED_NAMES_COUNT = 0x6003,
|
||||
SH_SHADER_VERSION = 0x6004,
|
||||
SH_RESOURCES_STRING_LENGTH = 0x6005,
|
||||
SH_OUTPUT_TYPE = 0x6006
|
||||
} ShShaderInfo;
|
||||
|
||||
// Compile options.
|
||||
typedef enum {
|
||||
SH_VALIDATE = 0,
|
||||
@ -188,6 +167,11 @@ typedef enum {
|
||||
// This flag scalarizes vec/ivec/bvec/mat constructor args.
|
||||
// It is intended as a workaround for Linux/Mac driver bugs.
|
||||
SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000,
|
||||
|
||||
// This flag overwrites a struct name with a unique prefix.
|
||||
// It is intended as a workaround for drivers that do not handle
|
||||
// struct scopes correctly, including all Mac drivers and Linux AMD.
|
||||
SH_REGENERATE_STRUCT_NAMES = 0x80000,
|
||||
} ShCompileOptions;
|
||||
|
||||
// Defines alternate strategies for implementing array index clamping.
|
||||
@ -202,14 +186,14 @@ typedef enum {
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
COMPILER_EXPORT int ShInitialize();
|
||||
COMPILER_EXPORT bool ShInitialize();
|
||||
//
|
||||
// Driver should call this at shutdown.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
COMPILER_EXPORT int ShFinalize();
|
||||
COMPILER_EXPORT bool ShFinalize();
|
||||
|
||||
// The 64 bits hash function. The first parameter is the input string; the
|
||||
// second parameter is the string length.
|
||||
@ -240,6 +224,12 @@ typedef struct
|
||||
int EXT_frag_depth;
|
||||
int EXT_shader_texture_lod;
|
||||
|
||||
// Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
|
||||
// with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
|
||||
// EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
|
||||
// function. This applies to Tegra K1 devices.
|
||||
int NV_draw_buffers;
|
||||
|
||||
// Set to 1 if highp precision is supported in the fragment language.
|
||||
// Default is 0.
|
||||
int FragmentPrecisionHigh;
|
||||
@ -268,8 +258,10 @@ typedef struct
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
// Parameters:
|
||||
// resources: The object to initialize. Will be comparable with memcmp.
|
||||
//
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
@ -278,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
//
|
||||
typedef void* ShHandle;
|
||||
typedef void *ShHandle;
|
||||
|
||||
//
|
||||
// Returns the a concatenated list of the items in ShBuiltInResources as a string.
|
||||
// Returns the a concatenated list of the items in ShBuiltInResources as a
|
||||
// null-terminated string.
|
||||
// This function must be updated whenever ShBuiltInResources is changed.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of the compiler to be used.
|
||||
// outStringLen: Specifies the size of the buffer, in number of characters. The size
|
||||
// of the buffer required to store the resources string can be obtained
|
||||
// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
|
||||
// outStr: Returns a null-terminated string representing all the built-in resources.
|
||||
COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
|
||||
COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
@ -307,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources* resources);
|
||||
const ShBuiltInResources *resources);
|
||||
COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// Compiles the given shader source.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of compiler to be used.
|
||||
// shaderStrings: Specifies an array of pointers to null-terminated strings
|
||||
@ -334,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
||||
// Can be queried by calling ShGetVariableInfo().
|
||||
//
|
||||
COMPILER_EXPORT int ShCompile(
|
||||
COMPILER_EXPORT bool ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const char * const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions
|
||||
);
|
||||
int compileOptions);
|
||||
|
||||
// Returns a parameter from a compiled shader.
|
||||
// Return the version of the shader language.
|
||||
COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
|
||||
|
||||
// Return the currently set language output type.
|
||||
COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
|
||||
const ShHandle handle);
|
||||
|
||||
// Returns null-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// pname: Specifies the parameter to query.
|
||||
// The following parameters are defined:
|
||||
// SH_INFO_LOG_LENGTH: the number of characters in the information log
|
||||
// including the null termination character.
|
||||
// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
|
||||
// including the null termination character.
|
||||
// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_VARYINGS: the number of varying variables.
|
||||
// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
|
||||
// including the null termination character.
|
||||
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
|
||||
// the null termination character.
|
||||
// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
|
||||
// null termination character.
|
||||
// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
|
||||
// null termination character.
|
||||
// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
|
||||
// SH_SHADER_VERSION: the version of the shader language
|
||||
// SH_OUTPUT_TYPE: the currently set language output type
|
||||
//
|
||||
// params: Requested parameter
|
||||
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
|
||||
ShShaderInfo pname,
|
||||
size_t* params);
|
||||
|
||||
// Returns nul-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the information log. It is assumed that infoLog has enough memory
|
||||
// to accomodate the information log. The size of the buffer required
|
||||
// to store the returned information log can be obtained by calling
|
||||
// ShGetInfo with SH_INFO_LOG_LENGTH.
|
||||
COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
|
||||
COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
|
||||
|
||||
// Returns null-terminated object code for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the object code. It is assumed that infoLog has enough memory to
|
||||
// accomodate the object code. The size of the buffer required to
|
||||
// store the returned object code can be obtained by calling
|
||||
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
|
||||
COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
|
||||
COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
|
||||
|
||||
// Returns information about a shader variable.
|
||||
// Returns a (original_name, hash) map containing all the user defined
|
||||
// names in the shader, including variable names, function names, struct
|
||||
// names, and struct field names.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// variableType: Specifies the variable type; options include
|
||||
// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
|
||||
// index: Specifies the index of the variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value other
|
||||
// than NULL is passed.
|
||||
// size: Returns the size of the variable.
|
||||
// type: Returns the data type of the variable.
|
||||
// precision: Returns the precision of the variable.
|
||||
// staticUse: Returns 1 if the variable is accessed in a statement after
|
||||
// pre-processing, whether or not run-time flow of control will
|
||||
// cause that statement to be executed.
|
||||
// Returns 0 otherwise.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// variable. It is assumed that name has enough memory to accormodate
|
||||
// the variable name. The size of the buffer required to store the
|
||||
// variable name can be obtained by calling ShGetInfo with
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
|
||||
// SH_VARYING_MAX_LENGTH.
|
||||
// mappedName: Returns a null terminated string containing the mapped name of
|
||||
// the variable, It is assumed that mappedName has enough memory
|
||||
// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
|
||||
// mapped name. If the name is not mapped, then name and mappedName
|
||||
// are the same.
|
||||
COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
|
||||
ShShaderInfo variableType,
|
||||
int index,
|
||||
size_t* length,
|
||||
int* size,
|
||||
sh::GLenum* type,
|
||||
ShPrecisionType* precision,
|
||||
int* staticUse,
|
||||
char* name,
|
||||
char* mappedName);
|
||||
|
||||
// Returns information about a name hashing entry from the latest compile.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the name hashing entry to be queried.
|
||||
// name: Returns a null terminated string containing the user defined name.
|
||||
// It is assumed that name has enough memory to accomodate the name.
|
||||
// The size of the buffer required to store the user defined name can
|
||||
// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
|
||||
// hashedName: Returns a null terminated string containing the hashed name of
|
||||
// the uniform variable, It is assumed that hashedName has enough
|
||||
// memory to accomodate the name. The size of the buffer required
|
||||
// to store the name can be obtained by calling ShGetInfo with
|
||||
// SH_HASHED_NAME_MAX_LENGTH.
|
||||
COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
|
||||
int index,
|
||||
char* name,
|
||||
char* hashedName);
|
||||
COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||
const ShHandle handle);
|
||||
|
||||
// Shader variable inspection.
|
||||
// Returns a pointer to a list of variables of the designated type.
|
||||
@ -470,17 +372,17 @@ typedef struct
|
||||
int size;
|
||||
} ShVariableInfo;
|
||||
|
||||
// Returns 1 if the passed in variables pack in maxVectors following
|
||||
// Returns true if the passed in variables pack in maxVectors following
|
||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// flag above.
|
||||
// Parameters:
|
||||
// maxVectors: the available rows of registers.
|
||||
// varInfoArray: an array of variable info (types and sizes).
|
||||
// varInfoArraySize: the size of the variable array.
|
||||
COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
|
||||
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors,
|
||||
ShVariableInfo* varInfoArray,
|
||||
ShVariableInfo *varInfoArray,
|
||||
size_t varInfoArraySize);
|
||||
|
||||
// Gives the compiler-assigned register for an interface block.
|
||||
@ -491,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
|
||||
// interfaceBlockName: Specifies the interface block
|
||||
// indexOut: output variable that stores the assigned register
|
||||
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
const char *interfaceBlockName,
|
||||
const std::string &interfaceBlockName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
// Gives the compiler-assigned register for uniforms in the default
|
||||
@ -503,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
// interfaceBlockName: Specifies the uniform
|
||||
// indexOut: output variable that stores the assigned register
|
||||
COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
|
||||
const char *uniformName,
|
||||
const std::string &uniformName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _COMPILER_INTERFACE_INCLUDED_
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
// Assume ShaderLang.h is included before ShaderVars.h, for sh::GLenum
|
||||
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
|
||||
|
||||
namespace sh
|
||||
{
|
||||
@ -39,7 +40,7 @@ enum BlockLayoutType
|
||||
// Note: we must override the copy constructor and assignment operator so we can
|
||||
// work around excessive GCC binary bloating:
|
||||
// See https://code.google.com/p/angleproject/issues/detail?id=697
|
||||
struct ShaderVariable
|
||||
struct COMPILER_EXPORT ShaderVariable
|
||||
{
|
||||
ShaderVariable();
|
||||
ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
|
||||
@ -49,6 +50,22 @@ struct ShaderVariable
|
||||
|
||||
bool isArray() const { return arraySize > 0; }
|
||||
unsigned int elementCount() const { return std::max(1u, arraySize); }
|
||||
bool isStruct() const { return !fields.empty(); }
|
||||
|
||||
// All of the shader's variables are described using nested data
|
||||
// structures. This is needed in order to disambiguate similar looking
|
||||
// types, such as two structs containing the same fields, but in
|
||||
// different orders. "findInfoByMappedName" provides an easy query for
|
||||
// users to dive into the data structure and fetch the unique variable
|
||||
// instance corresponding to a dereferencing chain of the top-level
|
||||
// variable.
|
||||
// Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
|
||||
// that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
|
||||
// in |originalName|, based on the assumption that |this| defines 'a'.
|
||||
// If no match is found, return false.
|
||||
bool findInfoByMappedName(const std::string &mappedFullName,
|
||||
const ShaderVariable **leafVar,
|
||||
std::string* originalFullName) const;
|
||||
|
||||
GLenum type;
|
||||
GLenum precision;
|
||||
@ -56,58 +73,97 @@ struct ShaderVariable
|
||||
std::string mappedName;
|
||||
unsigned int arraySize;
|
||||
bool staticUse;
|
||||
std::vector<ShaderVariable> fields;
|
||||
std::string structName;
|
||||
|
||||
protected:
|
||||
bool isSameVariableAtLinkTime(const ShaderVariable &other,
|
||||
bool matchPrecision) const;
|
||||
|
||||
bool operator==(const ShaderVariable &other) const;
|
||||
bool operator!=(const ShaderVariable &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct Uniform : public ShaderVariable
|
||||
struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||
{
|
||||
Uniform();
|
||||
~Uniform();
|
||||
Uniform(const Uniform &other);
|
||||
Uniform &operator=(const Uniform &other);
|
||||
bool operator==(const Uniform &other) const;
|
||||
bool operator!=(const Uniform &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool isStruct() const { return !fields.empty(); }
|
||||
|
||||
std::vector<Uniform> fields;
|
||||
// Decide whether two uniforms are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.5.
|
||||
bool isSameUniformAtLinkTime(const Uniform &other) const;
|
||||
};
|
||||
|
||||
struct Attribute : public ShaderVariable
|
||||
struct COMPILER_EXPORT Attribute : public ShaderVariable
|
||||
{
|
||||
Attribute();
|
||||
~Attribute();
|
||||
Attribute(const Attribute &other);
|
||||
Attribute &operator=(const Attribute &other);
|
||||
bool operator==(const Attribute &other) const;
|
||||
bool operator!=(const Attribute &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
int location;
|
||||
};
|
||||
|
||||
struct InterfaceBlockField : public ShaderVariable
|
||||
struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
|
||||
{
|
||||
InterfaceBlockField();
|
||||
~InterfaceBlockField();
|
||||
InterfaceBlockField(const InterfaceBlockField &other);
|
||||
InterfaceBlockField &operator=(const InterfaceBlockField &other);
|
||||
bool operator==(const InterfaceBlockField &other) const;
|
||||
bool operator!=(const InterfaceBlockField &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool isStruct() const { return !fields.empty(); }
|
||||
// Decide whether two InterfaceBlock fields are the same at shader
|
||||
// link time, assuming one from vertex shader and the other from
|
||||
// fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.7.
|
||||
bool isSameInterfaceBlockFieldAtLinkTime(
|
||||
const InterfaceBlockField &other) const;
|
||||
|
||||
bool isRowMajorMatrix;
|
||||
std::vector<InterfaceBlockField> fields;
|
||||
bool isRowMajorLayout;
|
||||
};
|
||||
|
||||
struct Varying : public ShaderVariable
|
||||
struct COMPILER_EXPORT Varying : public ShaderVariable
|
||||
{
|
||||
Varying();
|
||||
~Varying();
|
||||
Varying(const Varying &other);
|
||||
Varying(const Varying &otherg);
|
||||
Varying &operator=(const Varying &other);
|
||||
bool operator==(const Varying &other) const;
|
||||
bool operator!=(const Varying &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool isStruct() const { return !fields.empty(); }
|
||||
// Decide whether two varyings are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.9.
|
||||
bool isSameVaryingAtLinkTime(const Varying &other) const;
|
||||
|
||||
InterpolationType interpolation;
|
||||
std::vector<Varying> fields;
|
||||
std::string structName;
|
||||
bool isInvariant;
|
||||
};
|
||||
|
||||
struct InterfaceBlock
|
||||
struct COMPILER_EXPORT InterfaceBlock
|
||||
{
|
||||
InterfaceBlock();
|
||||
~InterfaceBlock();
|
||||
@ -116,6 +172,7 @@ struct InterfaceBlock
|
||||
|
||||
std::string name;
|
||||
std::string mappedName;
|
||||
std::string instanceName;
|
||||
unsigned int arraySize;
|
||||
BlockLayoutType layout;
|
||||
bool isRowMajorLayout;
|
||||
|
@ -71,7 +71,7 @@ const char * OSWinrt::get_video_driver_name(int p_driver) const {
|
||||
|
||||
OS::VideoMode OSWinrt::get_default_video_mode() const {
|
||||
|
||||
return VideoMode(800,600,false);
|
||||
return video_mode;
|
||||
}
|
||||
|
||||
int OSWinrt::get_audio_driver_count() const {
|
||||
@ -142,12 +142,27 @@ void OSWinrt::set_gl_context(ContextEGL* p_context) {
|
||||
gl_context = p_context;
|
||||
};
|
||||
|
||||
void OSWinrt::screen_size_changed() {
|
||||
|
||||
gl_context->reset();
|
||||
};
|
||||
|
||||
void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
|
||||
|
||||
main_loop=NULL;
|
||||
outside=true;
|
||||
|
||||
gl_context->initialize();
|
||||
VideoMode vm;
|
||||
vm.width = gl_context->get_window_width();
|
||||
vm.height = gl_context->get_window_height();
|
||||
vm.fullscreen = true;
|
||||
vm.resizable = false;
|
||||
|
||||
set_video_mode(vm);
|
||||
|
||||
gl_context->make_current();
|
||||
rasterizer = memnew( RasterizerGLES2 );
|
||||
|
||||
visual_server = memnew( VisualServerRaster(rasterizer) );
|
||||
if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
|
||||
@ -270,6 +285,11 @@ String OSWinrt::get_clipboard() const {
|
||||
};
|
||||
|
||||
|
||||
void OSWinrt::input_event(InputEvent &p_event) {
|
||||
p_event.ID = ++last_id;
|
||||
input->parse_input_event(p_event);
|
||||
};
|
||||
|
||||
void OSWinrt::delete_main_loop() {
|
||||
|
||||
if (main_loop)
|
||||
@ -392,7 +412,7 @@ void OSWinrt::set_window_title(const String& p_title) {
|
||||
|
||||
void OSWinrt::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
|
||||
|
||||
|
||||
video_mode = p_video_mode;
|
||||
}
|
||||
OS::VideoMode OSWinrt::get_video_mode(int p_screen) const {
|
||||
|
||||
@ -512,7 +532,7 @@ Error OSWinrt::kill(const ProcessID& p_pid) {
|
||||
|
||||
Error OSWinrt::set_cwd(const String& p_cwd) {
|
||||
|
||||
return OK;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
String OSWinrt::get_executable_path() const {
|
||||
@ -553,8 +573,12 @@ Error OSWinrt::shell_open(String p_uri) {
|
||||
|
||||
String OSWinrt::get_locale() const {
|
||||
|
||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // this should work on phone 8.1, but it doesn't
|
||||
return "en";
|
||||
#else
|
||||
Platform::String ^language = Windows::Globalization::Language::CurrentInputMethodLanguageTag;
|
||||
return language->Data();
|
||||
#endif
|
||||
}
|
||||
|
||||
void OSWinrt::release_rendering_thread() {
|
||||
@ -634,6 +658,7 @@ OSWinrt::OSWinrt() {
|
||||
|
||||
gl_context = NULL;
|
||||
|
||||
AudioDriverManagerSW::add_driver(&audio_driver);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "servers/spatial_sound/spatial_sound_server_sw.h"
|
||||
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
|
||||
#include "servers/physics_2d/physics_2d_server_sw.h"
|
||||
#include "servers/audio/audio_driver_dummy.h"
|
||||
|
||||
#include "gl_context_egl.h"
|
||||
|
||||
@ -124,6 +125,7 @@ class OSWinrt : public OS {
|
||||
|
||||
MainLoop *main_loop;
|
||||
|
||||
AudioDriverDummy audio_driver;
|
||||
AudioServerSW *audio_server;
|
||||
SampleManagerMallocSW *sample_manager;
|
||||
SpatialSoundServerSW *spatial_sound_server;
|
||||
@ -226,17 +228,22 @@ public:
|
||||
virtual String get_data_dir() const;
|
||||
|
||||
void set_gl_context(ContextEGL* p_context);
|
||||
void screen_size_changed();
|
||||
|
||||
virtual void release_rendering_thread();
|
||||
virtual void make_rendering_thread();
|
||||
virtual void swap_buffers();
|
||||
|
||||
virtual bool has_touchscreen_ui_hint() const { return true; };
|
||||
|
||||
virtual Error shell_open(String p_uri);
|
||||
|
||||
void run();
|
||||
|
||||
virtual bool get_swap_ok_cancel() { return true; }
|
||||
|
||||
void input_event(InputEvent &p_event);
|
||||
|
||||
OSWinrt();
|
||||
~OSWinrt();
|
||||
|
||||
|
@ -122,6 +122,13 @@ def configure(env):
|
||||
if platform.platform() == 'Linux':
|
||||
env.Append(CPPFLAGS=["-DALSA_ENABLED"])
|
||||
env.Append(LIBS=['asound'])
|
||||
if not os.system("pkg-config --exists libpulse-simple"):
|
||||
print("Enabling PulseAudio")
|
||||
env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"])
|
||||
env.ParseConfig('pkg-config --cflags --libs libpulse-simple')
|
||||
else:
|
||||
print("PulseAudio development libraries not found, disabling driver")
|
||||
|
||||
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES1_ENABLED','-DGLES_OVER_GL'])
|
||||
env.Append(LIBS=['GL', 'GLU', 'pthread', 'z'])
|
||||
#env.Append(CPPFLAGS=['-DMPC_FIXED_POINT'])
|
||||
|
@ -75,6 +75,18 @@ OS::VideoMode OS_X11::get_default_video_mode() const {
|
||||
return OS::VideoMode(800,600,false);
|
||||
}
|
||||
|
||||
int OS_X11::get_audio_driver_count() const {
|
||||
|
||||
return AudioDriverManagerSW::get_driver_count();
|
||||
}
|
||||
|
||||
const char *OS_X11::get_audio_driver_name(int p_driver) const {
|
||||
|
||||
AudioDriverSW* driver = AudioDriverManagerSW::get_driver(p_driver);
|
||||
ERR_FAIL_COND_V( !driver, "" );
|
||||
return AudioDriverManagerSW::get_driver(p_driver)->get_name();
|
||||
}
|
||||
|
||||
void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
|
||||
|
||||
last_button_state=0;
|
||||
@ -1447,6 +1459,10 @@ OS_X11::OS_X11() {
|
||||
AudioDriverManagerSW::add_driver(&driver_rtaudio);
|
||||
#endif
|
||||
|
||||
#ifdef PULSEAUDIO_ENABLED
|
||||
AudioDriverManagerSW::add_driver(&driver_pulseaudio);
|
||||
#endif
|
||||
|
||||
#ifdef ALSA_ENABLED
|
||||
AudioDriverManagerSW::add_driver(&driver_alsa);
|
||||
#endif
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "drivers/rtaudio/audio_driver_rtaudio.h"
|
||||
#include "drivers/alsa/audio_driver_alsa.h"
|
||||
#include "drivers/ao/audio_driver_ao.h"
|
||||
#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
|
||||
#include "servers/physics_2d/physics_2d_server_sw.h"
|
||||
|
||||
#include <X11/keysym.h>
|
||||
@ -134,6 +135,10 @@ class OS_X11 : public OS_Unix {
|
||||
AudioDriverAO driver_ao;
|
||||
#endif
|
||||
|
||||
#ifdef PULSEAUDIO_ENABLED
|
||||
AudioDriverPulseAudio driver_pulseaudio;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
JOYSTICKS_MAX = 8,
|
||||
MAX_JOY_AXIS = 32768, // I've no idea
|
||||
@ -166,6 +171,9 @@ protected:
|
||||
virtual const char * get_video_driver_name(int p_driver) const;
|
||||
virtual VideoMode get_default_video_mode() const;
|
||||
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char * get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
|
||||
virtual void finalize();
|
||||
|
||||
|
@ -41,7 +41,6 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
|
||||
|
||||
bool solids=build_mode==BUILD_SOLIDS;
|
||||
|
||||
|
||||
if (solids) {
|
||||
|
||||
//here comes the sun, lalalala
|
||||
@ -51,6 +50,8 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
|
||||
Ref<ConvexPolygonShape2D> convex = memnew( ConvexPolygonShape2D );
|
||||
convex->set_points(decomp[i]);
|
||||
co->add_shape(convex,get_transform());
|
||||
if (trigger)
|
||||
co->set_shape_as_trigger(co->get_shape_count()-1,true);
|
||||
|
||||
}
|
||||
|
||||
@ -71,6 +72,8 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
|
||||
concave->set_segments(segments);
|
||||
|
||||
co->add_shape(concave,get_transform());
|
||||
if (trigger)
|
||||
co->set_shape_as_trigger(co->get_shape_count()-1,true);
|
||||
|
||||
}
|
||||
|
||||
@ -166,6 +169,18 @@ Rect2 CollisionPolygon2D::get_item_rect() const {
|
||||
return aabb;
|
||||
}
|
||||
|
||||
void CollisionPolygon2D::set_trigger(bool p_trigger) {
|
||||
|
||||
trigger=p_trigger;
|
||||
_update_parent();
|
||||
}
|
||||
|
||||
bool CollisionPolygon2D::is_trigger() const{
|
||||
|
||||
return trigger;
|
||||
}
|
||||
|
||||
|
||||
void CollisionPolygon2D::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon2D::_add_to_collision_object);
|
||||
@ -175,14 +190,19 @@ void CollisionPolygon2D::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_build_mode"),&CollisionPolygon2D::set_build_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon2D::get_build_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_trigger"),&CollisionPolygon2D::set_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("is_trigger"),&CollisionPolygon2D::is_trigger);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Segments"),_SCS("set_build_mode"),_SCS("get_build_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger"));
|
||||
}
|
||||
|
||||
CollisionPolygon2D::CollisionPolygon2D() {
|
||||
|
||||
aabb=Rect2(-10,-10,20,20);
|
||||
build_mode=BUILD_SOLIDS;
|
||||
trigger=false;
|
||||
|
||||
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ protected:
|
||||
Rect2 aabb;
|
||||
BuildMode build_mode;
|
||||
Vector<Point2> polygon;
|
||||
bool trigger;
|
||||
|
||||
void _add_to_collision_object(Object *p_obj);
|
||||
void _update_parent();
|
||||
@ -60,6 +61,9 @@ protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_trigger(bool p_trigger);
|
||||
bool is_trigger() const;
|
||||
|
||||
void set_build_mode(BuildMode p_mode);
|
||||
BuildMode get_build_mode() const;
|
||||
|
||||
|
@ -858,7 +858,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
|
||||
//motion recover
|
||||
for(int i=0;i<get_shape_count();i++) {
|
||||
|
||||
|
||||
if (is_shape_set_as_trigger(i))
|
||||
continue;
|
||||
if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask))
|
||||
collided=true;
|
||||
|
||||
@ -902,6 +903,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
|
||||
|
||||
for(int i=0;i<get_shape_count();i++) {
|
||||
|
||||
if (is_shape_set_as_trigger(i))
|
||||
continue;
|
||||
|
||||
float lsafe,lunsafe;
|
||||
bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask);
|
||||
|
@ -870,6 +870,9 @@ Vector3 KinematicBody::move(const Vector3& p_motion) {
|
||||
for(int j=0;j<8;j++) {
|
||||
for(int i=0;i<res_shapes;i++) {
|
||||
|
||||
if (is_shape_set_as_trigger(i))
|
||||
continue;
|
||||
|
||||
Vector3 a = sr[i*2+0];
|
||||
Vector3 b = sr[i*2+1];
|
||||
//print_line(String()+a+" -> "+b);
|
||||
@ -930,6 +933,8 @@ Vector3 KinematicBody::move(const Vector3& p_motion) {
|
||||
for(int i=0;i<get_shape_count();i++) {
|
||||
|
||||
|
||||
if (is_shape_set_as_trigger(i))
|
||||
continue;
|
||||
|
||||
float lsafe,lunsafe;
|
||||
PhysicsDirectSpaceState::ShapeRestInfo lrest;
|
||||
@ -1041,6 +1046,8 @@ bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) {
|
||||
//fill exclude list..
|
||||
for(int i=0;i<get_shape_count();i++) {
|
||||
|
||||
if (is_shape_set_as_trigger(i))
|
||||
continue;
|
||||
|
||||
bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,0,exclude,get_layer_mask(),mask);
|
||||
if (col)
|
||||
|
@ -1178,6 +1178,19 @@ NodePath AnimationPlayer::get_root() const {
|
||||
return root;
|
||||
}
|
||||
|
||||
void AnimationPlayer::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
String pf = p_function;
|
||||
if (p_function=="play" || p_function=="remove_animation" || p_function=="has_animation" || p_function=="queue") {
|
||||
List<StringName> al;
|
||||
get_animation_list(&al);
|
||||
for (List<StringName>::Element *E=al.front();E;E=E->next()) {
|
||||
|
||||
r_options->push_back("\""+String(E->get())+"\"");
|
||||
}
|
||||
}
|
||||
Node::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
void AnimationPlayer::_bind_methods() {
|
||||
|
||||
|
@ -290,6 +290,9 @@ public:
|
||||
|
||||
void clear_caches(); ///< must be called by hand if an animation was modified after added
|
||||
|
||||
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
|
||||
AnimationPlayer();
|
||||
~AnimationPlayer();
|
||||
|
||||
|
@ -124,32 +124,34 @@ void Tween::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_tween_process_mode"),&Tween::get_tween_process_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("start"),&Tween::start );
|
||||
ObjectTypeDB::bind_method(_MD("reset","node","key"),&Tween::reset );
|
||||
ObjectTypeDB::bind_method(_MD("reset","object","key"),&Tween::reset );
|
||||
ObjectTypeDB::bind_method(_MD("reset_all"),&Tween::reset_all );
|
||||
ObjectTypeDB::bind_method(_MD("stop","node","key"),&Tween::stop );
|
||||
ObjectTypeDB::bind_method(_MD("stop","object","key"),&Tween::stop );
|
||||
ObjectTypeDB::bind_method(_MD("stop_all"),&Tween::stop_all );
|
||||
ObjectTypeDB::bind_method(_MD("resume","node","key"),&Tween::resume );
|
||||
ObjectTypeDB::bind_method(_MD("resume","object","key"),&Tween::resume );
|
||||
ObjectTypeDB::bind_method(_MD("resume_all"),&Tween::resume_all );
|
||||
ObjectTypeDB::bind_method(_MD("remove","node","key"),&Tween::remove );
|
||||
ObjectTypeDB::bind_method(_MD("remove","object","key"),&Tween::remove );
|
||||
ObjectTypeDB::bind_method(_MD("remove_all"),&Tween::remove_all );
|
||||
ObjectTypeDB::bind_method(_MD("seek","time"),&Tween::seek );
|
||||
ObjectTypeDB::bind_method(_MD("tell"),&Tween::tell );
|
||||
ObjectTypeDB::bind_method(_MD("get_runtime"),&Tween::get_runtime );
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("interpolate_property","node","property","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_property, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("interpolate_method","node","method","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_method, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("interpolate_callback","node","callback","times_in_sec","args"),&Tween::interpolate_callback, DEFVAL(Variant()) );
|
||||
ObjectTypeDB::bind_method(_MD("follow_property","node","property","initial_val","target","target_property","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_property, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("follow_method","node","method","initial_val","target","target_method","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_method, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("targeting_property","node","property","initial","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_property, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("targeting_method","node","method","initial","initial_method","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_method, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("interpolate_property","object","property","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_property, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("interpolate_method","object","method","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_method, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("interpolate_callback","object","times_in_sec","callback","args"),&Tween::interpolate_callback, DEFVAL(Variant()) );
|
||||
ObjectTypeDB::bind_method(_MD("follow_property","object","property","initial_val","target","target_property","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_property, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("follow_method","object","method","initial_val","target","target_method","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_method, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("targeting_property","object","property","initial","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_property, DEFVAL(0) );
|
||||
ObjectTypeDB::bind_method(_MD("targeting_method","object","method","initial","initial_method","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_method, DEFVAL(0) );
|
||||
|
||||
ADD_SIGNAL( MethodInfo("tween_start", PropertyInfo( Variant::OBJECT,"node"), PropertyInfo( Variant::STRING,"key")) );
|
||||
ADD_SIGNAL( MethodInfo("tween_step", PropertyInfo( Variant::OBJECT,"node"), PropertyInfo( Variant::STRING,"key"), PropertyInfo( Variant::REAL,"elapsed"), PropertyInfo( Variant::OBJECT,"value")) );
|
||||
ADD_SIGNAL( MethodInfo("tween_complete", PropertyInfo( Variant::OBJECT,"node"), PropertyInfo( Variant::STRING,"key")) );
|
||||
ADD_SIGNAL( MethodInfo("tween_start", PropertyInfo( Variant::OBJECT,"object"), PropertyInfo( Variant::STRING,"key")) );
|
||||
ADD_SIGNAL( MethodInfo("tween_step", PropertyInfo( Variant::OBJECT,"object"), PropertyInfo( Variant::STRING,"key"), PropertyInfo( Variant::REAL,"elapsed"), PropertyInfo( Variant::OBJECT,"value")) );
|
||||
ADD_SIGNAL( MethodInfo("tween_complete", PropertyInfo( Variant::OBJECT,"object"), PropertyInfo( Variant::STRING,"key")) );
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "playback/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_tween_process_mode"), _SCS("get_tween_process_mode"));
|
||||
//ADD_PROPERTY( PropertyInfo( Variant::BOOL, "activate"), _SCS("set_active"), _SCS("is_active"));
|
||||
|
||||
BIND_CONSTANT(TWEEN_PROCESS_FIXED);
|
||||
BIND_CONSTANT(TWEEN_PROCESS_IDLE);
|
||||
|
||||
BIND_CONSTANT(TRANS_LINEAR);
|
||||
BIND_CONSTANT(TRANS_SINE);
|
||||
@ -181,19 +183,19 @@ Variant& Tween::_get_initial_val(InterpolateData& p_data) {
|
||||
case TARGETING_PROPERTY:
|
||||
case TARGETING_METHOD: {
|
||||
|
||||
Node *node = get_node(p_data.target);
|
||||
ERR_FAIL_COND_V(node == NULL,p_data.initial_val);
|
||||
Object *object = ObjectDB::get_instance(p_data.target_id);
|
||||
ERR_FAIL_COND_V(object == NULL,p_data.initial_val);
|
||||
|
||||
static Variant initial_val;
|
||||
if(p_data.type == TARGETING_PROPERTY) {
|
||||
|
||||
bool valid = false;
|
||||
initial_val = node->get(p_data.target_key, &valid);
|
||||
initial_val = object->get(p_data.target_key, &valid);
|
||||
ERR_FAIL_COND_V(!valid,p_data.initial_val);
|
||||
} else {
|
||||
|
||||
Variant::CallError error;
|
||||
initial_val = node->call(p_data.target_key, NULL, 0, error);
|
||||
initial_val = object->call(p_data.target_key, NULL, 0, error);
|
||||
ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK,p_data.initial_val);
|
||||
}
|
||||
return initial_val;
|
||||
@ -213,7 +215,7 @@ Variant& Tween::_get_delta_val(InterpolateData& p_data) {
|
||||
case FOLLOW_PROPERTY:
|
||||
case FOLLOW_METHOD: {
|
||||
|
||||
Node *target = get_node(p_data.target);
|
||||
Object *target = ObjectDB::get_instance(p_data.target_id);
|
||||
ERR_FAIL_COND_V(target == NULL,p_data.initial_val);
|
||||
|
||||
Variant final_val;
|
||||
@ -264,6 +266,11 @@ Variant Tween::_run_equation(InterpolateData& p_data) {
|
||||
|
||||
switch(initial_val.get_type())
|
||||
{
|
||||
|
||||
case Variant::BOOL:
|
||||
result = ((int) _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int) initial_val, (int) delta_val, p_data.times_in_sec)) >= 0.5;
|
||||
break;
|
||||
|
||||
case Variant::INT:
|
||||
result = (int) _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int) initial_val, (int) delta_val, p_data.times_in_sec);
|
||||
break;
|
||||
@ -409,7 +416,7 @@ Variant Tween::_run_equation(InterpolateData& p_data) {
|
||||
|
||||
bool Tween::_apply_tween_value(InterpolateData& p_data, Variant& value) {
|
||||
|
||||
Object *object = get_node(p_data.path);
|
||||
Object *object = ObjectDB::get_instance(p_data.id);
|
||||
ERR_FAIL_COND_V(object == NULL, false);
|
||||
|
||||
switch(p_data.type) {
|
||||
@ -452,6 +459,7 @@ void Tween::_tween_process(float p_delta) {
|
||||
return;
|
||||
p_delta *= speed_scale;
|
||||
|
||||
pending_update ++;
|
||||
// if repeat and all interpolates was finished then reset all interpolates
|
||||
if(repeat) {
|
||||
bool all_finished = true;
|
||||
@ -476,7 +484,7 @@ void Tween::_tween_process(float p_delta) {
|
||||
if(!data.active || data.finish)
|
||||
continue;
|
||||
|
||||
Object *object = get_node(data.path);
|
||||
Object *object = ObjectDB::get_instance(data.id);
|
||||
if(object == NULL)
|
||||
continue;
|
||||
|
||||
@ -523,6 +531,7 @@ void Tween::_tween_process(float p_delta) {
|
||||
if(data.finish)
|
||||
emit_signal("tween_complete",object,data.key);
|
||||
}
|
||||
pending_update --;
|
||||
}
|
||||
|
||||
void Tween::set_tween_process_mode(TweenProcessMode p_mode) {
|
||||
@ -598,16 +607,17 @@ bool Tween::start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::reset(Node *p_node, String p_key) {
|
||||
bool Tween::reset(Object *p_object, String p_key) {
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
Node *node = get_node(data.path);
|
||||
if(node == NULL)
|
||||
Object *object = ObjectDB::get_instance(data.id);
|
||||
if(object == NULL)
|
||||
continue;
|
||||
|
||||
if(node == p_node && data.key == p_key) {
|
||||
if(object == p_object && data.key == p_key) {
|
||||
|
||||
data.elapsed = 0;
|
||||
data.finish = false;
|
||||
@ -615,11 +625,13 @@ bool Tween::reset(Node *p_node, String p_key) {
|
||||
_apply_tween_value(data, data.initial_val);
|
||||
}
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::reset_all() {
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
@ -628,20 +640,23 @@ bool Tween::reset_all() {
|
||||
if(data.delay == 0)
|
||||
_apply_tween_value(data, data.initial_val);
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::stop(Node *p_node, String p_key) {
|
||||
bool Tween::stop(Object *p_object, String p_key) {
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
Node *node = get_node(data.path);
|
||||
if(node == NULL)
|
||||
Object *object = ObjectDB::get_instance(data.id);
|
||||
if(object == NULL)
|
||||
continue;
|
||||
if(node == p_node && data.key == p_key)
|
||||
if(object == p_object && data.key == p_key)
|
||||
data.active = false;
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -650,28 +665,32 @@ bool Tween::stop_all() {
|
||||
set_active(false);
|
||||
_set_process(false);
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
data.active = false;
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::resume(Node *p_node, String p_key) {
|
||||
bool Tween::resume(Object *p_object, String p_key) {
|
||||
|
||||
set_active(true);
|
||||
_set_process(true);
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
Node *node = get_node(data.path);
|
||||
if(node == NULL)
|
||||
Object *object = ObjectDB::get_instance(data.id);
|
||||
if(object == NULL)
|
||||
continue;
|
||||
if(node == p_node && data.key == p_key)
|
||||
if(object == p_object && data.key == p_key)
|
||||
data.active = true;
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -680,23 +699,26 @@ bool Tween::resume_all() {
|
||||
set_active(true);
|
||||
_set_process(true);
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
data.active = true;
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::remove(Node *p_node, String p_key) {
|
||||
bool Tween::remove(Object *p_object, String p_key) {
|
||||
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
Node *node = get_node(data.path);
|
||||
if(node == NULL)
|
||||
Object *object = ObjectDB::get_instance(data.id);
|
||||
if(object == NULL)
|
||||
continue;
|
||||
if(node == p_node && data.key == p_key) {
|
||||
if(object == p_object && data.key == p_key) {
|
||||
interpolates.erase(E);
|
||||
return true;
|
||||
}
|
||||
@ -706,6 +728,7 @@ bool Tween::remove(Node *p_node, String p_key) {
|
||||
|
||||
bool Tween::remove_all() {
|
||||
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
set_active(false);
|
||||
_set_process(false);
|
||||
interpolates.clear();
|
||||
@ -714,6 +737,7 @@ bool Tween::remove_all() {
|
||||
|
||||
bool Tween::seek(real_t p_time) {
|
||||
|
||||
pending_update ++;
|
||||
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
InterpolateData& data = E->get();
|
||||
@ -744,11 +768,13 @@ bool Tween::seek(real_t p_time) {
|
||||
|
||||
_apply_tween_value(data, result);
|
||||
}
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
real_t Tween::tell() const {
|
||||
|
||||
pending_update ++;
|
||||
real_t pos = 0;
|
||||
for(const List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
@ -756,11 +782,13 @@ real_t Tween::tell() const {
|
||||
if(data.elapsed > pos)
|
||||
pos = data.elapsed;
|
||||
}
|
||||
pending_update --;
|
||||
return pos;
|
||||
}
|
||||
|
||||
real_t Tween::get_runtime() const {
|
||||
|
||||
pending_update ++;
|
||||
real_t runtime = 0;
|
||||
for(const List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
|
||||
|
||||
@ -769,6 +797,7 @@ real_t Tween::get_runtime() const {
|
||||
if(t > runtime)
|
||||
runtime = t;
|
||||
}
|
||||
pending_update --;
|
||||
return runtime;
|
||||
}
|
||||
|
||||
@ -779,6 +808,12 @@ bool Tween::_calc_delta_val(const Variant& p_initial_val, const Variant& p_final
|
||||
Variant& delta_val = p_delta_val;
|
||||
|
||||
switch(initial_val.get_type()) {
|
||||
|
||||
case Variant::BOOL:
|
||||
//delta_val = p_final_val;
|
||||
delta_val = (int) p_final_val - (int) p_initial_val;
|
||||
break;
|
||||
|
||||
case Variant::INT:
|
||||
delta_val = (int) final_val - (int) initial_val;
|
||||
break;
|
||||
@ -873,7 +908,7 @@ bool Tween::_calc_delta_val(const Variant& p_initial_val, const Variant& p_final
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::interpolate_property(Node *p_node
|
||||
bool Tween::interpolate_property(Object *p_object
|
||||
, String p_property
|
||||
, Variant p_initial_val
|
||||
, Variant p_final_val
|
||||
@ -882,11 +917,12 @@ bool Tween::interpolate_property(Node *p_node
|
||||
, EaseType p_ease_type
|
||||
, real_t p_delay
|
||||
) {
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
// convert INT to REAL is better for interpolaters
|
||||
if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
|
||||
if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec <= 0, false);
|
||||
ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
|
||||
@ -894,7 +930,7 @@ bool Tween::interpolate_property(Node *p_node
|
||||
ERR_FAIL_COND_V(p_delay < 0, false);
|
||||
|
||||
bool prop_valid = false;
|
||||
p_node->get(p_property,&prop_valid);
|
||||
p_object->get(p_property,&prop_valid);
|
||||
ERR_FAIL_COND_V(!prop_valid, false);
|
||||
|
||||
InterpolateData data;
|
||||
@ -903,7 +939,7 @@ bool Tween::interpolate_property(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_property;
|
||||
data.initial_val = p_initial_val;
|
||||
data.final_val = p_final_val;
|
||||
@ -919,7 +955,7 @@ bool Tween::interpolate_property(Node *p_node
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::interpolate_method(Node *p_node
|
||||
bool Tween::interpolate_method(Object *p_object
|
||||
, String p_method
|
||||
, Variant p_initial_val
|
||||
, Variant p_final_val
|
||||
@ -928,18 +964,19 @@ bool Tween::interpolate_method(Node *p_node
|
||||
, EaseType p_ease_type
|
||||
, real_t p_delay
|
||||
) {
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
// convert INT to REAL is better for interpolaters
|
||||
if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
|
||||
if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec <= 0, false);
|
||||
ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
|
||||
ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
|
||||
ERR_FAIL_COND_V(p_delay < 0, false);
|
||||
|
||||
ERR_FAIL_COND_V(!p_node->has_method(p_method), false);
|
||||
ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
|
||||
|
||||
InterpolateData data;
|
||||
data.active = true;
|
||||
@ -947,7 +984,7 @@ bool Tween::interpolate_method(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_method;
|
||||
data.initial_val = p_initial_val;
|
||||
data.final_val = p_final_val;
|
||||
@ -963,16 +1000,17 @@ bool Tween::interpolate_method(Node *p_node
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::interpolate_callback(Node *p_node
|
||||
, String p_callback
|
||||
bool Tween::interpolate_callback(Object *p_object
|
||||
, real_t p_times_in_sec
|
||||
, String p_callback
|
||||
, Variant p_arg
|
||||
) {
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec < 0, false);
|
||||
|
||||
ERR_FAIL_COND_V(!p_node->has_method(p_callback), false);
|
||||
ERR_FAIL_COND_V(!p_object->has_method(p_callback), false);
|
||||
|
||||
InterpolateData data;
|
||||
data.active = true;
|
||||
@ -980,30 +1018,33 @@ bool Tween::interpolate_callback(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_callback;
|
||||
data.times_in_sec = p_times_in_sec;
|
||||
data.delay = 0;
|
||||
data.arg = p_arg;
|
||||
|
||||
pending_update ++;
|
||||
interpolates.push_back(data);
|
||||
pending_update --;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::follow_property(Node *p_node
|
||||
bool Tween::follow_property(Object *p_object
|
||||
, String p_property
|
||||
, Variant p_initial_val
|
||||
, Node *p_target
|
||||
, Object *p_target
|
||||
, String p_target_property
|
||||
, real_t p_times_in_sec
|
||||
, TransitionType p_trans_type
|
||||
, EaseType p_ease_type
|
||||
, real_t p_delay
|
||||
) {
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
// convert INT to REAL is better for interpolaters
|
||||
if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_target == NULL, false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec <= 0, false);
|
||||
ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
|
||||
@ -1011,7 +1052,7 @@ bool Tween::follow_property(Node *p_node
|
||||
ERR_FAIL_COND_V(p_delay < 0, false);
|
||||
|
||||
bool prop_valid = false;
|
||||
p_node->get(p_property,&prop_valid);
|
||||
p_object->get(p_property,&prop_valid);
|
||||
ERR_FAIL_COND_V(!prop_valid, false);
|
||||
|
||||
bool target_prop_valid = false;
|
||||
@ -1028,10 +1069,10 @@ bool Tween::follow_property(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_property;
|
||||
data.initial_val = p_initial_val;
|
||||
data.target = p_target->get_path();
|
||||
data.target_id = p_target->get_instance_ID();
|
||||
data.target_key = p_target_property;
|
||||
data.times_in_sec = p_times_in_sec;
|
||||
data.trans_type = p_trans_type;
|
||||
@ -1042,27 +1083,28 @@ bool Tween::follow_property(Node *p_node
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::follow_method(Node *p_node
|
||||
bool Tween::follow_method(Object *p_object
|
||||
, String p_method
|
||||
, Variant p_initial_val
|
||||
, Node *p_target
|
||||
, Object *p_target
|
||||
, String p_target_method
|
||||
, real_t p_times_in_sec
|
||||
, TransitionType p_trans_type
|
||||
, EaseType p_ease_type
|
||||
, real_t p_delay
|
||||
) {
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
// convert INT to REAL is better for interpolaters
|
||||
if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_target == NULL, false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec <= 0, false);
|
||||
ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
|
||||
ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
|
||||
ERR_FAIL_COND_V(p_delay < 0, false);
|
||||
|
||||
ERR_FAIL_COND_V(!p_node->has_method(p_method), false);
|
||||
ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
|
||||
ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false);
|
||||
|
||||
Variant::CallError error;
|
||||
@ -1079,10 +1121,10 @@ bool Tween::follow_method(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_method;
|
||||
data.initial_val = p_initial_val;
|
||||
data.target = p_target->get_path();
|
||||
data.target_id = p_target->get_instance_ID();
|
||||
data.target_key = p_target_method;
|
||||
data.times_in_sec = p_times_in_sec;
|
||||
data.trans_type = p_trans_type;
|
||||
@ -1093,9 +1135,9 @@ bool Tween::follow_method(Node *p_node
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tween::targeting_property(Node *p_node
|
||||
bool Tween::targeting_property(Object *p_object
|
||||
, String p_property
|
||||
, Node *p_initial
|
||||
, Object *p_initial
|
||||
, String p_initial_property
|
||||
, Variant p_final_val
|
||||
, real_t p_times_in_sec
|
||||
@ -1103,10 +1145,11 @@ bool Tween::targeting_property(Node *p_node
|
||||
, EaseType p_ease_type
|
||||
, real_t p_delay
|
||||
) {
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
// convert INT to REAL is better for interpolaters
|
||||
if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_initial == NULL, false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec <= 0, false);
|
||||
ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
|
||||
@ -1114,7 +1157,7 @@ bool Tween::targeting_property(Node *p_node
|
||||
ERR_FAIL_COND_V(p_delay < 0, false);
|
||||
|
||||
bool prop_valid = false;
|
||||
p_node->get(p_property,&prop_valid);
|
||||
p_object->get(p_property,&prop_valid);
|
||||
ERR_FAIL_COND_V(!prop_valid, false);
|
||||
|
||||
bool initial_prop_valid = false;
|
||||
@ -1131,9 +1174,9 @@ bool Tween::targeting_property(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_property;
|
||||
data.target = p_initial->get_path();
|
||||
data.target_id = p_initial->get_instance_ID();
|
||||
data.target_key = p_initial_property;
|
||||
data.initial_val = initial_val;
|
||||
data.final_val = p_final_val;
|
||||
@ -1150,9 +1193,9 @@ bool Tween::targeting_property(Node *p_node
|
||||
}
|
||||
|
||||
|
||||
bool Tween::targeting_method(Node *p_node
|
||||
bool Tween::targeting_method(Object *p_object
|
||||
, String p_method
|
||||
, Node *p_initial
|
||||
, Object *p_initial
|
||||
, String p_initial_method
|
||||
, Variant p_final_val
|
||||
, real_t p_times_in_sec
|
||||
@ -1160,17 +1203,18 @@ bool Tween::targeting_method(Node *p_node
|
||||
, EaseType p_ease_type
|
||||
, real_t p_delay
|
||||
) {
|
||||
ERR_FAIL_COND_V(pending_update != 0, false);
|
||||
// convert INT to REAL is better for interpolaters
|
||||
if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
|
||||
|
||||
ERR_FAIL_COND_V(p_node == NULL, false);
|
||||
ERR_FAIL_COND_V(p_object == NULL, false);
|
||||
ERR_FAIL_COND_V(p_initial == NULL, false);
|
||||
ERR_FAIL_COND_V(p_times_in_sec <= 0, false);
|
||||
ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
|
||||
ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
|
||||
ERR_FAIL_COND_V(p_delay < 0, false);
|
||||
|
||||
ERR_FAIL_COND_V(!p_node->has_method(p_method), false);
|
||||
ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
|
||||
ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false);
|
||||
|
||||
Variant::CallError error;
|
||||
@ -1187,9 +1231,9 @@ bool Tween::targeting_method(Node *p_node
|
||||
data.finish = false;
|
||||
data.elapsed = 0;
|
||||
|
||||
data.path = p_node->get_path();
|
||||
data.id = p_object->get_instance_ID();
|
||||
data.key = p_method;
|
||||
data.target = p_initial->get_path();
|
||||
data.target_id = p_initial->get_instance_ID();
|
||||
data.target_key = p_initial_method;
|
||||
data.initial_val = initial_val;
|
||||
data.final_val = p_final_val;
|
||||
@ -1213,6 +1257,7 @@ Tween::Tween() {
|
||||
active=false;
|
||||
repeat=false;
|
||||
speed_scale=1;
|
||||
pending_update=0;
|
||||
}
|
||||
|
||||
Tween::~Tween() {
|
||||
|
@ -54,15 +54,17 @@ public:
|
||||
TRANS_CIRC,
|
||||
TRANS_BOUNCE,
|
||||
TRANS_BACK,
|
||||
TRANS_COUNT,
|
||||
|
||||
TRANS_COUNT,
|
||||
};
|
||||
|
||||
enum EaseType {
|
||||
EASE_IN,
|
||||
EASE_OUT,
|
||||
EASE_IN_OUT,
|
||||
EASE_OUT_IN,
|
||||
EASE_COUNT,
|
||||
EASE_OUT_IN,
|
||||
|
||||
EASE_COUNT,
|
||||
};
|
||||
|
||||
private:
|
||||
@ -82,12 +84,12 @@ private:
|
||||
InterpolateType type;
|
||||
bool finish;
|
||||
real_t elapsed;
|
||||
NodePath path;
|
||||
ObjectID id;
|
||||
StringName key;
|
||||
Variant initial_val;
|
||||
Variant delta_val;
|
||||
Variant final_val;
|
||||
NodePath target;
|
||||
ObjectID target_id;
|
||||
StringName target_key;
|
||||
real_t times_in_sec;
|
||||
TransitionType trans_type;
|
||||
@ -102,6 +104,7 @@ private:
|
||||
bool active;
|
||||
bool repeat;
|
||||
float speed_scale;
|
||||
mutable int pending_update;
|
||||
|
||||
List<InterpolateData> interpolates;
|
||||
|
||||
@ -142,20 +145,20 @@ public:
|
||||
float get_speed() const;
|
||||
|
||||
bool start();
|
||||
bool reset(Node *p_node, String p_key);
|
||||
bool reset(Object *p_node, String p_key);
|
||||
bool reset_all();
|
||||
bool stop(Node *p_node, String p_key);
|
||||
bool stop(Object *p_node, String p_key);
|
||||
bool stop_all();
|
||||
bool resume(Node *p_node, String p_key);
|
||||
bool resume(Object *p_node, String p_key);
|
||||
bool resume_all();
|
||||
bool remove(Node *p_node, String p_key);
|
||||
bool remove(Object *p_node, String p_key);
|
||||
bool remove_all();
|
||||
|
||||
bool seek(real_t p_time);
|
||||
real_t tell() const;
|
||||
real_t get_runtime() const;
|
||||
|
||||
bool interpolate_property(Node *p_node
|
||||
bool interpolate_property(Object *p_node
|
||||
, String p_property
|
||||
, Variant p_initial_val
|
||||
, Variant p_final_val
|
||||
@ -165,7 +168,7 @@ public:
|
||||
, real_t p_delay = 0
|
||||
);
|
||||
|
||||
bool interpolate_method(Node *p_node
|
||||
bool interpolate_method(Object *p_node
|
||||
, String p_method
|
||||
, Variant p_initial_val
|
||||
, Variant p_final_val
|
||||
@ -175,16 +178,16 @@ public:
|
||||
, real_t p_delay = 0
|
||||
);
|
||||
|
||||
bool interpolate_callback(Node *p_node
|
||||
, String p_callback
|
||||
bool interpolate_callback(Object *p_node
|
||||
, real_t p_times_in_sec
|
||||
, String p_callback
|
||||
, Variant p_arg = Variant()
|
||||
);
|
||||
|
||||
bool follow_property(Node *p_node
|
||||
bool follow_property(Object *p_node
|
||||
, String p_property
|
||||
, Variant p_initial_val
|
||||
, Node *p_target
|
||||
, Object *p_target
|
||||
, String p_target_property
|
||||
, real_t p_times_in_sec
|
||||
, TransitionType p_trans_type
|
||||
@ -192,10 +195,10 @@ public:
|
||||
, real_t p_delay = 0
|
||||
);
|
||||
|
||||
bool follow_method(Node *p_node
|
||||
bool follow_method(Object *p_node
|
||||
, String p_method
|
||||
, Variant p_initial_val
|
||||
, Node *p_target
|
||||
, Object *p_target
|
||||
, String p_target_method
|
||||
, real_t p_times_in_sec
|
||||
, TransitionType p_trans_type
|
||||
@ -203,9 +206,9 @@ public:
|
||||
, real_t p_delay = 0
|
||||
);
|
||||
|
||||
bool targeting_property(Node *p_node
|
||||
bool targeting_property(Object *p_node
|
||||
, String p_property
|
||||
, Node *p_initial
|
||||
, Object *p_initial
|
||||
, String p_initial_property
|
||||
, Variant p_final_val
|
||||
, real_t p_times_in_sec
|
||||
@ -214,9 +217,9 @@ public:
|
||||
, real_t p_delay = 0
|
||||
);
|
||||
|
||||
bool targeting_method(Node *p_node
|
||||
bool targeting_method(Object *p_node
|
||||
, String p_method
|
||||
, Node *p_initial
|
||||
, Object *p_initial
|
||||
, String p_initial_method
|
||||
, Variant p_final_val
|
||||
, real_t p_times_in_sec
|
||||
|
@ -44,7 +44,7 @@ void BoxContainer::_resort() {
|
||||
|
||||
Size2i new_size=get_size();;
|
||||
|
||||
int sep=get_constant("separation",vertical?"VBoxContainer":"HBoxContainer");
|
||||
int sep=get_constant("separation");//,vertical?"VBoxContainer":"HBoxContainer");
|
||||
|
||||
bool first=true;
|
||||
int children_count=0;
|
||||
@ -202,7 +202,7 @@ Size2 BoxContainer::get_minimum_size() const {
|
||||
/* Calculate MINIMUM SIZE */
|
||||
|
||||
Size2i minimum;
|
||||
int sep=get_constant("separation",vertical?"VBoxContainer":"HBoxContainer");
|
||||
int sep=get_constant("separation");//,vertical?"VBoxContainer":"HBoxContainer");
|
||||
|
||||
bool first=true;
|
||||
|
||||
|
@ -1325,9 +1325,12 @@ Size2 Control::get_minimum_size() const {
|
||||
|
||||
Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
|
||||
if (tex)
|
||||
return *tex;
|
||||
if (p_type==StringName()) {
|
||||
|
||||
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
|
||||
if (tex)
|
||||
return *tex;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
||||
@ -1353,12 +1356,11 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type
|
||||
|
||||
Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
|
||||
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
|
||||
|
||||
|
||||
if (style)
|
||||
return *style;
|
||||
if (p_type==StringName()) {
|
||||
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
|
||||
if (style)
|
||||
return *style;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
||||
@ -1382,9 +1384,11 @@ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p
|
||||
}
|
||||
Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const Ref<Font>* font = data.font_override.getptr(p_name);
|
||||
if (font)
|
||||
return *font;
|
||||
if (p_type==StringName()) {
|
||||
const Ref<Font>* font = data.font_override.getptr(p_name);
|
||||
if (font)
|
||||
return *font;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
||||
@ -1411,9 +1415,11 @@ Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) c
|
||||
}
|
||||
Color Control::get_color(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const Color* color = data.color_override.getptr(p_name);
|
||||
if (color)
|
||||
return *color;
|
||||
if (p_type==StringName()) {
|
||||
const Color* color = data.color_override.getptr(p_name);
|
||||
if (color)
|
||||
return *color;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
// try with custom themes
|
||||
@ -1438,9 +1444,11 @@ Color Control::get_color(const StringName& p_name,const StringName& p_type) cons
|
||||
|
||||
int Control::get_constant(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const int* constant = data.constant_override.getptr(p_name);
|
||||
if (constant)
|
||||
return *constant;
|
||||
if (p_type==StringName()) {
|
||||
const int* constant = data.constant_override.getptr(p_name);
|
||||
if (constant)
|
||||
return *constant;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
// try with custom themes
|
||||
@ -1467,9 +1475,11 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
|
||||
|
||||
bool Control::has_icon(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
|
||||
if (tex)
|
||||
return true;
|
||||
if (p_type==StringName()) {
|
||||
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
|
||||
if (tex)
|
||||
return true;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
||||
@ -1494,11 +1504,12 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const
|
||||
}
|
||||
bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
if (p_type==StringName()) {
|
||||
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
|
||||
|
||||
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
|
||||
|
||||
if (style)
|
||||
return true;
|
||||
if (style)
|
||||
return true;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
||||
@ -1523,9 +1534,11 @@ bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) co
|
||||
}
|
||||
bool Control::has_font(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const Ref<Font>* font = data.font_override.getptr(p_name);
|
||||
if (font)
|
||||
return true;
|
||||
if (p_type==StringName()) {
|
||||
const Ref<Font>* font = data.font_override.getptr(p_name);
|
||||
if (font)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
@ -1551,9 +1564,11 @@ bool Control::has_font(const StringName& p_name,const StringName& p_type) const
|
||||
}
|
||||
bool Control::has_color(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const Color* color = data.color_override.getptr(p_name);
|
||||
if (color)
|
||||
return true;
|
||||
if (p_type==StringName()) {
|
||||
const Color* color = data.color_override.getptr(p_name);
|
||||
if (color)
|
||||
return true;
|
||||
}
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
||||
@ -1579,9 +1594,12 @@ bool Control::has_color(const StringName& p_name,const StringName& p_type) const
|
||||
|
||||
bool Control::has_constant(const StringName& p_name,const StringName& p_type) const {
|
||||
|
||||
const int* constant = data.constant_override.getptr(p_name);
|
||||
if (constant)
|
||||
return true;
|
||||
if (p_type==StringName()) {
|
||||
|
||||
const int* constant = data.constant_override.getptr(p_name);
|
||||
if (constant)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
StringName type = p_type?p_type:get_type_name();
|
||||
|
320
scene/gui/graph_node.cpp
Normal file
320
scene/gui/graph_node.cpp
Normal file
@ -0,0 +1,320 @@
|
||||
#include "graph_node.h"
|
||||
|
||||
|
||||
bool GraphNode::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
if (!p_name.operator String().begins_with("slot/"))
|
||||
return false;
|
||||
|
||||
int idx=p_name.operator String().get_slice("/",1).to_int();
|
||||
String what = p_name.operator String().get_slice("/",2);
|
||||
|
||||
|
||||
Slot si;
|
||||
if (slot_info.has(idx))
|
||||
si=slot_info[idx];
|
||||
|
||||
|
||||
if (what=="left_enabled")
|
||||
si.enable_left=p_value;
|
||||
else if (what=="left_type")
|
||||
si.type_left=p_value;
|
||||
else if (what=="left_color")
|
||||
si.color_left=p_value;
|
||||
else if (what=="right_enabled")
|
||||
si.enable_right=p_value;
|
||||
else if (what=="right_type")
|
||||
si.type_right=p_value;
|
||||
else if (what=="right_color")
|
||||
si.color_right=p_value;
|
||||
else
|
||||
return false;
|
||||
|
||||
set_slot(idx,si.enable_left,si.type_left,si.color_left,si.enable_right,si.type_right,si.color_right);
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GraphNode::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
|
||||
|
||||
print_line("get "+p_name.operator String());
|
||||
if (!p_name.operator String().begins_with("slot/")) {
|
||||
print_line("no begins");
|
||||
return false;
|
||||
}
|
||||
|
||||
int idx=p_name.operator String().get_slice("/",1).to_int();
|
||||
String what = p_name.operator String().get_slice("/",2);
|
||||
|
||||
|
||||
|
||||
Slot si;
|
||||
if (slot_info.has(idx))
|
||||
si=slot_info[idx];
|
||||
|
||||
if (what=="left_enabled")
|
||||
r_ret=si.enable_left;
|
||||
else if (what=="left_type")
|
||||
r_ret=si.type_left;
|
||||
else if (what=="left_color")
|
||||
r_ret=si.color_left;
|
||||
else if (what=="right_enabled")
|
||||
r_ret=si.enable_right;
|
||||
else if (what=="right_type")
|
||||
r_ret=si.type_right;
|
||||
else if (what=="right_color")
|
||||
r_ret=si.color_right;
|
||||
else
|
||||
return false;
|
||||
|
||||
print_line("ask for: "+p_name.operator String()+" get: "+String(r_ret));
|
||||
return true;
|
||||
}
|
||||
void GraphNode::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
int idx=0;
|
||||
for(int i=0;i<get_child_count();i++) {
|
||||
Control *c=get_child(i)->cast_to<Control>();
|
||||
if (!c || c->is_set_as_toplevel() || !c->get_owner())
|
||||
continue;
|
||||
|
||||
String base="slot/"+itos(idx)+"/";
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL,base+"left_enabled"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT,base+"left_type"));
|
||||
p_list->push_back(PropertyInfo(Variant::COLOR,base+"left_color"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL,base+"right_enabled"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT,base+"right_type"));
|
||||
p_list->push_back(PropertyInfo(Variant::COLOR,base+"right_color"));
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GraphNode::_resort() {
|
||||
|
||||
|
||||
|
||||
int sep=get_constant("separation");
|
||||
Ref<StyleBox> sb=get_stylebox("frame");
|
||||
bool first=true;
|
||||
|
||||
Size2 minsize;
|
||||
|
||||
for(int i=0;i<get_child_count();i++) {
|
||||
Control *c=get_child(i)->cast_to<Control>();
|
||||
if (!c)
|
||||
continue;
|
||||
if (c->is_set_as_toplevel())
|
||||
continue;
|
||||
|
||||
Size2i size=c->get_combined_minimum_size();
|
||||
|
||||
minsize.y+=size.y;
|
||||
minsize.x=MAX(minsize.x,size.x);
|
||||
|
||||
if (first)
|
||||
first=false;
|
||||
else
|
||||
minsize.y+=sep;
|
||||
|
||||
}
|
||||
|
||||
int vofs=0;
|
||||
int w = get_size().x - sb->get_minimum_size().x;
|
||||
|
||||
|
||||
cache_y.clear();
|
||||
for(int i=0;i<get_child_count();i++) {
|
||||
Control *c=get_child(i)->cast_to<Control>();
|
||||
if (!c)
|
||||
continue;
|
||||
if (c->is_set_as_toplevel() || !c->get_owner())
|
||||
continue;
|
||||
|
||||
Size2i size=c->get_combined_minimum_size();
|
||||
|
||||
Rect2 r(sb->get_margin(MARGIN_LEFT),sb->get_margin(MARGIN_TOP)+vofs,w,size.y);
|
||||
|
||||
fit_child_in_rect(c,r);
|
||||
cache_y.push_back(vofs+size.y*0.5);
|
||||
|
||||
if (vofs>0)
|
||||
vofs+=sep;
|
||||
vofs+=size.y;
|
||||
|
||||
|
||||
}
|
||||
|
||||
_change_notify();
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GraphNode::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_DRAW) {
|
||||
|
||||
Ref<StyleBox> sb=get_stylebox("frame");
|
||||
Ref<Texture> port =get_icon("port");
|
||||
Point2i icofs = -port->get_size()*0.5;
|
||||
int edgeofs=3;
|
||||
icofs.y+=sb->get_margin(MARGIN_TOP);
|
||||
draw_style_box(sb,Rect2(Point2(),get_size()));
|
||||
|
||||
for (Map<int,Slot>::Element *E=slot_info.front();E;E=E->next()) {
|
||||
|
||||
if (E->key()>cache_y.size())
|
||||
continue;
|
||||
if (!slot_info.has(E->key()))
|
||||
continue;
|
||||
const Slot &s=slot_info[E->key()];
|
||||
//left
|
||||
if (s.enable_left)
|
||||
port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left);
|
||||
if (s.enable_right)
|
||||
port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right);
|
||||
|
||||
}
|
||||
}
|
||||
if (p_what==NOTIFICATION_SORT_CHILDREN) {
|
||||
|
||||
_resort();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GraphNode::set_title(const String& p_title) {
|
||||
|
||||
title=p_title;
|
||||
update();
|
||||
}
|
||||
|
||||
String GraphNode::get_title() const {
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
void GraphNode::set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right) {
|
||||
|
||||
ERR_FAIL_COND(p_idx<0);
|
||||
|
||||
if (!p_enable_left && p_type_left==0 && p_color_left==Color(1,1,1,1) && !p_enable_right && p_type_right==0 && p_color_right==Color(1,1,1,1)) {
|
||||
slot_info.erase(p_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
Slot s;
|
||||
s.enable_left=p_enable_left;
|
||||
s.type_left=p_type_left;
|
||||
s.color_left=p_color_left;
|
||||
s.enable_right=p_enable_right;
|
||||
s.type_right=p_type_right;
|
||||
s.color_right=p_color_right;
|
||||
slot_info[p_idx]=s;
|
||||
update();
|
||||
}
|
||||
|
||||
void GraphNode::clear_slot(int p_idx){
|
||||
|
||||
slot_info.erase(p_idx);
|
||||
update();
|
||||
}
|
||||
void GraphNode::clear_all_slots(){
|
||||
|
||||
slot_info.clear();
|
||||
update();
|
||||
}
|
||||
bool GraphNode::is_slot_enabled_left(int p_idx) const{
|
||||
|
||||
if (!slot_info.has(p_idx))
|
||||
return false;
|
||||
return slot_info[p_idx].enable_left;
|
||||
|
||||
}
|
||||
|
||||
int GraphNode::get_slot_type_left(int p_idx) const{
|
||||
|
||||
if (!slot_info.has(p_idx))
|
||||
return 0;
|
||||
return slot_info[p_idx].type_left;
|
||||
|
||||
}
|
||||
|
||||
Color GraphNode::get_slot_color_left(int p_idx) const{
|
||||
|
||||
if (!slot_info.has(p_idx))
|
||||
return Color(1,1,1,1);
|
||||
return slot_info[p_idx].color_left;
|
||||
|
||||
}
|
||||
|
||||
bool GraphNode::is_slot_enabled_right(int p_idx) const{
|
||||
|
||||
if (!slot_info.has(p_idx))
|
||||
return false;
|
||||
return slot_info[p_idx].enable_right;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GraphNode::get_slot_type_right(int p_idx) const{
|
||||
|
||||
if (!slot_info.has(p_idx))
|
||||
return 0;
|
||||
return slot_info[p_idx].type_right;
|
||||
|
||||
}
|
||||
|
||||
Color GraphNode::get_slot_color_right(int p_idx) const{
|
||||
|
||||
if (!slot_info.has(p_idx))
|
||||
return Color(1,1,1,1);
|
||||
return slot_info[p_idx].color_right;
|
||||
|
||||
}
|
||||
|
||||
Size2 GraphNode::get_minimum_size() const {
|
||||
|
||||
int sep=get_constant("separation");
|
||||
Ref<StyleBox> sb=get_stylebox("frame");
|
||||
bool first=true;
|
||||
|
||||
Size2 minsize;
|
||||
|
||||
for(int i=0;i<get_child_count();i++) {
|
||||
|
||||
Control *c=get_child(i)->cast_to<Control>();
|
||||
if (!c)
|
||||
continue;
|
||||
if (c->is_set_as_toplevel() || !c->get_owner())
|
||||
continue;
|
||||
|
||||
Size2i size=c->get_combined_minimum_size();
|
||||
|
||||
minsize.y+=size.y;
|
||||
minsize.x=MAX(minsize.x,size.x);
|
||||
|
||||
if (first)
|
||||
first=false;
|
||||
else
|
||||
minsize.y+=sep;
|
||||
}
|
||||
|
||||
return minsize+sb->get_minimum_size();
|
||||
}
|
||||
|
||||
|
||||
void GraphNode::_bind_methods() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
GraphNode::GraphNode() {
|
||||
|
||||
|
||||
}
|
61
scene/gui/graph_node.h
Normal file
61
scene/gui/graph_node.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef GRAPH_NODE_H
|
||||
#define GRAPH_NODE_H
|
||||
|
||||
#include "scene/gui/container.h"
|
||||
|
||||
class GraphNode : public Container {
|
||||
|
||||
OBJ_TYPE(GraphNode,Container);
|
||||
|
||||
|
||||
String title;
|
||||
struct Slot {
|
||||
bool enable_left;
|
||||
int type_left;
|
||||
Color color_left;
|
||||
bool enable_right;
|
||||
int type_right;
|
||||
Color color_right;
|
||||
|
||||
|
||||
Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); };
|
||||
};
|
||||
|
||||
Vector<int> cache_y;
|
||||
|
||||
Map<int,Slot> slot_info;
|
||||
|
||||
void _resort();
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
void set_title(const String& p_title);
|
||||
String get_title() const;
|
||||
|
||||
void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right);
|
||||
void clear_slot(int p_idx);
|
||||
void clear_all_slots();
|
||||
bool is_slot_enabled_left(int p_idx) const;
|
||||
int get_slot_type_left(int p_idx) const;
|
||||
Color get_slot_color_left(int p_idx) const;
|
||||
bool is_slot_enabled_right(int p_idx) const;
|
||||
int get_slot_type_right(int p_idx) const;
|
||||
Color get_slot_color_right(int p_idx) const;
|
||||
|
||||
virtual Size2 get_minimum_size() const;
|
||||
|
||||
GraphNode();
|
||||
};
|
||||
|
||||
|
||||
#endif // GRAPH_NODE_H
|
File diff suppressed because it is too large
Load Diff
@ -79,6 +79,7 @@ class TextEdit : public Control {
|
||||
Color mark_color;
|
||||
Color breakpoint_color;
|
||||
Color current_line_color;
|
||||
Color brace_mismatch_color;
|
||||
|
||||
int row_height;
|
||||
int line_spacing;
|
||||
@ -185,6 +186,8 @@ class TextEdit : public Control {
|
||||
int completion_index;
|
||||
Rect2i completion_rect;
|
||||
int completion_line_ofs;
|
||||
String completion_hint;
|
||||
int completion_hint_offset;
|
||||
|
||||
bool setting_text;
|
||||
|
||||
@ -208,6 +211,7 @@ class TextEdit : public Control {
|
||||
bool line_numbers;
|
||||
|
||||
bool auto_brace_completion_enabled;
|
||||
bool brace_matching_enabled;
|
||||
bool cut_copy_line;
|
||||
|
||||
uint64_t last_dblclk;
|
||||
@ -261,6 +265,7 @@ class TextEdit : public Control {
|
||||
|
||||
void _clear();
|
||||
void _cancel_completion();
|
||||
void _cancel_code_hint();
|
||||
void _confirm_completion();
|
||||
void _update_completion_candidates();
|
||||
|
||||
@ -313,6 +318,10 @@ public:
|
||||
inline void set_auto_brace_completion(bool p_enabled) {
|
||||
auto_brace_completion_enabled = p_enabled;
|
||||
}
|
||||
inline void set_brace_matching(bool p_enabled) {
|
||||
brace_matching_enabled=p_enabled;
|
||||
update();
|
||||
}
|
||||
|
||||
void cursor_set_column(int p_col);
|
||||
void cursor_set_line(int p_row);
|
||||
@ -350,7 +359,7 @@ public:
|
||||
|
||||
void undo();
|
||||
void redo();
|
||||
void clear_undo_history();
|
||||
void clear_undo_history();
|
||||
|
||||
|
||||
void set_draw_tabs(bool p_draw);
|
||||
@ -378,8 +387,11 @@ public:
|
||||
|
||||
void set_completion(bool p_enabled,const Vector<String>& p_prefixes);
|
||||
void code_complete(const Vector<String> &p_strings);
|
||||
void set_code_hint(const String& p_hint);
|
||||
void query_code_comple();
|
||||
|
||||
String get_text_for_completion();
|
||||
|
||||
TextEdit();
|
||||
~TextEdit();
|
||||
};
|
||||
|
@ -1731,6 +1731,26 @@ NodePath Node::get_import_path() const {
|
||||
|
||||
#endif
|
||||
|
||||
static void _add_nodes_to_options(const Node *p_base,const Node *p_node,List<String>*r_options) {
|
||||
|
||||
if (p_node!=p_base && !p_node->get_owner())
|
||||
return;
|
||||
String n = p_base->get_path_to(p_node);
|
||||
r_options->push_back("\""+n+"\"");
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
_add_nodes_to_options(p_base,p_node->get_child(i),r_options);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
String pf=p_function;
|
||||
if ((pf=="has_node" || pf=="get_node") && p_idx==0) {
|
||||
|
||||
_add_nodes_to_options(this,this,r_options);
|
||||
}
|
||||
Object::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
void Node::_bind_methods() {
|
||||
|
||||
|
@ -284,6 +284,7 @@ public:
|
||||
NodePath get_import_path() const;
|
||||
#endif
|
||||
|
||||
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
_FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; }
|
||||
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "scene/gui/split_container.h"
|
||||
#include "scene/gui/video_player.h"
|
||||
#include "scene/gui/reference_frame.h"
|
||||
#include "scene/gui/graph_node.h"
|
||||
#include "scene/resources/video_stream.h"
|
||||
#include "scene/2d/particles_2d.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
@ -303,6 +304,7 @@ void register_scene_types() {
|
||||
ObjectTypeDB::register_virtual_type<SplitContainer>();
|
||||
ObjectTypeDB::register_type<HSplitContainer>();
|
||||
ObjectTypeDB::register_type<VSplitContainer>();
|
||||
ObjectTypeDB::register_type<GraphNode>();
|
||||
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
|
@ -38,15 +38,18 @@ int AudioStreamResampled::get_channel_count() const {
|
||||
|
||||
|
||||
template<int C>
|
||||
void AudioStreamResampled::_resample(int32_t *p_dest,int p_todo,int32_t p_increment) {
|
||||
uint32_t AudioStreamResampled::_resample(int32_t *p_dest,int p_todo,int32_t p_increment) {
|
||||
|
||||
uint32_t read=offset&MIX_FRAC_MASK;
|
||||
|
||||
for (int i=0;i<p_todo;i++) {
|
||||
|
||||
offset = (offset + p_increment)&(((1<<(rb_bits+MIX_FRAC_BITS))-1));
|
||||
read+=p_increment;
|
||||
uint32_t pos = offset >> MIX_FRAC_BITS;
|
||||
uint32_t frac = offset & MIX_FRAC_MASK;
|
||||
#ifndef FAST_AUDIO
|
||||
ERR_FAIL_COND(pos>=rb_len);
|
||||
ERR_FAIL_COND_V(pos>=rb_len,0);
|
||||
#endif
|
||||
uint32_t pos_next = (pos+1)&rb_mask;
|
||||
//printf("rb pos %i\n",pos);
|
||||
@ -151,7 +154,7 @@ void AudioStreamResampled::_resample(int32_t *p_dest,int p_todo,int32_t p_increm
|
||||
}
|
||||
|
||||
|
||||
rb_read_pos=offset>>MIX_FRAC_BITS;
|
||||
return read>>MIX_FRAC_BITS;//rb_read_pos=offset>>MIX_FRAC_BITS;
|
||||
|
||||
}
|
||||
|
||||
@ -173,10 +176,10 @@ bool AudioStreamResampled::mix(int32_t *p_dest, int p_frames) {
|
||||
|
||||
} else if (rb_read_pos<write_pos_cache) {
|
||||
|
||||
rb_todo=write_pos_cache-rb_read_pos-1;
|
||||
rb_todo=write_pos_cache-rb_read_pos; //-1?
|
||||
} else {
|
||||
|
||||
rb_todo=(rb_len-rb_read_pos)+write_pos_cache-1;
|
||||
rb_todo=(rb_len-rb_read_pos)+write_pos_cache; //-1?
|
||||
}
|
||||
|
||||
int todo = MIN( ((int64_t(rb_todo)<<MIX_FRAC_BITS)/increment)+1, p_frames );
|
||||
@ -220,13 +223,22 @@ bool AudioStreamResampled::mix(int32_t *p_dest, int p_frames) {
|
||||
#endif
|
||||
{
|
||||
|
||||
uint32_t read=0;
|
||||
switch(channels) {
|
||||
case 1: _resample<1>(p_dest,todo,increment); break;
|
||||
case 2: _resample<2>(p_dest,todo,increment); break;
|
||||
case 4: _resample<4>(p_dest,todo,increment); break;
|
||||
case 6: _resample<6>(p_dest,todo,increment); break;
|
||||
case 1: read=_resample<1>(p_dest,todo,increment); break;
|
||||
case 2: read=_resample<2>(p_dest,todo,increment); break;
|
||||
case 4: read=_resample<4>(p_dest,todo,increment); break;
|
||||
case 6: read=_resample<6>(p_dest,todo,increment); break;
|
||||
}
|
||||
|
||||
if (read>rb_todo)
|
||||
read=rb_todo;
|
||||
|
||||
rb_read_pos = (rb_read_pos+read)&rb_mask;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -57,7 +57,7 @@ class AudioStreamResampled : public AudioStream {
|
||||
|
||||
|
||||
template<int C>
|
||||
void _resample(int32_t *p_dest,int p_todo,int32_t p_increment);
|
||||
uint32_t _resample(int32_t *p_dest,int p_todo,int32_t p_increment);
|
||||
|
||||
|
||||
protected:
|
||||
@ -97,7 +97,7 @@ protected:
|
||||
_FORCE_INLINE_ int16_t *get_write_buffer() { return read_buf; }
|
||||
_FORCE_INLINE_ void write(uint32_t p_frames) {
|
||||
|
||||
ERR_FAIL_COND(p_frames > rb_len);
|
||||
ERR_FAIL_COND(p_frames >= rb_len);
|
||||
|
||||
switch(channels) {
|
||||
case 1: {
|
||||
|
@ -65,7 +65,7 @@ static Ref<Texture> make_icon(T p_src) {
|
||||
|
||||
|
||||
Ref<ImageTexture> texture( memnew( ImageTexture ) );
|
||||
texture->create_from_image( Image(p_src) );
|
||||
texture->create_from_image( Image(p_src),ImageTexture::FLAG_FILTER );
|
||||
|
||||
return texture;
|
||||
}
|
||||
@ -331,6 +331,7 @@ void make_default_theme() {
|
||||
t->set_color("current_line_color","TextEdit", Color(0.3,0.5,0.8,0.15) );
|
||||
t->set_color("cursor_color","TextEdit", control_font_color );
|
||||
t->set_color("symbol_color","TextEdit", control_font_color_hover );
|
||||
t->set_color("brace_mismatch_color","TextEdit", Color(1,0.2,0.2) );
|
||||
t->set_constant("line_spacing","TextEdit",1 );
|
||||
|
||||
t->set_stylebox("scroll","HScrollBar", make_stylebox( hscroll_bg_png,3,3,3,3,0,0,0,0) );
|
||||
@ -416,6 +417,14 @@ void make_default_theme() {
|
||||
t->set_constant("hseparation","PopupMenu",2);
|
||||
t->set_constant("vseparation","PopupMenu",1);
|
||||
|
||||
Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png,6,21,6,5,16,21,16,5);
|
||||
//graphsb->set_expand_margin_size(MARGIN_LEFT,10);
|
||||
//graphsb->set_expand_margin_size(MARGIN_RIGHT,10);
|
||||
t->set_stylebox("frame","GraphNode", graphsb );
|
||||
t->set_constant("separation","GraphNode", 1 );
|
||||
t->set_icon("port","GraphNode", make_icon( graph_port_png ) );
|
||||
|
||||
|
||||
t->set_stylebox("bg","Tree", make_stylebox( tree_bg_png,4,4,4,5,3,3,3,3) );
|
||||
t->set_stylebox("bg_focus","Tree", focus );
|
||||
Ref<StyleBoxTexture> tree_selected = make_stylebox( selection_png,4,4,4,4);
|
||||
|
BIN
scene/resources/default_theme/graph_node.png
Normal file
BIN
scene/resources/default_theme/graph_node.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 770 B |
BIN
scene/resources/default_theme/graph_port.png
Normal file
BIN
scene/resources/default_theme/graph_port.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 509 B |
@ -99,6 +99,16 @@ static const unsigned char full_panel_bg_png[]={
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char graph_node_png[]={
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x40,0x8,0x6,0x0,0x0,0x0,0x13,0x7d,0xf7,0x96,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0xc,0x14,0x10,0x3,0x2e,0x15,0xb6,0x7,0x4a,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x2,0x6a,0x49,0x44,0x41,0x54,0x58,0xc3,0xed,0x97,0xbb,0x6e,0x13,0x51,0x10,0x86,0xbf,0xf1,0x2e,0xb1,0x83,0x85,0x63,0x5,0x10,0xe2,0x22,0xa5,0x0,0x1a,0x24,0x90,0x22,0x9e,0x81,0x2,0xd1,0x53,0xf1,0x2,0x20,0xa,0x1a,0xa,0xa0,0x44,0xd0,0xd0,0x20,0x81,0xe0,0x5,0xa8,0xe8,0x11,0x5,0xcf,0x80,0x22,0x81,0x42,0x3,0x14,0x91,0xb8,0x4,0x85,0x58,0x8e,0x21,0x78,0xd7,0xd9,0x73,0x86,0xe2,0x9c,0xdd,0xec,0xae,0xd7,0xce,0x85,0xe,0xed,0x34,0xbb,0x3a,0x3e,0xf3,0xcd,0xcc,0x3f,0x63,0x69,0x47,0xd8,0x36,0x1,0x1a,0x40,0xe0,0x9f,0x42,0xd1,0x14,0xb0,0x80,0xf1,0x4f,0x25,0x77,0xa9,0x1,0x1c,0x4,0xe6,0x81,0xa3,0x40,0x7,0x38,0x50,0x2,0x6c,0x1,0x3,0x60,0xd,0xe8,0x1,0x7f,0x0,0x9b,0x46,0x6d,0x3,0x67,0xe6,0xe,0x75,0xaf,0xb7,0x9a,0xad,0xcb,0x33,0x33,0xcd,0x53,0x54,0xd8,0x68,0x14,0x7f,0x89,0xe2,0xe8,0xf5,0xc6,0xaf,0xfe,0x73,0xe0,0x13,0xb0,0x29,0x3e,0xd2,0xc2,0x7c,0xf7,0xf0,0xe3,0xd3,0xb,0x67,0xaf,0x3c,0xb8,0xfb,0x88,0xd9,0x4e,0xab,0xca,0x9f,0xe1,0x20,0xe2,0xde,0xc3,0xdb,0x7c,0x5e,0xf9,0xf8,0xaa,0xd7,0x5f,0xbf,0x5,0xac,0x8,0xd0,0x2,0x16,0x8f,0x1f,0x3b,0xf9,0xe6,0xc5,0xb3,0x97,0xed,0x24,0xb1,0x24,0xa3,0xa4,0x12,0x10,0xce,0x84,0x84,0x61,0x83,0x6b,0x37,0xae,0x6e,0x7e,0xff,0xf1,0xf5,0x12,0xb0,0x14,0x7a,0x1d,0xda,0x61,0x10,0xb6,0x87,0xbf,0x63,0x10,0x75,0x47,0xa,0x2a,0x79,0x85,0x95,0x51,0xbc,0xc5,0x28,0x86,0x30,0x8,0xdb,0xbe,0x6c,0x49,0x1,0x1,0x80,0x51,0xeb,0xfc,0x9d,0xc0,0x4e,0x6b,0xf,0xd1,0xfc,0xb9,0xb3,0x20,0x5,0x68,0xfa,0x8b,0x5a,0x8b,0xaa,0x80,0x28,0x82,0xa0,0x28,0xa2,0x92,0x73,0xd3,0xb1,0xde,0x86,0x85,0x46,0x5b,0x45,0x51,0x50,0x45,0xc4,0x95,0x61,0x53,0x27,0x71,0x61,0x74,0x1a,0xc0,0xaa,0xcd,0x6e,0xa8,0x64,0x2f,0xee,0x5d,0x29,0x8a,0x32,0x39,0x3,0x5f,0xb6,0x2f,0x4c,0x45,0x73,0x5a,0xd8,0x31,0x48,0x1,0x60,0xac,0x2d,0xf1,0x5,0x51,0x75,0x45,0x68,0x5a,0xbf,0x4e,0xcf,0x60,0xfb,0x82,0x2b,0x5a,0x73,0x4e,0xb6,0xe2,0xf,0x52,0x2,0xd8,0x82,0xe2,0x14,0x50,0x54,0xc4,0x2f,0x8b,0x68,0xad,0x1f,0x99,0x54,0x79,0x41,0xdd,0x0,0xf8,0xb6,0x82,0x88,0x4e,0xeb,0x82,0x66,0x89,0xaa,0x3b,0xc8,0x52,0x48,0x41,0x56,0x76,0xcc,0x60,0x7b,0x74,0x75,0xac,0x1a,0x49,0x47,0x72,0x72,0x6,0xe2,0xe7,0x56,0x45,0xfd,0x5d,0xc9,0x44,0x28,0x40,0x2b,0x45,0x34,0xea,0x7,0xa8,0x14,0xc9,0x92,0x75,0x64,0x7,0x11,0x8d,0x8f,0x98,0x9b,0x87,0xf2,0xf4,0x4d,0xd5,0x40,0xd5,0xc9,0x97,0xf,0xa3,0x5a,0x74,0x9c,0x36,0x89,0xf7,0x9f,0xdc,0x61,0xaf,0x96,0x1,0x92,0x2d,0xc3,0xe2,0xf9,0x8b,0xbb,0x72,0x5a,0x7a,0xff,0xb6,0x3a,0x83,0x8d,0x41,0x7f,0xcf,0x19,0x34,0xf8,0x47,0xab,0x1,0x35,0xa0,0x6,0xd4,0x80,0x1a,0x50,0x3,0x6a,0xc0,0x7f,0x9,0x90,0x8a,0x4f,0xe0,0x3d,0x67,0x60,0xf7,0xe1,0x6b,0x53,0x80,0x5,0x22,0x63,0x4c,0x6c,0x93,0x5d,0x78,0x25,0x60,0x8c,0x89,0x81,0x8,0xb0,0xd,0xbf,0xca,0xae,0x47,0xf1,0x70,0x79,0xad,0xb7,0xca,0x34,0x88,0x4d,0x60,0xad,0xb7,0x4a,0x14,0xf,0x97,0x81,0x75,0xc0,0xa4,0x9b,0xeb,0x1c,0x70,0xa1,0xd3,0xee,0x3e,0x6d,0x35,0x67,0xcf,0x5,0x41,0x50,0x29,0xae,0x31,0xc6,0x46,0xf1,0xf0,0xc3,0x60,0xb3,0x7f,0x13,0x78,0x7,0x6c,0x48,0x6e,0x85,0xeb,0x0,0x27,0x80,0x23,0x40,0x73,0xc2,0xf2,0x1d,0x3,0x3f,0x81,0x6f,0x7e,0x8f,0x36,0x52,0x12,0x34,0x4c,0xf7,0xc1,0x9,0x55,0xa8,0x2f,0x39,0xd9,0xa7,0xf0,0xe3,0xf6,0x17,0x4c,0x97,0x1d,0x24,0x5b,0x8,0x8b,0x95,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char graph_port_png[]={
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0xa,0x0,0x0,0x0,0xa,0x8,0x6,0x0,0x0,0x0,0x8d,0x32,0xcf,0xbd,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x0,0x0,0x0,0x0,0x0,0xf9,0x43,0xbb,0x7f,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0xc,0x14,0x17,0x20,0x3,0xeb,0x8f,0x3a,0xdb,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x1,0x65,0x49,0x44,0x41,0x54,0x18,0xd3,0x4d,0xd0,0x4f,0x6b,0xda,0x70,0x1c,0x7,0xe0,0xcf,0x37,0x7f,0x7e,0x49,0x66,0xd2,0x64,0x61,0x5,0x61,0x76,0x47,0xf1,0xa4,0x2d,0xdb,0x75,0x5,0x11,0x84,0xb0,0x5e,0xeb,0xd9,0xeb,0xf4,0x6d,0xec,0x2d,0xf8,0x26,0xb6,0x77,0xe0,0x45,0xba,0xa3,0x6c,0xa0,0x3b,0xad,0x39,0xb6,0x36,0x8,0x1b,0x4b,0x32,0xd2,0xc6,0x6c,0x9a,0x4f,0x4f,0x85,0x3e,0x2f,0xe1,0x11,0x0,0x20,0x29,0xd3,0xe9,0xd4,0xda,0x6e,0xb7,0x23,0xdf,0xf7,0xbb,0x0,0x90,0xe7,0xf9,0x8f,0x66,0xb3,0xf9,0x79,0x36,0x9b,0x55,0x22,0x42,0x83,0xa4,0x44,0x51,0xf4,0xea,0xe2,0xe2,0xc3,0xf7,0xf1,0x78,0xdc,0xa,0x82,0x40,0x8,0x20,0xcf,0x32,0x2e,0x97,0xcb,0x4f,0x51,0x14,0xbd,0x25,0xf9,0x5b,0x26,0x93,0x89,0xdd,0xe9,0x74,0xe2,0xf7,0xe7,0xe7,0x27,0x59,0xfa,0x87,0x65,0xb9,0x13,0x0,0xb0,0x1d,0x9b,0xe1,0xcb,0x50,0xbe,0x5e,0x5d,0xdd,0xfe,0xbc,0xbe,0x6e,0x6b,0x49,0x92,0x8c,0x4e,0x7b,0xa7,0xad,0xbf,0x79,0x4e,0xd3,0x54,0x12,0x86,0x21,0xc2,0x30,0x84,0x32,0x95,0xe4,0x79,0xc6,0xde,0xd9,0x59,0x2b,0x49,0xee,0x46,0x86,0xeb,0xba,0x5d,0xfb,0x85,0x23,0x87,0xfd,0x1e,0xb6,0xed,0x40,0xd7,0x35,0x0,0x40,0x7d,0x38,0xa0,0xdc,0xed,0x44,0x37,0x74,0xb8,0xae,0xd7,0x35,0x48,0x62,0xff,0xff,0x1f,0xfc,0x20,0x80,0xae,0xe9,0x78,0x42,0x0,0xca,0xb2,0x90,0x65,0x19,0x58,0xd7,0xd0,0x8a,0xa2,0x58,0xa7,0x69,0x56,0x6b,0xa2,0x51,0x29,0x5,0xcb,0x52,0xb0,0x94,0x5,0x4b,0x29,0x88,0x8,0xd3,0x34,0xad,0x8b,0xfb,0x62,0xad,0xf,0x6,0x83,0xb8,0xaa,0xaa,0xb1,0xe7,0x79,0xbe,0x77,0x74,0x44,0xb7,0xe1,0x89,0x69,0x1a,0x28,0xcb,0x92,0x9b,0xcd,0x46,0x56,0xab,0xd5,0x86,0xe4,0x47,0x21,0x29,0xc3,0xe1,0xf0,0xb8,0xdf,0xef,0x7f,0x6b,0xb7,0xdb,0xaf,0x1b,0x8d,0x86,0x46,0x10,0xf,0xf7,0xf,0x75,0x1c,0xc7,0x77,0x8b,0xc5,0xe2,0xdd,0x7c,0x3e,0xff,0x25,0xcf,0xc3,0x6f,0x6e,0x6f,0x2e,0x1d,0xdb,0xe9,0x9,0x80,0xb2,0x2a,0xd7,0x27,0xad,0x37,0x5f,0x9e,0xc2,0x1f,0x1,0x3a,0xe6,0xa5,0x7b,0xef,0xf2,0xf3,0xcd,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char hscroll_bg_png[]={
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x8,0x8,0x6,0x0,0x0,0x0,0xc4,0xf,0xbe,0x8b,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x49,0x0,0x42,0x0,0x4e,0x4e,0xda,0xb4,0x7e,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdd,0x9,0x1b,0x12,0x30,0x1c,0x3c,0x99,0xa,0x1c,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0x53,0x49,0x44,0x41,0x54,0x18,0xd3,0x7d,0x8f,0xc9,0xd,0x80,0x20,0x0,0xc0,0xca,0x21,0xe8,0x5f,0x12,0x89,0x84,0xfd,0x5c,0x48,0x26,0x34,0x3e,0x74,0x2,0xa2,0xe8,0x2,0x40,0xbf,0xed,0xa7,0xc2,0xbb,0xb0,0x3,0x1b,0x75,0x92,0xf0,0x2e,0x7c,0x46,0x9b,0xaa,0xcd,0x4f,0x46,0x3,0x8c,0x76,0xea,0x7,0x4a,0x29,0x5a,0x68,0x0,0x29,0x65,0x3f,0x30,0x83,0xed,0x6,0xe9,0xbc,0x8e,0xf6,0x45,0x79,0xb,0xc0,0x5c,0xb3,0xeb,0x12,0xef,0x1f,0xc6,0x6f,0x12,0x2,0xa,0xbd,0xc9,0x5d,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
};
|
||||
|
@ -458,6 +458,8 @@ FixedMaterial::~FixedMaterial() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool ShaderMaterial::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
if (p_name==SceneStringNames::get_singleton()->shader_shader) {
|
||||
@ -558,7 +560,21 @@ void ShaderMaterial::_bind_methods() {
|
||||
}
|
||||
|
||||
|
||||
void ShaderMaterial::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
String f = p_function.operator String();
|
||||
if ((f=="get_shader_param" || f=="set_shader_param") && p_idx==0) {
|
||||
|
||||
if (shader.is_valid()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Material::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
ShaderMaterial::ShaderMaterial() :Material(VisualServer::get_singleton()->material_create()){
|
||||
|
||||
|
@ -243,6 +243,7 @@ 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;
|
||||
|
||||
ShaderMaterial();
|
||||
};
|
||||
|
@ -142,6 +142,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector
|
||||
if (d<closest_dist) {
|
||||
ignore_from_edge=E->get();
|
||||
closest_dist=d;
|
||||
closest_point=closest;
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +169,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector
|
||||
if (d<closest_dist) {
|
||||
ignore_to_edge=E->get();
|
||||
closest_dist=d;
|
||||
closest_point=closest;
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,7 +531,7 @@ Vector2 PolygonPathFinder::get_closest_point(const Vector2& p_point) const {
|
||||
|
||||
float d = p_point.distance_squared_to(points[i].pos);
|
||||
if (d<closest_dist) {
|
||||
d=closest_dist;
|
||||
closest_dist=d;
|
||||
closest_idx=i;
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,13 @@ Dictionary Shader::_get_code() {
|
||||
c["vertex_ofs"]=0;
|
||||
c["light"]=ls;
|
||||
c["light_ofs"]=0;
|
||||
Array arr;
|
||||
for(const Map<StringName,Ref<Texture> >::Element *E=default_textures.front();E;E=E->next()) {
|
||||
arr.push_back(E->key());
|
||||
arr.push_back(E->get());
|
||||
}
|
||||
if (arr.size())
|
||||
c["default_tex"]=arr;
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -132,8 +139,41 @@ void Shader::_set_code(const Dictionary& p_string) {
|
||||
light=p_string["light"];
|
||||
|
||||
set_code(p_string["vertex"],p_string["fragment"],light);
|
||||
if (p_string.has("default_tex")) {
|
||||
Array arr=p_string["default_tex"];
|
||||
if ((arr.size()&1)==0) {
|
||||
for(int i=0;i<arr.size();i+=2)
|
||||
set_default_texture_param(arr[i],arr[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::set_default_texture_param(const StringName& p_param,const Ref<Texture>& p_texture) {
|
||||
|
||||
if (p_texture.is_valid())
|
||||
default_textures[p_param]=p_texture;
|
||||
else
|
||||
default_textures.erase(p_param);
|
||||
}
|
||||
|
||||
Ref<Texture> Shader::get_default_texture_param(const StringName& p_param) const{
|
||||
|
||||
if (default_textures.has(p_param))
|
||||
return default_textures[p_param];
|
||||
else
|
||||
return Ref<Texture>();
|
||||
}
|
||||
|
||||
void Shader::get_default_texture_param_list(List<StringName>* r_textures) const{
|
||||
|
||||
for(const Map<StringName,Ref<Texture> >::Element *E=default_textures.front();E;E=E->next()) {
|
||||
|
||||
r_textures->push_back(E->key());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Shader::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_mode","mode"),&Shader::set_mode);
|
||||
@ -144,6 +184,9 @@ void Shader::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_fragment_code"),&Shader::get_fragment_code);
|
||||
ObjectTypeDB::bind_method(_MD("get_light_code"),&Shader::get_light_code);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_default_texture_param","param","texture:Texture"),&Shader::set_default_texture_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_default_texture_param:Texture","param"),&Shader::get_default_texture_param);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("has_param","name"),&Shader::has_param);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_code","code"),&Shader::_set_code);
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include "resource.h"
|
||||
#include "io/resource_loader.h"
|
||||
|
||||
#include "scene/resources/texture.h"
|
||||
class Shader : public Resource {
|
||||
|
||||
OBJ_TYPE(Shader,Resource);
|
||||
@ -48,6 +48,7 @@ class Shader : public Resource {
|
||||
// convertion fast and save memory.
|
||||
mutable bool params_cache_dirty;
|
||||
mutable Map<StringName,StringName> params_cache; //map a shader param to a material param..
|
||||
Map<StringName,Ref<Texture> > default_textures;
|
||||
|
||||
protected:
|
||||
|
||||
@ -72,6 +73,10 @@ public:
|
||||
void get_param_list(List<PropertyInfo> *p_params) const;
|
||||
bool has_param(const StringName& p_param) const;
|
||||
|
||||
void set_default_texture_param(const StringName& p_param, const Ref<Texture> &p_texture);
|
||||
Ref<Texture> get_default_texture_param(const StringName& p_param) const;
|
||||
void get_default_texture_param_list(List<StringName>* r_textures) const;
|
||||
|
||||
virtual RID get_rid() const;
|
||||
|
||||
Shader();
|
||||
|
@ -187,6 +187,7 @@ public:
|
||||
virtual bool texture_has_alpha(RID p_texture) const=0;
|
||||
virtual void texture_set_size_override(RID p_texture,int p_width, int p_height)=0;
|
||||
|
||||
|
||||
virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const=0;
|
||||
|
||||
/* SHADER API */
|
||||
@ -203,6 +204,9 @@ public:
|
||||
|
||||
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const=0;
|
||||
|
||||
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0;
|
||||
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0;
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
virtual RID material_create()=0;
|
||||
|
@ -221,6 +221,16 @@ void RasterizerDummy::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RasterizerDummy::shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture) {
|
||||
|
||||
}
|
||||
|
||||
RID RasterizerDummy::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const {
|
||||
|
||||
return RID();
|
||||
}
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
|
||||
|
@ -429,6 +429,10 @@ public:
|
||||
|
||||
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
|
||||
|
||||
|
||||
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
|
||||
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
virtual RID material_create();
|
||||
|
@ -157,6 +157,16 @@ void VisualServerRaster::shader_get_param_list(RID p_shader, List<PropertyInfo>
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture) {
|
||||
|
||||
rasterizer->shader_set_default_texture_param(p_shader,p_name,p_texture);
|
||||
}
|
||||
|
||||
RID VisualServerRaster::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
|
||||
|
||||
return rasterizer->shader_get_default_texture_param(p_shader,p_name);
|
||||
}
|
||||
|
||||
|
||||
/* Material */
|
||||
|
||||
|
@ -756,6 +756,10 @@ public:
|
||||
|
||||
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
|
||||
|
||||
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
|
||||
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
|
||||
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
virtual RID material_create();
|
||||
|
@ -653,6 +653,10 @@ public:
|
||||
FUNC1RC(String,shader_get_light_code,RID);
|
||||
FUNC2SC(shader_get_param_list,RID,List<PropertyInfo>*);
|
||||
|
||||
FUNC3(shader_set_default_texture_param,RID,const StringName&,RID);
|
||||
FUNC2RC(RID,shader_get_default_texture_param,RID,const StringName&);
|
||||
|
||||
|
||||
/*virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) {
|
||||
if (Thread::get_caller_ID()!=server_thread) {
|
||||
command_queue.push_and_sync( visual_server, &VisualServer::shader_get_param_list,p_shader,p_param_list);
|
||||
|
@ -140,6 +140,7 @@ public:
|
||||
SHADER_POST_PROCESS,
|
||||
};
|
||||
|
||||
|
||||
virtual RID shader_create(ShaderMode p_mode=SHADER_MATERIAL)=0;
|
||||
|
||||
virtual void shader_set_mode(RID p_shader,ShaderMode p_mode)=0;
|
||||
@ -151,6 +152,9 @@ public:
|
||||
virtual String shader_get_light_code(RID p_shader) const=0;
|
||||
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const=0;
|
||||
|
||||
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0;
|
||||
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0;
|
||||
|
||||
|
||||
/* COMMON MATERIAL API */
|
||||
|
||||
|
@ -487,6 +487,7 @@ FindReplaceDialog::FindReplaceDialog() {
|
||||
|
||||
vb->add_child(error_label);
|
||||
|
||||
|
||||
set_hide_on_ok(false);
|
||||
|
||||
}
|
||||
@ -507,15 +508,19 @@ void CodeTextEditor::_text_changed() {
|
||||
}
|
||||
|
||||
void CodeTextEditor::_code_complete_timer_timeout() {
|
||||
if (!is_visible())
|
||||
return;
|
||||
if (enable_complete_timer)
|
||||
text_editor->query_code_comple();
|
||||
}
|
||||
|
||||
void CodeTextEditor::_complete_request(const String& p_request, int p_line) {
|
||||
void CodeTextEditor::_complete_request() {
|
||||
|
||||
List<String> entries;
|
||||
_code_complete_script(text_editor->get_text(),p_request,p_line,&entries);
|
||||
_code_complete_script(text_editor->get_text_for_completion(),&entries);
|
||||
// print_line("COMPLETE: "+p_request);
|
||||
if (entries.size()==0)
|
||||
return;
|
||||
Vector<String> strs;
|
||||
strs.resize(entries.size());
|
||||
int i=0;
|
||||
@ -555,7 +560,7 @@ void CodeTextEditor::_on_settings_change() {
|
||||
|
||||
// AUTO BRACE COMPLETION
|
||||
text_editor->set_auto_brace_completion(
|
||||
EDITOR_DEF("text_editor/auto_brace_complete", false)
|
||||
EDITOR_DEF("text_editor/auto_brace_complete", true)
|
||||
);
|
||||
|
||||
code_complete_timer->set_wait_time(
|
||||
@ -596,6 +601,7 @@ CodeTextEditor::CodeTextEditor() {
|
||||
text_editor->set_margin(MARGIN_BOTTOM,20);
|
||||
text_editor->add_font_override("font",get_font("source","Fonts"));
|
||||
text_editor->set_show_line_numbers(true);
|
||||
text_editor->set_brace_matching(true);
|
||||
|
||||
line_col = memnew( Label );
|
||||
add_child(line_col);
|
||||
@ -632,6 +638,8 @@ CodeTextEditor::CodeTextEditor() {
|
||||
text_editor->connect("request_completion", this,"_complete_request");
|
||||
Vector<String> cs;
|
||||
cs.push_back(".");
|
||||
cs.push_back(",");
|
||||
cs.push_back("(");
|
||||
text_editor->set_completion(true,cs);
|
||||
idle->connect("timeout", this,"_text_changed_idle_timeout");
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user