This commit is contained in:
Juan Linietsky 2015-05-11 15:49:41 -03:00
commit 4b8745ad63
133 changed files with 2815 additions and 1176 deletions

View file

@ -123,6 +123,7 @@ opts.Add('disable_3d', 'Disable 3D nodes for smaller executable (yes/no)', "no")
opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no") opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no")
opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no') opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no')
opts.Add('extra_suffix', 'Custom extra suffix added to the base filename of all generated binary files.', '') opts.Add('extra_suffix', 'Custom extra suffix added to the base filename of all generated binary files.', '')
opts.Add('vsproj', 'Generate Visual Studio Project. (yes/no)', 'no')
# add platform specific options # add platform specific options
@ -177,6 +178,25 @@ if selected_platform in platform_list:
else: else:
env = env_base.Clone() env = env_base.Clone()
if env['vsproj']=="yes":
env.vs_incs = []
env.vs_srcs = []
def AddToVSProject( sources ):
for x in sources:
if type(x) == type(""):
fname = env.File(x).path
else:
fname = env.File(x)[0].path
pieces = fname.split(".")
if len(pieces)>0:
basename = pieces[0]
basename = basename.replace('\\\\','/')
env.vs_srcs = env.vs_srcs + [basename + ".cpp"]
env.vs_incs = env.vs_incs + [basename + ".h"]
#print basename
env.AddToVSProject = AddToVSProject
env.extra_suffix="" env.extra_suffix=""
if env["extra_suffix"] != '' : if env["extra_suffix"] != '' :
@ -330,6 +350,32 @@ if selected_platform in platform_list:
SConscript("main/SCsub") SConscript("main/SCsub")
SConscript("platform/"+selected_platform+"/SCsub"); # build selected platform SConscript("platform/"+selected_platform+"/SCsub"); # build selected platform
# Microsoft Visual Studio Project Generation
if (env['vsproj'])=="yes":
AddToVSProject(env.core_sources)
AddToVSProject(env.main_sources)
AddToVSProject(env.modules_sources)
AddToVSProject(env.scene_sources)
AddToVSProject(env.servers_sources)
AddToVSProject(env.tool_sources)
debug_variants = ['Debug|Win32']+['Debug|x64']
release_variants = ['Release|Win32']+['Release|x64']
release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64']
variants = debug_variants + release_variants + release_debug_variants
debug_targets = ['Debug']+['Debug']
release_targets = ['Release']+['Release']
release_debug_targets = ['ReleaseDebug']+['ReleaseDebug']
targets = debug_targets + release_targets + release_debug_targets
msvproj = env.MSVSProject(target = ['#godot' + env['MSVSPROJECTSUFFIX'] ],
incs = env.vs_incs,
srcs = env.vs_srcs,
runfile = targets,
buildtarget = targets,
auto_build_solution=1,
variant = variants)
else: else:

View file

@ -1381,7 +1381,7 @@ Globals::Globals() {
set("application/name","" ); set("application/name","" );
set("application/main_scene",""); set("application/main_scene","");
custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"xml,res,scn,xscn"); custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"scn,res,xscn,xml");
set("application/disable_stdout",false); set("application/disable_stdout",false);
set("application/use_shared_user_dir",true); set("application/use_shared_user_dir",true);

View file

@ -39,7 +39,7 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
if (!files) { if (!files) {
files = memnew((Map<String, Vector<uint8_t> >)); files = memnew((Map<String, Vector<uint8_t> >));
}; }
String name; String name;
if (Globals::get_singleton()) if (Globals::get_singleton())
@ -49,7 +49,7 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
name = DirAccess::normalize_path(name); name = DirAccess::normalize_path(name);
(*files)[name] = p_data; (*files)[name] = p_data;
}; }
void FileAccessMemory::cleanup() { void FileAccessMemory::cleanup() {
@ -57,13 +57,13 @@ void FileAccessMemory::cleanup() {
return; return;
memdelete(files); memdelete(files);
}; }
FileAccess* FileAccessMemory::create() { FileAccess* FileAccessMemory::create() {
return memnew(FileAccessMemory); return memnew(FileAccessMemory);
}; }
bool FileAccessMemory::file_exists(const String& p_name) { bool FileAccessMemory::file_exists(const String& p_name) {
@ -71,7 +71,7 @@ bool FileAccessMemory::file_exists(const String& p_name) {
name = DirAccess::normalize_path(name); name = DirAccess::normalize_path(name);
return files && (files->find(name) != NULL); return files && (files->find(name) != NULL);
}; }
Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) { Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
@ -89,57 +89,57 @@ Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
pos = 0; pos = 0;
return OK; return OK;
}; }
void FileAccessMemory::close() { void FileAccessMemory::close() {
data = NULL; data = NULL;
}; }
bool FileAccessMemory::is_open() const { bool FileAccessMemory::is_open() const {
return data != NULL; return data != NULL;
}; }
void FileAccessMemory::seek(size_t p_position) { void FileAccessMemory::seek(size_t p_position) {
ERR_FAIL_COND(!data); ERR_FAIL_COND(!data);
pos = p_position; pos = p_position;
}; }
void FileAccessMemory::seek_end(int64_t p_position) { void FileAccessMemory::seek_end(int64_t p_position) {
ERR_FAIL_COND(!data); ERR_FAIL_COND(!data);
pos = length + p_position; pos = length + p_position;
}; }
size_t FileAccessMemory::get_pos() const { size_t FileAccessMemory::get_pos() const {
ERR_FAIL_COND_V(!data, 0); ERR_FAIL_COND_V(!data, 0);
return pos; return pos;
}; }
size_t FileAccessMemory::get_len() const { size_t FileAccessMemory::get_len() const {
ERR_FAIL_COND_V(!data, 0); ERR_FAIL_COND_V(!data, 0);
return length; return length;
}; }
bool FileAccessMemory::eof_reached() const { bool FileAccessMemory::eof_reached() const {
return pos >= length; return pos >= length;
}; }
uint8_t FileAccessMemory::get_8() const { uint8_t FileAccessMemory::get_8() const {
uint8_t ret; uint8_t ret = 0;
if (pos < length) { if (pos < length) {
ret = data[pos]; ret = data[pos];
}; }
++pos; ++pos;
return ret; return ret;
}; }
int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const { int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const {
@ -156,19 +156,19 @@ int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const {
pos += p_length; pos += p_length;
return read; return read;
}; }
Error FileAccessMemory::get_error() const { Error FileAccessMemory::get_error() const {
return pos >= length ? ERR_FILE_EOF : OK; return pos >= length ? ERR_FILE_EOF : OK;
}; }
void FileAccessMemory::store_8(uint8_t p_byte) { void FileAccessMemory::store_8(uint8_t p_byte) {
ERR_FAIL_COND(!data); ERR_FAIL_COND(!data);
ERR_FAIL_COND(pos >= length); ERR_FAIL_COND(pos >= length);
data[pos++] = p_byte; data[pos++] = p_byte;
}; }
void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) { void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) {
@ -176,11 +176,11 @@ void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) {
int write = MIN(p_length, left); int write = MIN(p_length, left);
if (write < p_length) { if (write < p_length) {
WARN_PRINT("Writing less data than requested"); WARN_PRINT("Writing less data than requested");
}; }
copymem(&data[pos], p_src, write); copymem(&data[pos], p_src, write);
pos += p_length; pos += p_length;
}; }
FileAccessMemory::FileAccessMemory() { FileAccessMemory::FileAccessMemory() {

View file

@ -92,7 +92,9 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o
void PackedData::add_pack_source(PackSource *p_source) { void PackedData::add_pack_source(PackSource *p_source) {
sources.push_back(p_source); if (p_source != NULL) {
sources.push_back(p_source);
}
}; };
PackedData *PackedData::singleton=NULL; PackedData *PackedData::singleton=NULL;

View file

@ -309,6 +309,7 @@ Error ResourceInteractiveLoaderXML::_parse_array_element(Vector<char> &buff,bool
buff_max++; buff_max++;
buff.resize(buff_max); buff.resize(buff_max);
buffptr=buff.ptr();
} }
@ -1849,7 +1850,7 @@ void ResourceFormatSaverXMLInstance::escape(String& p_str) {
p_str=p_str.replace(">","&lt;"); p_str=p_str.replace(">","&lt;");
p_str=p_str.replace("'","&apos;"); p_str=p_str.replace("'","&apos;");
p_str=p_str.replace("\"","&quot;"); p_str=p_str.replace("\"","&quot;");
for (int i=1;i<32;i++) { for (char i=1;i<32;i++) {
char chr[2]={i,0}; char chr[2]={i,0};
const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
@ -2563,7 +2564,7 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
List<PropertyInfo> property_list; List<PropertyInfo> property_list;
res->get_property_list(&property_list); res->get_property_list(&property_list);
property_list.sort(); // property_list.sort();
for(List<PropertyInfo>::Element *PE = property_list.front();PE;PE=PE->next()) { for(List<PropertyInfo>::Element *PE = property_list.front();PE;PE=PE->next()) {

View file

@ -117,6 +117,7 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const Stri
RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) { RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) {
String path=p_path;
//or this must be implemented //or this must be implemented
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path); Ref<ResourceInteractiveLoader> ril = load_interactive(p_path);
@ -150,9 +151,13 @@ void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p
RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) { RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) {
String local_path = Globals::get_singleton()->localize_path(p_path); String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
local_path=find_complete_path(p_path,p_type_hint); local_path=find_complete_path(local_path,p_type_hint);
ERR_FAIL_COND_V(local_path=="",RES()); ERR_FAIL_COND_V(local_path=="",RES());
if (!p_no_cache && ResourceCache::has(local_path)) { if (!p_no_cache && ResourceCache::has(local_path)) {
@ -209,7 +214,11 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n
Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) { Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) {
String local_path = Globals::get_singleton()->localize_path(p_path); String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String extension=p_path.extension(); String extension=p_path.extension();
bool found=false; bool found=false;
@ -283,9 +292,13 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
String local_path = Globals::get_singleton()->localize_path(p_path); String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
local_path=find_complete_path(p_path,p_type_hint); local_path=find_complete_path(local_path,p_type_hint);
ERR_FAIL_COND_V(local_path=="",Ref<ResourceInteractiveLoader>()); ERR_FAIL_COND_V(local_path=="",Ref<ResourceInteractiveLoader>());
@ -340,7 +353,13 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l
void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) { void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
String local_path = Globals::get_singleton()->localize_path(p_path);
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path); String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension(); String extension=remapped_path.extension();
@ -359,7 +378,11 @@ void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_depen
String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) { String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {
String local_path = Globals::get_singleton()->localize_path(p_path); String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
return find_complete_path(local_path,p_type); return find_complete_path(local_path,p_type);
@ -367,7 +390,12 @@ String ResourceLoader::guess_full_filename(const String &p_path,const String& p_
String ResourceLoader::get_resource_type(const String &p_path) { String ResourceLoader::get_resource_type(const String &p_path) {
String local_path = Globals::get_singleton()->localize_path(p_path); String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path); String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension(); String extension=remapped_path.extension();

View file

@ -36,8 +36,9 @@ uint32_t Math::default_seed=1;
#define PHI 0x9e3779b9 #define PHI 0x9e3779b9
static uint32_t Q[4096], c = 362436; #if 0
static uint32_t Q[4096];
#endif
uint32_t Math::rand_from_seed(uint32_t *seed) { uint32_t Math::rand_from_seed(uint32_t *seed) {
@ -269,7 +270,7 @@ bool Math::is_inf(double p_val) {
uint32_t Math::larger_prime(uint32_t p_val) { uint32_t Math::larger_prime(uint32_t p_val) {
static const int primes[] = { static const uint32_t primes[] = {
5, 5,
13, 13,
23, 23,

View file

@ -98,7 +98,7 @@ struct VariantCaster<m_enum> {\
#define CHECK_ARG(m_arg)\ #define CHECK_ARG(m_arg)\
if ((m_arg-1)<p_arg_count) {\ if ((m_arg-1)<p_arg_count) {\
Variant::Type argtype=get_argument_type(m_arg-1);\ Variant::Type argtype=get_argument_type(m_arg-1);\
if (!Variant::can_convert(p_args[m_arg-1]->get_type(),argtype)) {\ if (!Variant::can_convert_strict(p_args[m_arg-1]->get_type(),argtype)) {\
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\
r_error.argument=m_arg-1;\ r_error.argument=m_arg-1;\
r_error.expected=argtype;\ r_error.expected=argtype;\

View file

@ -1282,6 +1282,23 @@ void Object::get_signal_list(List<MethodInfo> *p_signals ) const {
} }
} }
void Object::get_all_signal_connections(List<Connection> *p_connections) const {
const StringName *S=NULL;
while((S=signal_map.next(S))) {
const Signal *s=&signal_map[*S];
for(int i=0;i<s->slot_map.size();i++) {
p_connections->push_back(s->slot_map.getv(i).conn);
}
}
}
void Object::get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const { void Object::get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const {
const Signal *s=signal_map.getptr(p_signal); const Signal *s=signal_map.getptr(p_signal);

View file

@ -574,6 +574,7 @@ public:
void emit_signal(const StringName& p_name,VARIANT_ARG_LIST); void emit_signal(const StringName& p_name,VARIANT_ARG_LIST);
void get_signal_list(List<MethodInfo> *p_signals ) const; void get_signal_list(List<MethodInfo> *p_signals ) const;
void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const; void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const;
void get_all_signal_connections(List<Connection> *p_connections) const;
Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds=Vector<Variant>(),uint32_t p_flags=0); Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds=Vector<Variant>(),uint32_t p_flags=0);
void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method); void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method);

View file

@ -3297,8 +3297,11 @@ String String::path_to_file(const String& p_path) const {
String src=this->replace("\\","/").get_base_dir(); String src=this->replace("\\","/").get_base_dir();
String dst=p_path.replace("\\","/").get_base_dir(); String dst=p_path.replace("\\","/").get_base_dir();
String rel = src.path_to(dst);
return src.path_to(dst)+p_path.get_file(); if (rel==dst) // failed
return p_path;
else
return rel+p_path.get_file();
} }
String String::path_to(const String& p_path) const { String String::path_to(const String& p_path) const {
@ -3333,7 +3336,9 @@ String String::path_to(const String& p_path) const {
String src_begin=src.get_slice("/",0); String src_begin=src.get_slice("/",0);
String dst_begin=dst.get_slice("/",0); String dst_begin=dst.get_slice("/",0);
ERR_FAIL_COND_V(src_begin!=dst_begin,p_path); //return dst absolute path if (src_begin!=dst_begin)
return p_path; //impossible to do this
base=src_begin; base=src_begin;
src=src.substr(src_begin.length(),src.length()); src=src.substr(src_begin.length(),src.length());
dst=dst.substr(dst_begin.length(),dst.length()); dst=dst.substr(dst_begin.length(),dst.length());

View file

@ -258,12 +258,12 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
case MATRIX32: { case MATRIX32: {
static const Type invalid[]={ static const Type valid[]={
TRANSFORM, TRANSFORM,
NIL NIL
}; };
invalid_types=invalid; valid_types=valid;
} break; } break;
case QUAT: { case QUAT: {
@ -299,6 +299,256 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
} break; } break;
case COLOR: {
static const Type valid[] = {
//STRING,
//INT,
NIL,
};
valid_types = valid;
} break;
case _RID: {
static const Type valid[]={
OBJECT,
NIL
};
valid_types=valid;
} break;
case OBJECT: {
static const Type valid[]={
NIL
};
valid_types=valid;
} break;
case NODE_PATH: {
static const Type valid[]={
STRING,
NIL
};
valid_types=valid;
} break;
case ARRAY: {
static const Type valid[]={
RAW_ARRAY,
INT_ARRAY,
STRING_ARRAY,
REAL_ARRAY,
COLOR_ARRAY,
VECTOR2_ARRAY,
VECTOR3_ARRAY,
NIL
};
valid_types=valid;
} break;
// arrays
case RAW_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case INT_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case REAL_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case STRING_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case VECTOR2_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case VECTOR3_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case COLOR_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
default: {}
}
if (valid_types) {
int i=0;
while(valid_types[i]!=NIL) {
if (p_type_from==valid_types[i])
return true;
i++;
}
} else if (invalid_types) {
int i=0;
while(invalid_types[i]!=NIL) {
if (p_type_from==invalid_types[i])
return false;
i++;
}
}
return false;
}
bool Variant::can_convert_strict(Variant::Type p_type_from,Variant::Type p_type_to) {
if (p_type_from==p_type_to)
return true;
if (p_type_to==NIL && p_type_from!=NIL) //nil can convert to anything
return true;
if (p_type_from == NIL) {
return (p_type_to == OBJECT);
};
const Type *valid_types=NULL;
const Type *invalid_types=NULL;
switch(p_type_to) {
case BOOL: {
static const Type valid[]={
INT,
REAL,
//STRING,
NIL,
};
valid_types=valid;
} break;
case INT: {
static const Type valid[]={
BOOL,
REAL,
//STRING,
NIL,
};
valid_types=valid;
} break;
case REAL: {
static const Type valid[]={
BOOL,
INT,
//STRING,
NIL,
};
valid_types=valid;
} break;
case STRING: {
static const Type valid[]={
NODE_PATH,
NIL
};
valid_types=valid;
} break;
case MATRIX32: {
static const Type valid[]={
TRANSFORM,
NIL
};
valid_types=valid;
} break;
case QUAT: {
static const Type valid[]={
MATRIX3,
NIL
};
valid_types=valid;
} break;
case MATRIX3: {
static const Type valid[]={
QUAT,
NIL
};
valid_types=valid;
} break;
case TRANSFORM: {
static const Type valid[]={
MATRIX32,
QUAT,
MATRIX3,
NIL
};
valid_types=valid;
} break;
case COLOR: { case COLOR: {
static const Type valid[] = { static const Type valid[] = {
@ -532,7 +782,7 @@ bool Variant::is_zero() const {
} break; } break;
case QUAT: { case QUAT: {
*reinterpret_cast<const Quat*>(_data._mem)==Quat(); return *reinterpret_cast<const Quat*>(_data._mem)==Quat();
} break; } break;
case MATRIX3: { case MATRIX3: {

View file

@ -165,7 +165,8 @@ public:
_FORCE_INLINE_ Type get_type() const { return type; } _FORCE_INLINE_ Type get_type() const { return type; }
static String get_type_name(Variant::Type p_type); static String get_type_name(Variant::Type p_type);
static bool can_convert(Type p_type_from,Type p_type_to); static bool can_convert(Type p_type_from, Type p_type_to);
static bool can_convert_strict(Type p_type_from, Type p_type_to);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,6 @@
[application] [application]
name="Isometric 2D + Lighting"
main_scene="res://map.scn" main_scene="res://map.scn"
[input] [input]

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

View file

@ -21,6 +21,9 @@ const STOP_FORCE = 1300
const JUMP_SPEED = 200 const JUMP_SPEED = 200
const JUMP_MAX_AIRBORNE_TIME=0.2 const JUMP_MAX_AIRBORNE_TIME=0.2
const SLIDE_STOP_VELOCITY=1.0 #one pixel per second
const SLIDE_STOP_MIN_TRAVEL=1.0 #one pixel
var velocity = Vector2() var velocity = Vector2()
var on_air_time=100 var on_air_time=100
var jumping=false var jumping=false
@ -31,8 +34,6 @@ func _fixed_process(delta):
#create forces #create forces
var force = Vector2(0,GRAVITY) var force = Vector2(0,GRAVITY)
var stop = velocity.x!=0.0
var walk_left = Input.is_action_pressed("move_left") var walk_left = Input.is_action_pressed("move_left")
var walk_right = Input.is_action_pressed("move_right") var walk_right = Input.is_action_pressed("move_right")
@ -86,25 +87,42 @@ func _fixed_process(delta):
#char is on floor #char is on floor
on_air_time=0 on_air_time=0
floor_velocity=get_collider_velocity() floor_velocity=get_collider_velocity()
#velocity.y=0
#But we were moving and our motion was interrupted,
#so try to complete the motion by "sliding" if (on_air_time==0 and force.x==0 and get_travel().length() < SLIDE_STOP_MIN_TRAVEL and abs(velocity.x) < SLIDE_STOP_VELOCITY and get_collider_velocity()==Vector2()):
#by the normal #Since this formula will always slide the character around,
motion = n.slide(motion) #a special case must be considered to to stop it from moving
velocity = n.slide(velocity) #if standing on an inclined floor. Conditions are:
# 1) Standing on floor (on_air_time==0)
#then move again # 2) Did not move more than one pixel (get_travel().length() < SLIDE_STOP_MIN_TRAVEL)
move(motion) # 3) Not moving horizontally (abs(velocity.x) < SLIDE_STOP_VELOCITY)
# 4) Collider is not moving
revert_motion()
velocity.y=0.0
else:
#For every other case of motion,our motion was interrupted.
#Try to complete the motion by "sliding"
#by the normal
motion = n.slide(motion)
velocity = n.slide(velocity)
#then move again
move(motion)
if (floor_velocity!=Vector2()): if (floor_velocity!=Vector2()):
#if floor moves, move with floor #if floor moves, move with floor
move(floor_velocity*delta) move(floor_velocity*delta)
if (jumping and velocity.y>0): if (jumping and velocity.y>0):
#if falling, no longer jumping
jumping=false jumping=false
if (on_air_time<JUMP_MAX_AIRBORNE_TIME and jump and not prev_jump_pressed and not jumping): if (on_air_time<JUMP_MAX_AIRBORNE_TIME and jump and not prev_jump_pressed and not jumping):
# Jump must also be allowed to happen if the
# character left the floor a little bit ago.
# Makes controls more snappy.
velocity.y=-JUMP_SPEED velocity.y=-JUMP_SPEED
jumping=true jumping=true

View file

@ -56,7 +56,7 @@ func _integrate_forces(s):
state=STATE_DYING state=STATE_DYING
#lv=s.get_contact_local_normal(i)*400 #lv=s.get_contact_local_normal(i)*400
s.set_angular_velocity(sign(dp.x)*33.0) s.set_angular_velocity(sign(dp.x)*33.0)
set_friction(true) set_friction(1)
cc.disable() cc.disable()
get_node("sound").play("hit") get_node("sound").play("hit")

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="UTF-8" ?>
<resource_file type="PackedScene" subresource_count="3" version="1.1" version_name="Godot Engine v1.1.rc1.custom_build">
<ext_resource path="res://one_way_platform.png" type="Texture"></ext_resource>
<resource type="RectangleShape2D" path="local://1">
<real name="custom_solver_bias"> 0 </real>
<vector2 name="extents"> 100, 10 </vector2>
</resource>
<main_resource>
<dictionary name="_bundled" shared="false">
<string> "conn_count" </string>
<int> 0 </int>
<string> "conns" </string>
<int_array len="0"> </int_array>
<string> "names" </string>
<string_array len="42">
<string> "one_way_platform" </string>
<string> "StaticBody2D" </string>
<string> "_import_path" </string>
<string> "visibility/visible" </string>
<string> "visibility/opacity" </string>
<string> "visibility/self_opacity" </string>
<string> "visibility/light_mask" </string>
<string> "transform/pos" </string>
<string> "transform/rot" </string>
<string> "transform/scale" </string>
<string> "z/z" </string>
<string> "z/relative" </string>
<string> "input/pickable" </string>
<string> "shape_count" </string>
<string> "shapes/0/shape" </string>
<string> "shapes/0/transform" </string>
<string> "shapes/0/trigger" </string>
<string> "collision/layers" </string>
<string> "collision/mask" </string>
<string> "one_way_collision/direction" </string>
<string> "one_way_collision/max_depth" </string>
<string> "constant_linear_velocity" </string>
<string> "constant_angular_velocity" </string>
<string> "friction" </string>
<string> "bounce" </string>
<string> "__meta__" </string>
<string> "sprite" </string>
<string> "Sprite" </string>
<string> "texture" </string>
<string> "centered" </string>
<string> "offset" </string>
<string> "flip_h" </string>
<string> "flip_v" </string>
<string> "vframes" </string>
<string> "hframes" </string>
<string> "frame" </string>
<string> "modulate" </string>
<string> "region" </string>
<string> "region_rect" </string>
<string> "CollisionShape2D" </string>
<string> "shape" </string>
<string> "trigger" </string>
</string_array>
<string> "node_count" </string>
<int> 3 </int>
<string> "nodes" </string>
<int_array len="135"> -1, -1, 1, 0, -1, 24, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 1, 12, 8, 13, 3, 14, 9, 15, 10, 16, 8, 17, 3, 18, 3, 19, 11, 20, 12, 21, 4, 22, 5, 23, 2, 24, 5, 25, 13, 0, 0, 0, 27, 26, -1, 21, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 1, 28, 14, 29, 1, 30, 4, 31, 8, 32, 8, 33, 3, 34, 3, 35, 7, 36, 15, 37, 8, 38, 16, 0, 0, 0, 39, 39, -1, 12, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 17, 8, 5, 9, 6, 10, 7, 11, 1, 40, 9, 41, 8, 0 </int_array>
<string> "variants" </string>
<array len="18" shared="false">
<node_path> "" </node_path>
<bool> True </bool>
<real> 1 </real>
<int> 1 </int>
<vector2> 0, 0 </vector2>
<real> 0 </real>
<vector2> 1, 1 </vector2>
<int> 0 </int>
<bool> False </bool>
<resource resource_type="Shape2D" path="local://1"> </resource>
<matrix32> 1, -0, 0, 1, 1.46304, -13.1672 </matrix32>
<vector2> 0, 1 </vector2>
<real> 20 </real>
<dictionary shared="false">
<string> "__editor_plugin_screen__" </string>
<string> "2D" </string>
<string> "__editor_plugin_states__" </string>
<dictionary shared="false">
<string> "2D" </string>
<dictionary shared="false">
<string> "ofs" </string>
<vector2> -133.699, -110.553 </vector2>
<string> "snap_grid" </string>
<bool> False </bool>
<string> "snap_offset" </string>
<vector2> 0, 0 </vector2>
<string> "snap_pixel" </string>
<bool> False </bool>
<string> "snap_relative" </string>
<bool> False </bool>
<string> "snap_rotation" </string>
<bool> False </bool>
<string> "snap_rotation_offset" </string>
<real> 0 </real>
<string> "snap_rotation_step" </string>
<real> 0.261799 </real>
<string> "snap_show_grid" </string>
<bool> False </bool>
<string> "snap_step" </string>
<vector2> 10, 10 </vector2>
<string> "zoom" </string>
<real> 2.050546 </real>
</dictionary>
<string> "3D" </string>
<dictionary shared="false">
<string> "ambient_light_color" </string>
<color> 0.15, 0.15, 0.15, 1 </color>
<string> "default_light" </string>
<bool> True </bool>
<string> "default_srgb" </string>
<bool> False </bool>
<string> "deflight_rot_x" </string>
<real> 0.942478 </real>
<string> "deflight_rot_y" </string>
<real> 0.628319 </real>
<string> "fov" </string>
<real> 45 </real>
<string> "show_grid" </string>
<bool> True </bool>
<string> "show_origin" </string>
<bool> True </bool>
<string> "viewport_mode" </string>
<int> 1 </int>
<string> "viewports" </string>
<array len="4" shared="false">
<dictionary shared="false">
<string> "distance" </string>
<real> 4 </real>
<string> "listener" </string>
<bool> True </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
<string> "use_environment" </string>
<bool> False </bool>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </real>
</dictionary>
<dictionary shared="false">
<string> "distance" </string>
<real> 4 </real>
<string> "listener" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
<string> "use_environment" </string>
<bool> False </bool>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </real>
</dictionary>
<dictionary shared="false">
<string> "distance" </string>
<real> 4 </real>
<string> "listener" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
<string> "use_environment" </string>
<bool> False </bool>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </real>
</dictionary>
<dictionary shared="false">
<string> "distance" </string>
<real> 4 </real>
<string> "listener" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
<string> "use_environment" </string>
<bool> False </bool>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </real>
</dictionary>
</array>
<string> "zfar" </string>
<real> 500 </real>
<string> "znear" </string>
<real> 0.1 </real>
</dictionary>
</dictionary>
<string> "__editor_run_settings__" </string>
<dictionary shared="false">
<string> "custom_args" </string>
<string> "-l $scene" </string>
<string> "run_mode" </string>
<int> 0 </int>
</dictionary>
</dictionary>
<resource resource_type="Texture" path="res://one_way_platform.png"> </resource>
<color> 1, 1, 1, 1 </color>
<rect2> 0, 0, 0, 0 </rect2>
<vector2> 1.46304, -13.1672 </vector2>
</array>
<string> "version" </string>
<int> 1 </int>
</dictionary>
</main_resource>
</resource_file>

View file

@ -33,7 +33,6 @@ var shooting=false
var WALK_ACCEL = 800.0 var WALK_ACCEL = 800.0
var WALK_DEACCEL= 800.0 var WALK_DEACCEL= 800.0
var WALK_MAX_VELOCITY= 200.0 var WALK_MAX_VELOCITY= 200.0
var GRAVITY = 700.0
var AIR_ACCEL = 200.0 var AIR_ACCEL = 200.0
var AIR_DEACCEL= 200.0 var AIR_DEACCEL= 200.0
var JUMP_VELOCITY=460 var JUMP_VELOCITY=460

File diff suppressed because one or more lines are too long

View file

@ -143,6 +143,7 @@ func restart_pressed():
cells.clear() cells.clear()
get_node("gameover").set_text("") get_node("gameover").set_text("")
piece_active=true piece_active=true
get_node("../restart").release_focus()
update() update()

Binary file not shown.

Binary file not shown.

View file

@ -45,7 +45,7 @@ func _integrate_forces(state):
state.set_angular_velocity( -dp.cross(up).normalized() *33.0) state.set_angular_velocity( -dp.cross(up).normalized() *33.0)
get_node("AnimationPlayer").play("impact") get_node("AnimationPlayer").play("impact")
get_node("AnimationPlayer").queue("explode") get_node("AnimationPlayer").queue("explode")
set_friction(true) set_friction(1)
cc.disabled=true cc.disabled=true
get_node("sound").play("hit") get_node("sound").play("hit")
return return

Binary file not shown.

View file

@ -1,5 +1,6 @@
[application] [application]
name="Truck Town"
main_scene="res://car_select.scn" main_scene="res://car_select.scn"
[display] [display]

View file

@ -1,3 +1,4 @@
[application] [application]
name="Rich Text Label (BBCode)"
main_scene="res://rich_text_bbcode.scn" main_scene="res://rich_text_bbcode.scn"

View file

@ -1,6 +1,8 @@
extends Control extends Control
var mousepos
func _fixed_process(delta): func _fixed_process(delta):
var modetext = "Mode:\n" var modetext = "Mode:\n"
@ -31,7 +33,7 @@ func _fixed_process(delta):
get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) ) get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) )
get_node("Label_MousePosition").set_text(str("Mouse Position:\n", Input.get_mouse_pos() ) ) get_node("Label_MousePosition").set_text(str("Mouse Position:\n", mousepos ) )
get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) ) get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) )
@ -126,6 +128,12 @@ func check_wm_api():
func _ready(): func _ready():
if( check_wm_api() ): if( check_wm_api() ):
set_fixed_process(true) set_fixed_process(true)
set_process_input(true)
func _input(ev):
if (ev.type==InputEvent.MOUSE_MOTION):
mousepos = ev.pos
func _on_Button_MoveTo_pressed(): func _on_Button_MoveTo_pressed():

View file

@ -1,6 +1,6 @@
[application] [application]
name="window_management" name="Window Management"
main_scene="res://window_management.scn" main_scene="res://window_management.scn"
icon="icon.png" icon="icon.png"

View file

@ -19442,7 +19442,7 @@
<description> <description>
</description> </description>
</method> </method>
<method name="body_set_user_mask" > <method name="body_set_collision_mask" >
<argument index="0" name="body" type="RID"> <argument index="0" name="body" type="RID">
</argument> </argument>
<argument index="1" name="mask" type="int"> <argument index="1" name="mask" type="int">
@ -19450,7 +19450,7 @@
<description> <description>
</description> </description>
</method> </method>
<method name="body_get_user_mask" qualifiers="const" > <method name="body_get_collision_mask" qualifiers="const" >
<return type="int"> <return type="int">
</return> </return>
<argument index="0" name="body" type="RID"> <argument index="0" name="body" type="RID">

View file

@ -1,91 +1,94 @@
Import('env') Import('env')
env.drivers_sources=[] env.drivers_sources=[]
#env.add_source_files(env.drivers_sources,"*.cpp") #env.add_source_files(env.drivers_sources,"*.cpp")
env.Append(CPPPATH=["vorbis"]) env.Append(CPPPATH=["vorbis"])
Export('env') Export('env')
SConscript('unix/SCsub'); SConscript('unix/SCsub');
SConscript('alsa/SCsub'); SConscript('alsa/SCsub');
SConscript('pulseaudio/SCsub'); SConscript('pulseaudio/SCsub');
SConscript('windows/SCsub'); SConscript('windows/SCsub');
SConscript('gles2/SCsub'); SConscript('gles2/SCsub');
SConscript('gl_context/SCsub'); SConscript('gl_context/SCsub');
SConscript('openssl/SCsub'); SConscript('openssl/SCsub');
if (env["png"]=="yes"): if (env["png"]=="yes"):
SConscript("png/SCsub"); SConscript("png/SCsub");
if (env["jpg"]=="yes"): if (env["jpg"]=="yes"):
SConscript("jpg/SCsub"); SConscript("jpg/SCsub");
if (env["webp"]=="yes"): if (env["webp"]=="yes"):
SConscript("webp/SCsub"); SConscript("webp/SCsub");
SConscript("dds/SCsub"); SConscript("dds/SCsub");
SConscript("pvr/SCsub"); SConscript("pvr/SCsub");
SConscript("etc1/SCsub") SConscript("etc1/SCsub")
if (env["builtin_zlib"]=="yes"): if (env["builtin_zlib"]=="yes"):
SConscript("builtin_zlib/SCsub"); SConscript("builtin_zlib/SCsub");
if (env["openssl"]=="builtin"): if (env["openssl"]=="builtin"):
SConscript("builtin_openssl2/SCsub"); SConscript("builtin_openssl2/SCsub");
SConscript("rtaudio/SCsub"); SConscript("rtaudio/SCsub");
SConscript("nedmalloc/SCsub"); SConscript("nedmalloc/SCsub");
SConscript("trex/SCsub"); SConscript("trex/SCsub");
SConscript("chibi/SCsub"); SConscript("chibi/SCsub");
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"): if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"):
SConscript("ogg/SCsub"); SConscript("ogg/SCsub");
if (env["vorbis"]=="yes"): if (env["vorbis"]=="yes"):
SConscript("vorbis/SCsub"); SConscript("vorbis/SCsub");
if (env["tools"]=="yes"): if (env["tools"]=="yes"):
SConscript("convex_decomp/SCsub"); SConscript("convex_decomp/SCsub");
if env["theora"]=="yes": if env["theora"]=="yes":
SConscript("theoraplayer/SCsub") SConscript("theoraplayer/SCsub")
if (env["theora"]=="yes"): if (env["theora"]=="yes"):
SConscript("theora/SCsub"); SConscript("theora/SCsub");
if (env['speex']=='yes'): if (env['speex']=='yes'):
SConscript("speex/SCsub"); SConscript("speex/SCsub");
if (env['musepack']=='yes'): if (env['musepack']=='yes'):
SConscript("mpc/SCsub"); SConscript("mpc/SCsub");
if (env["squish"]=="yes" and env["tools"]=="yes"): if (env["squish"]=="yes" and env["tools"]=="yes"):
SConscript("squish/SCsub"); SConscript("squish/SCsub");
num = 0 num = 0
cur_base = "" cur_base = ""
total = len(env.drivers_sources) total = len(env.drivers_sources)
max_src = 64 max_src = 64
list = [] list = []
lib_list = [] lib_list = []
import string import string
for f in env.drivers_sources: if env['vsproj']=="yes":
fname = "" env.AddToVSProject(env.drivers_sources)
if type(f) == type(""):
fname = env.File(f).path for f in env.drivers_sources:
else: fname = ""
fname = env.File(f)[0].path if type(f) == type(""):
#base = string.join(fname.split("/")[:-1], "/") fname = env.File(f).path
fname = fname.replace("\\", "/") else:
base = string.join(fname.split("/")[:2], "/") fname = env.File(f)[0].path
if base != cur_base and len(list) > max_src: #base = string.join(fname.split("/")[:-1], "/")
lib = env.Library("drivers"+str(num), list) fname = fname.replace("\\", "/")
lib_list.append(lib) base = string.join(fname.split("/")[:2], "/")
list = [] if base != cur_base and len(list) > max_src:
num = num+1 lib = env.Library("drivers"+str(num), list)
cur_base = base lib_list.append(lib)
list.append(f) list = []
num = num+1
if len(list) > 0: cur_base = base
lib = env.Library("drivers"+str(num), list) list.append(f)
lib_list.append(lib)
if len(list) > 0:
lib = env.Library("drivers"+str(num), list)
drivers_base=[] lib_list.append(lib)
env.add_source_files(drivers_base,"*.cpp")
lib_list.insert(0, env.Library("drivers", drivers_base))
drivers_base=[]
env.Prepend(LIBS=lib_list) env.add_source_files(drivers_base,"*.cpp")
lib_list.insert(0, env.Library("drivers", drivers_base))
#lib = env.Library("drivers",env.drivers_sources)
#env.Prepend(LIBS=[lib]) env.Prepend(LIBS=lib_list)
#lib = env.Library("drivers",env.drivers_sources)
#env.Prepend(LIBS=[lib])

View file

@ -233,7 +233,7 @@ int CPPlayer::get_channel_voice(int p_channel) {
const char* CPPlayer::get_voice_sample_name(int p_voice) { const char* CPPlayer::get_voice_sample_name(int p_voice) {
const char *name; const char *name = NULL;
@ -302,7 +302,7 @@ const char * CPPlayer::get_voice_instrument_name(int p_voice) {
const char *name; const char *name = NULL;

View file

@ -970,6 +970,7 @@ int32 DecomposeConvex(b2Polygon* p, b2Polygon* results, int32 maxPolys) {
} }
if (nTri < 1) { if (nTri < 1) {
//Still no luck? Oh well... //Still no luck? Oh well...
delete[] triangulated;
return -1; return -1;
} }
int32 nPolys = PolygonizeTriangles(triangulated, nTri, results, maxPolys); int32 nPolys = PolygonizeTriangles(triangulated, nTri, results, maxPolys);

View file

@ -431,6 +431,42 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
// code="get_texpos(gl_ProjectionMatrixInverse * texture2D( depth_texture, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy,vec2(0.0),vec2(1.0))*gl_LightSource[5].specular.zw+gl_LightSource[5].specular.xy)"; // code="get_texpos(gl_ProjectionMatrixInverse * texture2D( depth_texture, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy,vec2(0.0),vec2(1.0))*gl_LightSource[5].specular.zw+gl_LightSource[5].specular.xy)";
//code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb"; //code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb";
break; break;
} else if (custom_h && callfunc=="cosh_custom") {
if (!cosh_used) {
global_code= "float cosh_custom(float val)\n"\
"{\n"\
" float tmp = exp(val);\n"\
" float cosH = (tmp + 1.0 / tmp) / 2.0;\n"\
" return cosH;\n"\
"}\n"+global_code;
cosh_used=true;
}
code="cosh_custom("+dump_node_code(onode->arguments[1],p_level)+"";
} else if (custom_h && callfunc=="sinh_custom") {
if (!sinh_used) {
global_code= "float sinh_custom(float val)\n"\
"{\n"\
" float tmp = exp(val);\n"\
" float sinH = (tmp - 1.0 / tmp) / 2.0;\n"\
" return sinH;\n"\
"}\n"+global_code;
sinh_used=true;
}
code="sinh_custom("+dump_node_code(onode->arguments[1],p_level)+"";
} else if (custom_h && callfunc=="tanh_custom") {
if (!tanh_used) {
global_code= "float tanh_custom(float val)\n"\
"{\n"\
" float tmp = exp(val);\n"\
" float tanH = (tmp - 1.0 / tmp) / (tmp + 1.0 / tmp);\n"\
" return tanH;\n"\
"}\n"+global_code;
tanh_used=true;
}
code="tanh_custom("+dump_node_code(onode->arguments[1],p_level)+"";
} else { } else {
@ -634,6 +670,9 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
r_flags.use_var2_interp=false; r_flags.use_var2_interp=false;
r_flags.uses_normalmap=false; r_flags.uses_normalmap=false;
r_flags.uses_normal=false; r_flags.uses_normal=false;
sinh_used=false;
tanh_used=false;
cosh_used=false;
String error; String error;
int errline,errcol; int errline,errcol;
@ -662,12 +701,18 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
r_flags.uses_shadow_color=uses_shadow_color; r_flags.uses_shadow_color=uses_shadow_color;
r_code_line=code; r_code_line=code;
r_globals_line=global_code; r_globals_line=global_code;
return OK; return OK;
} }
ShaderCompilerGLES2::ShaderCompilerGLES2() { ShaderCompilerGLES2::ShaderCompilerGLES2() {
#ifdef GLEW_ENABLED
//use custom functions because they are not supported in GLSL120
custom_h=true;
#else
custom_h=false;
#endif
replace_table["bool"]= "bool"; replace_table["bool"]= "bool";
replace_table["float" ]= "float"; replace_table["float" ]= "float";
replace_table["vec2" ]= "vec2"; replace_table["vec2" ]= "vec2";
@ -686,9 +731,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
replace_table["acos" ]= "acos"; replace_table["acos" ]= "acos";
replace_table["atan" ]= "atan"; replace_table["atan" ]= "atan";
replace_table["atan2"]= "atan"; replace_table["atan2"]= "atan";
replace_table["sinh" ]= "sinh";
replace_table["cosh" ]= "cosh"; if (custom_h) {
replace_table["tanh" ]= "tanh"; replace_table["sinh" ]= "sinh_custom";
replace_table["cosh" ]= "cosh_custom";
replace_table["tanh" ]= "tanh_custom";
} else {
replace_table["sinh" ]= "sinh";
replace_table["cosh" ]= "cosh";
replace_table["tanh" ]= "tanh";
}
replace_table["pow" ]= "pow"; replace_table["pow" ]= "pow";
replace_table["exp" ]= "exp"; replace_table["exp" ]= "exp";
replace_table["log" ]= "log"; replace_table["log" ]= "log";

View file

@ -56,6 +56,13 @@ private:
bool uses_worldvec; bool uses_worldvec;
bool vertex_code_writes_vertex; bool vertex_code_writes_vertex;
bool uses_shadow_color; bool uses_shadow_color;
bool sinh_used;
bool tanh_used;
bool cosh_used;
bool custom_h;
Flags *flags; Flags *flags;
StringName vname_discard; StringName vname_discard;

View file

@ -36,6 +36,7 @@
#include <mpc/reader.h> #include <mpc/reader.h>
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> // memset()
#define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value...
typedef struct mpc_reader_stdio_t { typedef struct mpc_reader_stdio_t {

View file

@ -11,21 +11,21 @@ public:
ColorRgb() ColorRgb()
: r(0) : b(0)
, g(0) , g(0)
, b(0) { , r(0) {
} }
ColorRgb(T red, T green, T blue) ColorRgb(T red, T green, T blue)
: r(red) : b(blue)
, g(green) , g(green)
, b(blue) { , r(red) {
} }
ColorRgb(const ColorRgb<T> &x) ColorRgb(const ColorRgb<T> &x)
: r(x.r) : b(x.b)
, g(x.g) , g(x.g)
, b(x.b) { , r(x.r) {
} }
ColorRgb<int> operator *(int x) { ColorRgb<int> operator *(int x) {

View file

@ -46,6 +46,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <climits> #include <climits>
#include <algorithm>
// Static variable definitions. // Static variable definitions.
const unsigned int RtApi::MAX_SAMPLE_RATES = 14; const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
@ -63,6 +64,22 @@ const unsigned int RtApi::SAMPLE_RATES[] = {
#define MUTEX_DESTROY(A) DeleteCriticalSection(A) #define MUTEX_DESTROY(A) DeleteCriticalSection(A)
#define MUTEX_LOCK(A) EnterCriticalSection(A) #define MUTEX_LOCK(A) EnterCriticalSection(A)
#define MUTEX_UNLOCK(A) LeaveCriticalSection(A) #define MUTEX_UNLOCK(A) LeaveCriticalSection(A)
#include "tchar.h"
static std::string convertCharPointerToStdString(const char *text)
{
return std::string(text);
}
static std::string convertCharPointerToStdString(const wchar_t *text)
{
int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL);
std::string s( length-1, '\0' );
WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL);
return s;
}
#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
// pthread API // pthread API
#define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
@ -184,7 +201,7 @@ RtAudio :: RtAudio( RtAudio::Api api )
getCompiledApi( apis ); getCompiledApi( apis );
for ( unsigned int i=0; i<apis.size(); i++ ) { for ( unsigned int i=0; i<apis.size(); i++ ) {
openRtApi( apis[i] ); openRtApi( apis[i] );
if ( rtapi_->getDeviceCount() ) break; if ( rtapi_ && rtapi_->getDeviceCount() ) break;
} }
if ( rtapi_ ) return; if ( rtapi_ ) return;
@ -766,9 +783,14 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
bool haveValueRange = false; bool haveValueRange = false;
info.sampleRates.clear(); info.sampleRates.clear();
for ( UInt32 i=0; i<nRanges; i++ ) { for ( UInt32 i=0; i<nRanges; i++ ) {
if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) {
info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum ); unsigned int tmpSr = (unsigned int) rangeList[i].mMinimum;
else { info.sampleRates.push_back( tmpSr );
if ( !info.preferredSampleRate || ( tmpSr <= 48000 && tmpSr > info.preferredSampleRate ) )
info.preferredSampleRate = tmpSr;
} else {
haveValueRange = true; haveValueRange = true;
if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum; if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum; if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
@ -777,8 +799,12 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
if ( haveValueRange ) { if ( haveValueRange ) {
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) {
info.sampleRates.push_back( SAMPLE_RATES[k] ); info.sampleRates.push_back( SAMPLE_RATES[k] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[k];
}
} }
} }
@ -1385,6 +1411,18 @@ void RtApiCore :: closeStream( void )
CoreHandle *handle = (CoreHandle *) stream_.apiHandle; CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
if (handle) {
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
property.mSelector = kAudioDeviceProcessorOverload;
property.mScope = kAudioObjectPropertyScopeGlobal;
if (AudioObjectRemovePropertyListener( handle->id[0], &property, xrunListener, (void *) handle ) != noErr) {
errorText_ = "RtApiCore::closeStream(): error removing property listener!";
error( RtAudioError::WARNING );
}
}
if ( stream_.state == STREAM_RUNNING ) if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[0], callbackHandler ); AudioDeviceStop( handle->id[0], callbackHandler );
#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) #if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
@ -1396,6 +1434,18 @@ void RtApiCore :: closeStream( void )
} }
if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) { if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
if (handle) {
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
property.mSelector = kAudioDeviceProcessorOverload;
property.mScope = kAudioObjectPropertyScopeGlobal;
if (AudioObjectRemovePropertyListener( handle->id[1], &property, xrunListener, (void *) handle ) != noErr) {
errorText_ = "RtApiCore::closeStream(): error removing property listener!";
error( RtAudioError::WARNING );
}
}
if ( stream_.state == STREAM_RUNNING ) if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[1], callbackHandler ); AudioDeviceStop( handle->id[1], callbackHandler );
#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) #if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
@ -1989,7 +2039,9 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
// Get the current jack server sample rate. // Get the current jack server sample rate.
info.sampleRates.clear(); info.sampleRates.clear();
info.sampleRates.push_back( jack_get_sample_rate( client ) );
info.preferredSampleRate = jack_get_sample_rate( client );
info.sampleRates.push_back( info.preferredSampleRate );
// Count the available ports containing the client name as device // Count the available ports containing the client name as device
// channels. Jack "input ports" equal RtAudio output channels. // channels. Jack "input ports" equal RtAudio output channels.
@ -2769,8 +2821,12 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
info.sampleRates.clear(); info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) { for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] ); result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
if ( result == ASE_OK ) if ( result == ASE_OK ) {
info.sampleRates.push_back( SAMPLE_RATES[i] ); info.sampleRates.push_back( SAMPLE_RATES[i] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[i];
}
} }
// Determine supported data types ... just check first channel and assume rest are the same. // Determine supported data types ... just check first channel and assume rest are the same.
@ -2829,9 +2885,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
unsigned int firstChannel, unsigned int sampleRate, unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize, RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options ) RtAudio::StreamOptions *options )
{ {////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isDuplexInput = mode == INPUT && stream_.mode == OUTPUT;
// For ASIO, a duplex stream MUST use the same driver. // For ASIO, a duplex stream MUST use the same driver.
if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] != device ) { if ( isDuplexInput && stream_.device[0] != device ) {
errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!"; errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!";
return FAILURE; return FAILURE;
} }
@ -2845,7 +2904,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
} }
// Only load the driver once for duplex stream. // Only load the driver once for duplex stream.
if ( mode != INPUT || stream_.mode != OUTPUT ) { if ( !isDuplexInput ) {
// The getDeviceInfo() function will not work when a stream is open // The getDeviceInfo() function will not work when a stream is open
// because ASIO does not allow multiple devices to run at the same // because ASIO does not allow multiple devices to run at the same
// time. Thus, we'll probe the system before opening a stream and // time. Thus, we'll probe the system before opening a stream and
@ -2866,22 +2925,26 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
} }
} }
// keep them before any "goto error", they are used for error cleanup + goto device boundary checks
bool buffersAllocated = false;
AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
unsigned int nChannels;
// Check the device channel count. // Check the device channel count.
long inputChannels, outputChannels; long inputChannels, outputChannels;
result = ASIOGetChannels( &inputChannels, &outputChannels ); result = ASIOGetChannels( &inputChannels, &outputChannels );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) || if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) { ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
stream_.nDeviceChannels[mode] = channels; stream_.nDeviceChannels[mode] = channels;
stream_.nUserChannels[mode] = channels; stream_.nUserChannels[mode] = channels;
@ -2890,30 +2953,27 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
// Verify the sample rate is supported. // Verify the sample rate is supported.
result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate ); result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Get the current sample rate // Get the current sample rate
ASIOSampleRate currentRate; ASIOSampleRate currentRate;
result = ASIOGetSampleRate( &currentRate ); result = ASIOGetSampleRate( &currentRate );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Set the sample rate only if necessary // Set the sample rate only if necessary
if ( currentRate != sampleRate ) { if ( currentRate != sampleRate ) {
result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate ); result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
} }
@ -2924,10 +2984,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
else channelInfo.isInput = true; else channelInfo.isInput = true;
result = ASIOGetChannelInfo( &channelInfo ); result = ASIOGetChannelInfo( &channelInfo );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Assuming WINDOWS host is always little-endian. // Assuming WINDOWS host is always little-endian.
@ -2956,10 +3015,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
} }
if ( stream_.deviceFormat[mode] == 0 ) { if ( stream_.deviceFormat[mode] == 0 ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Set the buffer size. For a duplex stream, this will end up // Set the buffer size. For a duplex stream, this will end up
@ -2968,49 +3026,63 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
long minSize, maxSize, preferSize, granularity; long minSize, maxSize, preferSize, granularity;
result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity ); result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; if ( isDuplexInput ) {
else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; // When this is the duplex input (output was opened before), then we have to use the same
else if ( granularity == -1 ) { // buffersize as the output, because it might use the preferred buffer size, which most
// Make sure bufferSize is a power of two. // likely wasn't passed as input to this. The buffer sizes have to be identically anyway,
int log2_of_min_size = 0; // So instead of throwing an error, make them equal. The caller uses the reference
int log2_of_max_size = 0; // to the "bufferSize" param as usual to set up processing buffers.
for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) { *bufferSize = stream_.bufferSize;
if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
}
long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) ); } else {
int min_delta_num = log2_of_min_size; if ( *bufferSize == 0 ) *bufferSize = preferSize;
else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
if (current_delta < min_delta) {
min_delta = current_delta;
min_delta_num = i;
}
}
*bufferSize = ( (unsigned int)1 << min_delta_num );
if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
} else if ( granularity == -1 ) {
else if ( granularity != 0 ) { // Make sure bufferSize is a power of two.
// Set to an even multiple of granularity, rounding up. int log2_of_min_size = 0;
*bufferSize = (*bufferSize + granularity-1) / granularity * granularity; int log2_of_max_size = 0;
for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
}
long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
int min_delta_num = log2_of_min_size;
for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
if (current_delta < min_delta) {
min_delta = current_delta;
min_delta_num = i;
}
}
*bufferSize = ( (unsigned int)1 << min_delta_num );
if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
}
else if ( granularity != 0 ) {
// Set to an even multiple of granularity, rounding up.
*bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
}
} }
if ( mode == INPUT && stream_.mode == OUTPUT && stream_.bufferSize != *bufferSize ) { /*
drivers.removeCurrentDriver(); // we don't use it anymore, see above!
// Just left it here for the case...
if ( isDuplexInput && stream_.bufferSize != *bufferSize ) {
errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!"; errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
return FAILURE; goto error;
} }
*/
stream_.bufferSize = *bufferSize; stream_.bufferSize = *bufferSize;
stream_.nBuffers = 2; stream_.nBuffers = 2;
@ -3022,16 +3094,13 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.deviceInterleaved[mode] = false; stream_.deviceInterleaved[mode] = false;
// Allocate, if necessary, our AsioHandle structure for the stream. // Allocate, if necessary, our AsioHandle structure for the stream.
AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
if ( handle == 0 ) { if ( handle == 0 ) {
try { try {
handle = new AsioHandle; handle = new AsioHandle;
} }
catch ( std::bad_alloc& ) { catch ( std::bad_alloc& ) {
//if ( handle == NULL ) {
drivers.removeCurrentDriver();
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory."; errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
return FAILURE; goto error;
} }
handle->bufferInfos = 0; handle->bufferInfos = 0;
@ -3046,15 +3115,14 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
// Create the ASIO internal buffers. Since RtAudio sets up input // Create the ASIO internal buffers. Since RtAudio sets up input
// and output separately, we'll have to dispose of previously // and output separately, we'll have to dispose of previously
// created output buffers for a duplex stream. // created output buffers for a duplex stream.
long inputLatency, outputLatency;
if ( mode == INPUT && stream_.mode == OUTPUT ) { if ( mode == INPUT && stream_.mode == OUTPUT ) {
ASIODisposeBuffers(); ASIODisposeBuffers();
if ( handle->bufferInfos ) free( handle->bufferInfos ); if ( handle->bufferInfos ) free( handle->bufferInfos );
} }
// Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure. // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
bool buffersAllocated = false; unsigned int i;
unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) ); handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
if ( handle->bufferInfos == NULL ) { if ( handle->bufferInfos == NULL ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
@ -3075,18 +3143,37 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
infos->buffers[0] = infos->buffers[1] = 0; infos->buffers[0] = infos->buffers[1] = 0;
} }
// prepare for callbacks
stream_.sampleRate = sampleRate;
stream_.device[mode] = device;
stream_.mode = isDuplexInput ? DUPLEX : mode;
// store this class instance before registering callbacks, that are going to use it
asioCallbackInfo = &stream_.callbackInfo;
stream_.callbackInfo.object = (void *) this;
// Set up the ASIO callback structure and create the ASIO data buffers. // Set up the ASIO callback structure and create the ASIO data buffers.
asioCallbacks.bufferSwitch = &bufferSwitch; asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged; asioCallbacks.sampleRateDidChange = &sampleRateChanged;
asioCallbacks.asioMessage = &asioMessages; asioCallbacks.asioMessage = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = NULL; asioCallbacks.bufferSwitchTimeInfo = NULL;
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks ); result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
if ( result != ASE_OK ) {
// Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges
// but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver
// in that case, let's be naïve and try that instead
*bufferSize = preferSize;
stream_.bufferSize = *bufferSize;
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
}
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
goto error; goto error;
} }
buffersAllocated = true; buffersAllocated = true;
stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion. // Set flags for buffer conversion.
stream_.doConvertBuffer[mode] = false; stream_.doConvertBuffer[mode] = false;
@ -3109,11 +3196,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
bool makeBuffer = true; bool makeBuffer = true;
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
if ( mode == INPUT ) { if ( isDuplexInput && stream_.deviceBuffer ) {
if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); if ( bufferBytes <= bytesOut ) makeBuffer = false;
if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
} }
if ( makeBuffer ) { if ( makeBuffer ) {
@ -3127,18 +3212,8 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
} }
} }
stream_.sampleRate = sampleRate;
stream_.device[mode] = device;
stream_.state = STREAM_STOPPED;
asioCallbackInfo = &stream_.callbackInfo;
stream_.callbackInfo.object = (void *) this;
if ( stream_.mode == OUTPUT && mode == INPUT )
// We had already set up an output stream.
stream_.mode = DUPLEX;
else
stream_.mode = mode;
// Determine device latencies // Determine device latencies
long inputLatency, outputLatency;
result = ASIOGetLatencies( &inputLatency, &outputLatency ); result = ASIOGetLatencies( &inputLatency, &outputLatency );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency.";
@ -3158,32 +3233,38 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
return SUCCESS; return SUCCESS;
error: error:
if ( buffersAllocated ) if ( !isDuplexInput ) {
ASIODisposeBuffers(); // the cleanup for error in the duplex input, is done by RtApi::openStream
drivers.removeCurrentDriver(); // So we clean up for single channel only
if ( handle ) { if ( buffersAllocated )
CloseHandle( handle->condition ); ASIODisposeBuffers();
if ( handle->bufferInfos )
free( handle->bufferInfos );
delete handle;
stream_.apiHandle = 0;
}
for ( int i=0; i<2; i++ ) { drivers.removeCurrentDriver();
if ( stream_.userBuffer[i] ) {
free( stream_.userBuffer[i] ); if ( handle ) {
stream_.userBuffer[i] = 0; CloseHandle( handle->condition );
if ( handle->bufferInfos )
free( handle->bufferInfos );
delete handle;
stream_.apiHandle = 0;
}
if ( stream_.userBuffer[mode] ) {
free( stream_.userBuffer[mode] );
stream_.userBuffer[mode] = 0;
}
if ( stream_.deviceBuffer ) {
free( stream_.deviceBuffer );
stream_.deviceBuffer = 0;
} }
} }
if ( stream_.deviceBuffer ) {
free( stream_.deviceBuffer );
stream_.deviceBuffer = 0;
}
return FAILURE; return FAILURE;
} }////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RtApiAsio :: closeStream() void RtApiAsio :: closeStream()
{ {
@ -3635,12 +3716,12 @@ public:
outIndex_( 0 ) {} outIndex_( 0 ) {}
~WasapiBuffer() { ~WasapiBuffer() {
delete buffer_; free( buffer_ );
} }
// sets the length of the internal ring buffer // sets the length of the internal ring buffer
void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) { void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
delete buffer_; free( buffer_ );
buffer_ = ( char* ) calloc( bufferSize, formatBytes ); buffer_ = ( char* ) calloc( bufferSize, formatBytes );
@ -3799,7 +3880,7 @@ void convertBufferWasapi( char* outBuffer,
float sampleStep = 1.0f / sampleRatio; float sampleStep = 1.0f / sampleRatio;
float inSampleFraction = 0.0f; float inSampleFraction = 0.0f;
outSampleCount = ( unsigned int ) ( inSampleCount * sampleRatio ); outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio );
// frame-by-frame, copy each relative input sample into it's corresponding output sample // frame-by-frame, copy each relative input sample into it's corresponding output sample
for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )
@ -3945,7 +4026,6 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
RtAudio::DeviceInfo info; RtAudio::DeviceInfo info;
unsigned int captureDeviceCount = 0; unsigned int captureDeviceCount = 0;
unsigned int renderDeviceCount = 0; unsigned int renderDeviceCount = 0;
std::wstring deviceName;
std::string defaultDeviceName; std::string defaultDeviceName;
bool isCaptureDevice = false; bool isCaptureDevice = false;
@ -4048,8 +4128,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit; goto Exit;
} }
deviceName = defaultDeviceNameProp.pwszVal; defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal);
defaultDeviceName = std::string( deviceName.begin(), deviceName.end() );
// name // name
hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore ); hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
@ -4066,8 +4145,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit; goto Exit;
} }
deviceName = deviceNameProp.pwszVal; info.name =convertCharPointerToStdString(deviceNameProp.pwszVal);
info.name = std::string( deviceName.begin(), deviceName.end() );
// is default // is default
if ( isCaptureDevice ) { if ( isCaptureDevice ) {
@ -4110,6 +4188,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) { for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
info.sampleRates.push_back( SAMPLE_RATES[i] ); info.sampleRates.push_back( SAMPLE_RATES[i] );
} }
info.preferredSampleRate = deviceFormat->nSamplesPerSec;
// native format // native format
info.nativeFormats = 0; info.nativeFormats = 0;
@ -5245,14 +5324,11 @@ unsigned int RtApiDs :: getDeviceCount( void )
error( RtAudioError::WARNING ); error( RtAudioError::WARNING );
} }
// Clean out any devices that may have disappeared. // Clean out any devices that may have disappeared (code update submitted by Eli Zehngut).
std::vector< int > indices; for ( unsigned int i=0; i<dsDevices.size(); ) {
for ( unsigned int i=0; i<dsDevices.size(); i++ ) if ( dsDevices[i].found == false ) dsDevices.erase( dsDevices.begin() + i );
if ( dsDevices[i].found == false ) indices.push_back( i ); else i++;
//unsigned int nErased = 0; }
for ( unsigned int i=0; i<indices.size(); i++ )
dsDevices.erase( dsDevices.begin()+indices[i] );
//dsDevices.erase( dsDevices.begin()-nErased++ );
return static_cast<unsigned int>(dsDevices.size()); return static_cast<unsigned int>(dsDevices.size());
} }
@ -5308,8 +5384,12 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
info.sampleRates.clear(); info.sampleRates.clear();
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate && if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate &&
SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) {
info.sampleRates.push_back( SAMPLE_RATES[k] ); info.sampleRates.push_back( SAMPLE_RATES[k] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[k];
}
} }
// Get format information. // Get format information.
@ -6264,6 +6344,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6271,6 +6352,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6279,6 +6361,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6286,6 +6369,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6307,6 +6391,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6399,6 +6484,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6412,6 +6498,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6448,6 +6535,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6509,6 +6597,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6523,6 +6612,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6544,6 +6634,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6582,21 +6673,6 @@ static unsigned __stdcall callbackHandler( void *ptr )
return 0; return 0;
} }
#include "tchar.h"
static std::string convertTChar( LPCTSTR name )
{
#if defined( UNICODE ) || defined( _UNICODE )
int length = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
std::string s( length-1, '\0' );
WideCharToMultiByte(CP_UTF8, 0, name, -1, &s[0], length, NULL, NULL);
#else
std::string s( name );
#endif
return s;
}
static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
LPCTSTR description, LPCTSTR description,
LPCTSTR /*module*/, LPCTSTR /*module*/,
@ -6638,7 +6714,7 @@ static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
} }
// If good device, then save its name and guid. // If good device, then save its name and guid.
std::string name = convertTChar( description ); std::string name = convertCharPointerToStdString( description );
//if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" ) //if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
if ( lpguid == NULL ) if ( lpguid == NULL )
name = "Default Device"; name = "Default Device";
@ -6820,6 +6896,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Count cards and devices // Count cards and devices
card = -1; card = -1;
subdevice = -1;
snd_card_next( &card ); snd_card_next( &card );
while ( card >= 0 ) { while ( card >= 0 ) {
sprintf( name, "hw:%d", card ); sprintf( name, "hw:%d", card );
@ -7033,8 +7110,12 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Test our discrete set of sample rate values. // Test our discrete set of sample rate values.
info.sampleRates.clear(); info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) { for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 ) if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 ) {
info.sampleRates.push_back( SAMPLE_RATES[i] ); info.sampleRates.push_back( SAMPLE_RATES[i] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[i];
}
} }
if ( info.sampleRates.size() == 0 ) { if ( info.sampleRates.size() == 0 ) {
snd_pcm_close( phandle ); snd_pcm_close( phandle );
@ -7959,6 +8040,8 @@ void RtApiAlsa :: callbackEvent()
errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << "."; errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
} }
else
errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun.";
} }
else { else {
errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << "."; errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
@ -8067,6 +8150,7 @@ RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ )
for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
info.sampleRates.push_back( *sr ); info.sampleRates.push_back( *sr );
info.preferredSampleRate = 48000;
info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32; info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
return info; return info;
@ -8429,7 +8513,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
pah = static_cast<PulseAudioHandle *>( stream_.apiHandle ); pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
int error; int error;
if ( !options->streamName.empty() ) streamName = options->streamName; if ( options && !options->streamName.empty() ) streamName = options->streamName;
switch ( mode ) { switch ( mode ) {
case INPUT: case INPUT:
pa_buffer_attr buffer_attr; pa_buffer_attr buffer_attr;
@ -8635,6 +8719,10 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( ainfo.rates[i] == SAMPLE_RATES[k] ) { if ( ainfo.rates[i] == SAMPLE_RATES[k] ) {
info.sampleRates.push_back( SAMPLE_RATES[k] ); info.sampleRates.push_back( SAMPLE_RATES[k] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[k];
break; break;
} }
} }
@ -8643,8 +8731,12 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
else { else {
// Check min and max rate values; // Check min and max rate values;
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] ) if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] ) {
info.sampleRates.push_back( SAMPLE_RATES[k] ); info.sampleRates.push_back( SAMPLE_RATES[k] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[k];
}
} }
} }

View file

@ -310,12 +310,13 @@ class RtAudio
bool isDefaultOutput; /*!< true if this is the default output device. */ bool isDefaultOutput; /*!< true if this is the default output device. */
bool isDefaultInput; /*!< true if this is the default input device. */ bool isDefaultInput; /*!< true if this is the default input device. */
std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */ std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
unsigned int preferredSampleRate; /*!< Preferred sample rate, eg. for WASAPI the system sample rate. */
RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
// Default constructor. // Default constructor.
DeviceInfo() DeviceInfo()
:probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {} isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {}
}; };
//! The structure for specifying input or ouput stream parameters. //! The structure for specifying input or ouput stream parameters.

View file

@ -388,7 +388,7 @@ void VideoStreamTheoraplayer::pop_frame(Ref<ImageTexture> p_tex) {
{ {
DVector<uint8_t>::Write wr = data.write(); DVector<uint8_t>::Write wr = data.write();
uint8_t* ptr = wr.ptr(); uint8_t* ptr = wr.ptr();
memcpy(ptr, f->getBuffer(), imgsize); copymem(ptr, f->getBuffer(), imgsize);
} }
/* /*
for (int i=0; i<h; i++) { for (int i=0; i<h; i++) {

View file

@ -1160,7 +1160,7 @@ void _vp_couple_quantize_normalize(int blobno,
However, this is a temporary patch. However, this is a temporary patch.
by Aoyumi @ 2004/04/18 by Aoyumi @ 2004/04/18
*/ */
/*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit))); /*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit))); */
/* elliptical /* elliptical
if(reM[j]+reA[j]<0){ if(reM[j]+reA[j]<0){
reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate); reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);

View file

@ -167,6 +167,7 @@ Error DirAccessWindows::change_dir(String p_dir) {
if (worked) { if (worked) {
GetCurrentDirectoryW(2048,real_current_dir_name); GetCurrentDirectoryW(2048,real_current_dir_name);
current_dir=real_current_dir_name; // TODO, utf8 parser current_dir=real_current_dir_name; // TODO, utf8 parser
current_dir=current_dir.replace("\\","/"); current_dir=current_dir.replace("\\","/");
@ -190,9 +191,9 @@ Error DirAccessWindows::make_dir(String p_dir) {
#else #else
//p_dir=fix_path(p_dir); p_dir=fix_path(p_dir);
p_dir.replace("/","\\"); //p_dir.replace("/","\\");
bool success; bool success;
int err; int err;
@ -249,14 +250,14 @@ bool DirAccessWindows::file_exists(String p_file) {
p_file=fix_path(p_file); p_file=fix_path(p_file);
p_file.replace("/","\\"); //p_file.replace("/","\\");
WIN32_FILE_ATTRIBUTE_DATA fileInfo; //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr; DWORD fileAttr;
fileAttr = GetFileAttributesExW(p_file.c_str(), GetFileExInfoStandard, &fileInfo); fileAttr = GetFileAttributesW(p_file.c_str());
if (0 == fileAttr) if (INVALID_FILE_ATTRIBUTES == fileAttr)
return false; return false;
return !(fileAttr&FILE_ATTRIBUTE_DIRECTORY); return !(fileAttr&FILE_ATTRIBUTE_DIRECTORY);
@ -272,17 +273,16 @@ bool DirAccessWindows::dir_exists(String p_dir) {
else else
p_dir=fix_path(p_dir); p_dir=fix_path(p_dir);
p_dir.replace("/","\\"); //p_dir.replace("/","\\");
WIN32_FILE_ATTRIBUTE_DATA fileInfo; //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr; DWORD fileAttr;
fileAttr = GetFileAttributesExW(p_dir.c_str(), GetFileExInfoStandard, &fileInfo); fileAttr = GetFileAttributesW(p_dir.c_str());
if (0 == fileAttr) if (INVALID_FILE_ATTRIBUTES == fileAttr)
return false; return false;
return (fileAttr&FILE_ATTRIBUTE_DIRECTORY); return (fileAttr&FILE_ATTRIBUTE_DIRECTORY);
} }
@ -313,12 +313,15 @@ Error DirAccessWindows::remove(String p_path) {
p_path=fix_path(p_path); p_path=fix_path(p_path);
printf("erasing %s\n",p_path.utf8().get_data()); printf("erasing %s\n",p_path.utf8().get_data());
WIN32_FILE_ATTRIBUTE_DATA fileInfo; //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo); //DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
if (fileAttr == INVALID_FILE_ATTRIBUTES)
return FAILED;
if (fileAttr & FILE_ATTRIBUTE_DIRECTORY) DWORD fileAttr;
fileAttr = GetFileAttributesW(p_path.c_str());
if (INVALID_FILE_ATTRIBUTES == fileAttr)
return FAILED;
if ((fileAttr&FILE_ATTRIBUTE_DIRECTORY))
return ::_wrmdir(p_path.c_str())==0?OK:FAILED; return ::_wrmdir(p_path.c_str())==0?OK:FAILED;
else else
return ::_wunlink(p_path.c_str())==0?OK:FAILED; return ::_wunlink(p_path.c_str())==0?OK:FAILED;

View file

@ -251,7 +251,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
packed_data = memnew(PackedData); packed_data = memnew(PackedData);
#ifdef MINIZIP_ENABLED #ifdef MINIZIP_ENABLED
//XXX: always get_singleton() == 0x0
zip_packed_data = ZipArchive::get_singleton(); zip_packed_data = ZipArchive::get_singleton();
//TODO: remove this temporary fix
if (!zip_packed_data) {
zip_packed_data = memnew(ZipArchive);
}
packed_data->add_pack_source(zip_packed_data); packed_data->add_pack_source(zip_packed_data);
#endif #endif
@ -748,12 +755,12 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
if (file_access_network_client) if (file_access_network_client)
memdelete(file_access_network_client); memdelete(file_access_network_client);
if (packed_data) // Note 1: *zip_packed_data live into *packed_data
memdelete( packed_data ); // Note 2: PackedData::~PackedData destroy this.
#ifdef MINIZIP_ENABLED //#ifdef MINIZIP_ENABLED
if (zip_packed_data) // if (zip_packed_data)
memdelete( zip_packed_data ); // memdelete( zip_packed_data );
#endif //#endif
unregister_core_types(); unregister_core_types();

View file

@ -88,6 +88,7 @@ const char *GDFunctions::get_func_name(Function p_func) {
"str", "str",
"print", "print",
"printt", "printt",
"prints",
"printerr", "printerr",
"printraw", "printraw",
"var2str", "var2str",
@ -561,6 +562,22 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
r_ret=Variant(); r_ret=Variant();
} break;
case TEXT_PRINT_SPACED: {
String str;
for(int i=0;i<p_arg_count;i++) {
if (i)
str+=" ";
str+=p_args[i]->operator String();
}
//str+="\n";
print_line(str);
r_ret=Variant();
} break; } break;
case TEXT_PRINTERR: { case TEXT_PRINTERR: {
@ -1251,6 +1268,13 @@ MethodInfo GDFunctions::get_info(Function p_func) {
mi.return_val.type=Variant::NIL; mi.return_val.type=Variant::NIL;
return mi; return mi;
} break;
case TEXT_PRINT_SPACED: {
MethodInfo mi("prints",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
mi.return_val.type=Variant::NIL;
return mi;
} break; } break;
case TEXT_PRINTERR: { case TEXT_PRINTERR: {

View file

@ -84,6 +84,7 @@ public:
TEXT_STR, TEXT_STR,
TEXT_PRINT, TEXT_PRINT,
TEXT_PRINT_TABBED, TEXT_PRINT_TABBED,
TEXT_PRINT_SPACED,
TEXT_PRINTERR, TEXT_PRINTERR,
TEXT_PRINTRAW, TEXT_PRINTRAW,
VAR_TO_STR, VAR_TO_STR,

View file

@ -1036,7 +1036,7 @@ void GDTokenizerText::advance(int p_amount) {
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
#define BYTECODE_VERSION 3 #define BYTECODE_VERSION 4
Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) { Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {

View file

@ -26,7 +26,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
* Copyright (C) 2010 The Android Open Source Project /* Copyright (C) 2010 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -225,6 +225,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
static void _device_poll_thread(void *ud); static void _device_poll_thread(void *ud);
String get_package_name();
String get_project_name() const; String get_project_name() const;
void _fix_manifest(Vector<uint8_t>& p_manifest); void _fix_manifest(Vector<uint8_t>& p_manifest);
void _fix_resources(Vector<uint8_t>& p_manifest); void _fix_resources(Vector<uint8_t>& p_manifest);
@ -756,7 +758,7 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {
if (tname=="manifest" && attrname=="package") { if (tname=="manifest" && attrname=="package") {
print_line("FOUND PACKAGE"); print_line("FOUND PACKAGE");
string_table[attr_value]=package; string_table[attr_value]=get_package_name();
} }
//print_line("tname: "+tname); //print_line("tname: "+tname);
@ -1169,7 +1171,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
if (apk_expansion) { if (apk_expansion) {
String apkfname="main."+itos(version_code)+"."+package+".obb"; String apkfname="main."+itos(version_code)+"."+get_package_name()+".obb";
String fullpath=p_path.get_base_dir().plus_file(apkfname); String fullpath=p_path.get_base_dir().plus_file(apkfname);
FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE); FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE);
if (!pf) { if (!pf) {
@ -1514,7 +1516,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
args.push_back("-s"); args.push_back("-s");
args.push_back(devices[p_device].id); args.push_back(devices[p_device].id);
args.push_back("uninstall"); args.push_back("uninstall");
args.push_back(package); args.push_back(get_package_name());
err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
#if 0 #if 0
@ -1552,7 +1554,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
args.push_back("-a"); args.push_back("-a");
args.push_back("android.intent.action.MAIN"); args.push_back("android.intent.action.MAIN");
args.push_back("-n"); args.push_back("-n");
args.push_back(package+"/com.android.godot.Godot"); args.push_back(get_package_name()+"/com.android.godot.Godot");
err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
if (err || rv!=0) { if (err || rv!=0) {
@ -1564,12 +1566,37 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
return OK; return OK;
} }
String EditorExportPlatformAndroid::get_package_name() {
String pname = package;
String basename = Globals::get_singleton()->get("application/name");
basename=basename.to_lower();
String name;
bool first=true;
for(int i=0;i<basename.length();i++) {
CharType c = basename[i];
if (c>='0' && c<='9' && first) {
continue;
}
if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9')) {
name+=String::chr(c);
first=false;
}
}
if (name=="")
name="noname";
pname=pname.replace("$genname",name);
return pname;
}
EditorExportPlatformAndroid::EditorExportPlatformAndroid() { EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
version_code=1; version_code=1;
version_name="1.0"; version_name="1.0";
package="com.android.noname"; package="org.godotengine.$genname";
name=""; name="";
_signed=true; _signed=true;
apk_expansion=false; apk_expansion=false;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -966,8 +966,10 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
[NSApp activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
[window_object makeKeyAndOrderFront:nil]; [window_object makeKeyAndOrderFront:nil];
if (p_desired.fullscreen)
zoomed = true;
/*** END OSX INITIALIZATION ***/ /*** END OSX INITIALIZATION ***/
/*** END OSX INITIALIZATION ***/ /*** END OSX INITIALIZATION ***/
@ -1310,14 +1312,22 @@ void OS_OSX::set_window_size(const Size2 p_size) {
void OS_OSX::set_window_fullscreen(bool p_enabled) { void OS_OSX::set_window_fullscreen(bool p_enabled) {
[window_object performZoom:nil]; if (zoomed != p_enabled) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
[window_object toggleFullScreen:nil];
#else
[window_object performZoom:nil];
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
}
zoomed = p_enabled; zoomed = p_enabled;
}; };
bool OS_OSX::is_window_fullscreen() const { bool OS_OSX::is_window_fullscreen() const {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
if ( [window_object respondsToSelector:@selector(isZoomed)] ) if ( [window_object respondsToSelector:@selector(isZoomed)] )
return [window_object isZoomed]; return [window_object isZoomed];
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
return zoomed; return zoomed;
}; };
@ -1509,6 +1519,11 @@ void OS_OSX::run() {
main_loop->init(); main_loop->init();
if (zoomed) {
zoomed = false;
set_window_fullscreen(true);
}
// uint64_t last_ticks=get_ticks_usec(); // uint64_t last_ticks=get_ticks_usec();
// int frames=0; // int frames=0;

View file

@ -12,3 +12,9 @@ common_win=[
] ]
env.Program('#bin/godot',['godot_win.cpp']+common_win,PROGSUFFIX=env["PROGSUFFIX"]) env.Program('#bin/godot',['godot_win.cpp']+common_win,PROGSUFFIX=env["PROGSUFFIX"])
# Microsoft Visual Studio Project Generation
if (env['vsproj'])=="yes":
env.vs_srcs = env.vs_srcs + ["platform/windows/godot_win.cpp"]
for x in common_win:
env.vs_srcs = env.vs_srcs + ["platform/windows/" + x]

View file

@ -204,7 +204,7 @@ def configure(env):
elif (env["target"]=="debug"): elif (env["target"]=="debug"):
env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED','/DD3D_DEBUG_INFO','/O1']) env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED','/DD3D_DEBUG_INFO','/Od'])
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
env.Append(LINKFLAGS=['/DEBUG']) env.Append(LINKFLAGS=['/DEBUG'])

View file

@ -115,29 +115,24 @@ PCHAR*
return argv; return argv;
} }
char* mb_to_utf8(const char* mbs) { char* wc_to_utf8(const wchar_t* wc) {
int ulen = WideCharToMultiByte(CP_UTF8,0,wc,-1,NULL,0,NULL,NULL);
int wlen = MultiByteToWideChar(CP_ACP,0,mbs,-1,NULL,0); // returns 0 if failed
wchar_t *wbuf = new wchar_t[wlen + 1];
MultiByteToWideChar(CP_ACP,0,mbs,-1,wbuf,wlen);
wbuf[wlen]=0;
int ulen = WideCharToMultiByte(CP_UTF8,0,wbuf,-1,NULL,0,NULL,NULL);
char * ubuf = new char[ulen + 1]; char * ubuf = new char[ulen + 1];
WideCharToMultiByte(CP_UTF8,0,wbuf,-1,ubuf,ulen,NULL,NULL); WideCharToMultiByte(CP_UTF8,0,wc,-1,ubuf,ulen,NULL,NULL);
ubuf[ulen] = 0; ubuf[ulen] = 0;
return ubuf; return ubuf;
} }
int main(int argc, char** argv) { int widechar_main(int argc, wchar_t** argv) {
OS_Windows os(NULL); OS_Windows os(NULL);
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
char ** argv_utf8 = new char*[argc]; char ** argv_utf8 = new char*[argc];
for(int i=0; i<argc; ++i) { for(int i=0; i<argc; ++i) {
argv_utf8[i] = mb_to_utf8(argv[i]); argv_utf8[i] = wc_to_utf8(argv[i]);
} }
Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]); Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]);
@ -154,82 +149,30 @@ int main(int argc, char** argv) {
return os.get_exit_code(); return os.get_exit_code();
}; };
int main(int _argc, char** _argv) {
// _argc and _argv are ignored
// we are going to use the WideChar version of them instead
LPWSTR *wc_argv;
int argc;
int result;
wc_argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if( NULL == wc_argv ) {
wprintf(L"CommandLineToArgvW failed\n");
return 0;
}
result = widechar_main(argc, wc_argv);
LocalFree(wc_argv);
return result;
}
HINSTANCE godot_hinstance = NULL; HINSTANCE godot_hinstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
godot_hinstance = hInstance;
int argc; return main(0,NULL);
char** argv;
char* arg;
int index;
int result;
// count the arguments
argc = 1;
arg = lpCmdLine;
while (arg[0] != 0) {
while (arg[0] != 0 && arg[0] == ' ') {
arg++;
}
if (arg[0] != 0) {
argc++;
while (arg[0] != 0 && arg[0] != ' ') {
arg++;
}
}
}
// tokenize the arguments
argv = (char**)malloc(argc * sizeof(char*));
arg = lpCmdLine;
index = 1;
while (arg[0] != 0) {
while (arg[0] != 0 && arg[0] == ' ') {
arg++;
}
if (arg[0] != 0) {
argv[index] = arg;
index++;
while (arg[0] != 0 && arg[0] != ' ') {
arg++;
}
if (arg[0] != 0) {
arg[0] = 0;
arg++;
}
}
}
// put the program name into argv[0]
char filename[_MAX_PATH];
GetModuleFileName(NULL, filename, _MAX_PATH);
argv[0] = filename;
// call the user specified main function
result = main(argc, argv);
free(argv);
return result;
} }

View file

@ -2117,12 +2117,13 @@ bool OS_Windows::has_environment(const String& p_var) const {
String OS_Windows::get_environment(const String& p_var) const { String OS_Windows::get_environment(const String& p_var) const {
char* val = getenv(p_var.utf8().get_data()); wchar_t wval[0x7Fff]; // MSDN says 32767 char is the maximum
if (val) int wlen = GetEnvironmentVariableW(p_var.c_str(),wval,0x7Fff);
return val; if ( wlen > 0 ) {
return wval;
}
return ""; return "";
}; }
String OS_Windows::get_stdin_string(bool p_block) { String OS_Windows::get_stdin_string(bool p_block) {

View file

@ -317,8 +317,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
/* set the name and class hints for the window manager to use */ /* set the name and class hints for the window manager to use */
classHint = XAllocClassHint(); classHint = XAllocClassHint();
if (classHint) { if (classHint) {
classHint->res_name = "Godot"; classHint->res_name = (char *)"Godot";
classHint->res_class = "Godot"; classHint->res_class = (char *)"Godot";
} }
XSetClassHint(x11_display, x11_window, classHint); XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint); XFree(classHint);

View file

@ -512,6 +512,29 @@ bool Area2D::overlaps_body(Node* p_body) const{
} }
void Area2D::set_collision_mask(uint32_t p_mask) {
collision_mask=p_mask;
Physics2DServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask);
}
uint32_t Area2D::get_collision_mask() const {
return collision_mask;
}
void Area2D::set_layer_mask(uint32_t p_mask) {
layer_mask=p_mask;
Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask);
}
uint32_t Area2D::get_layer_mask() const {
return layer_mask;
}
void Area2D::_bind_methods() { void Area2D::_bind_methods() {
@ -542,6 +565,12 @@ void Area2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_priority); ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area2D::get_priority); ObjectTypeDB::bind_method(_MD("get_priority"),&Area2D::get_priority);
ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area2D::set_collision_mask);
ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area2D::get_collision_mask);
ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area2D::get_layer_mask);
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring); ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring);
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled); ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled);
@ -578,6 +607,8 @@ void Area2D::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority")); ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
} }
@ -593,9 +624,10 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea
priority=0; priority=0;
monitoring=false; monitoring=false;
monitorable=false; monitorable=false;
collision_mask=1;
layer_mask=1;
set_enable_monitoring(true); set_enable_monitoring(true);
set_monitorable(true); set_monitorable(true);
} }
Area2D::~Area2D() { Area2D::~Area2D() {

View file

@ -51,6 +51,8 @@ private:
bool gravity_is_point; bool gravity_is_point;
real_t linear_damp; real_t linear_damp;
real_t angular_damp; real_t angular_damp;
uint32_t collision_mask;
uint32_t layer_mask;
int priority; int priority;
bool monitoring; bool monitoring;
bool monitorable; bool monitorable;
@ -151,6 +153,12 @@ public:
void set_monitorable(bool p_enable); void set_monitorable(bool p_enable);
bool is_monitorable() const; bool is_monitorable() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
Array get_overlapping_bodies() const; //function for script Array get_overlapping_bodies() const; //function for script
Array get_overlapping_areas() const; //function for script Array get_overlapping_areas() const; //function for script

View file

@ -132,8 +132,7 @@ Matrix32 Camera2D::get_camera_transform() {
} }
Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());; Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());
screen_offset;
float angle = get_global_transform().get_rotation(); float angle = get_global_transform().get_rotation();
if(rotating){ if(rotating){

View file

@ -32,6 +32,7 @@ void Navigation2D::_navpoly_link(int p_id) {
p.edges.resize(plen); p.edges.resize(plen);
Vector2 center; Vector2 center;
float sum=0;
for(int j=0;j<plen;j++) { for(int j=0;j<plen;j++) {
@ -46,8 +47,23 @@ void Navigation2D::_navpoly_link(int p_id) {
center+=ep; center+=ep;
e.point=_get_point(ep); e.point=_get_point(ep);
p.edges[j]=e; p.edges[j]=e;
int idxn = indices[(j+1)%plen];
if (idxn<0 || idxn>=len) {
valid=false;
break;
}
Vector2 epn = nm.xform.xform(r[idxn]);
sum+=(epn.x-ep.x)*(epn.y+ep.y);
} }
p.clockwise=sum>0;
if (!valid) { if (!valid) {
nm.polygons.pop_back(); nm.polygons.pop_back();
ERR_CONTINUE(!valid); ERR_CONTINUE(!valid);
@ -493,17 +509,30 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
left = _get_vertex(p->edges[prev].point); left = _get_vertex(p->edges[prev].point);
right = _get_vertex(p->edges[prev_n].point); right = _get_vertex(p->edges[prev_n].point);
if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ if (p->clockwise) {
SWAP(left,right); SWAP(left,right);
} }
/*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){
SWAP(left,right);
}*/
} }
bool skip=false; bool skip=false;
/* print_line("-----\nAPEX: "+(apex_point-end_point));
print_line("LEFT:");
print_line("\tPortal: "+(portal_left-end_point));
print_line("\tPoint: "+(left-end_point));
print_line("\tFree: "+itos(CLOCK_TANGENT(apex_point,portal_left,left) >= 0));
print_line("RIGHT:");
print_line("\tPortal: "+(portal_right-end_point));
print_line("\tPoint: "+(right-end_point));
print_line("\tFree: "+itos(CLOCK_TANGENT(apex_point,portal_right,right) <= 0));
*/
if (CLOCK_TANGENT(apex_point,portal_left,left) >= 0){ if (CLOCK_TANGENT(apex_point,portal_left,left) >= 0){
//process //process
if (portal_left==apex_point || CLOCK_TANGENT(apex_point,left,portal_right) > 0) { if (portal_left.distance_squared_to(apex_point)<CMP_EPSILON || CLOCK_TANGENT(apex_point,left,portal_right) > 0) {
left_poly=p; left_poly=p;
portal_left=left; portal_left=left;
} else { } else {
@ -519,12 +548,13 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON) if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON)
path.push_back(apex_point); path.push_back(apex_point);
skip=true; skip=true;
//print_line("addpoint left");
} }
} }
if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){ if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){
//process //process
if (portal_right==apex_point || CLOCK_TANGENT(apex_point,right,portal_left) < 0) { if (portal_right.distance_squared_to(apex_point)<CMP_EPSILON || CLOCK_TANGENT(apex_point,right,portal_left) < 0) {
right_poly=p; right_poly=p;
portal_right=right; portal_right=right;
} else { } else {
@ -539,6 +569,8 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
portal_left=apex_point; portal_left=apex_point;
if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON) if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON)
path.push_back(apex_point); path.push_back(apex_point);
//print_line("addpoint right");
} }
} }

View file

@ -60,6 +60,8 @@ class Navigation2D : public Node2D {
float distance; float distance;
int prev_edge; int prev_edge;
bool clockwise;
NavMesh *owner; NavMesh *owner;
}; };

View file

@ -68,17 +68,34 @@ float PhysicsBody2D::get_one_way_collision_max_depth() const{
} }
void PhysicsBody2D::_set_layers(uint32_t p_mask) {
set_layer_mask(p_mask);
set_collision_mask(p_mask);
}
uint32_t PhysicsBody2D::_get_layers() const{
return get_layer_mask();
}
void PhysicsBody2D::_bind_methods() { void PhysicsBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody2D::set_collision_mask);
ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody2D::get_collision_mask);
ObjectTypeDB::bind_method(_MD("_set_layers","mask"),&PhysicsBody2D::_set_layers);
ObjectTypeDB::bind_method(_MD("_get_layers"),&PhysicsBody2D::_get_layers);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction); ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction); ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with); ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with);
ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with); ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with);
ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS,"",0),_SCS("_set_layers"),_SCS("_get_layers")); //for backwards compat
ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction")); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction"));
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth")); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth"));
} }
@ -94,9 +111,22 @@ uint32_t PhysicsBody2D::get_layer_mask() const {
return mask; return mask;
} }
void PhysicsBody2D::set_collision_mask(uint32_t p_mask) {
collision_mask=p_mask;
Physics2DServer::get_singleton()->body_set_collision_mask(get_rid(),p_mask);
}
uint32_t PhysicsBody2D::get_collision_mask() const {
return collision_mask;
}
PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
mask=1; mask=1;
collision_mask=1;
set_one_way_collision_max_depth(0); set_one_way_collision_max_depth(0);
set_pickable(false); set_pickable(false);
@ -909,6 +939,19 @@ Variant KinematicBody2D::_get_collider() const {
return obj; return obj;
} }
void KinematicBody2D::revert_motion() {
Matrix32 gt = get_global_transform();
gt.elements[2]-=travel;
travel=Vector2();
set_global_transform(gt);
}
Vector2 KinematicBody2D::get_travel() const {
return travel;
}
Vector2 KinematicBody2D::move(const Vector2& p_motion) { Vector2 KinematicBody2D::move(const Vector2& p_motion) {
@ -926,6 +969,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
Matrix32 gt = get_global_transform(); Matrix32 gt = get_global_transform();
gt.elements[2]+=result.motion; gt.elements[2]+=result.motion;
set_global_transform(gt); set_global_transform(gt);
travel=result.motion;
return result.remainder; return result.remainder;
#else #else
@ -1157,6 +1201,8 @@ void KinematicBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to); ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to);
ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move); ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move);
ObjectTypeDB::bind_method(_MD("get_travel"),&KinematicBody2D::get_travel);
ObjectTypeDB::bind_method(_MD("revert_motion"),&KinematicBody2D::revert_motion);
ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding); ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding);

View file

@ -39,8 +39,14 @@ class PhysicsBody2D : public CollisionObject2D {
OBJ_TYPE(PhysicsBody2D,CollisionObject2D); OBJ_TYPE(PhysicsBody2D,CollisionObject2D);
uint32_t mask; uint32_t mask;
uint32_t collision_mask;
Vector2 one_way_collision_direction; Vector2 one_way_collision_direction;
float one_way_collision_max_depth; float one_way_collision_max_depth;
void _set_layers(uint32_t p_mask);
uint32_t _get_layers() const;
protected: protected:
void _notification(int p_what); void _notification(int p_what);
@ -52,6 +58,9 @@ public:
void set_layer_mask(uint32_t p_mask); void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const; uint32_t get_layer_mask() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
void add_collision_exception_with(Node* p_node); //must be physicsbody void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node); void remove_collision_exception_with(Node* p_node);
@ -276,6 +285,7 @@ class KinematicBody2D : public PhysicsBody2D {
ObjectID collider; ObjectID collider;
int collider_shape; int collider_shape;
Variant collider_metadata; Variant collider_metadata;
Vector2 travel;
Variant _get_collider() const; Variant _get_collider() const;
@ -290,6 +300,10 @@ public:
bool test_move(const Vector2& p_motion); bool test_move(const Vector2& p_motion);
bool is_colliding() const; bool is_colliding() const;
Vector2 get_travel() const;
void revert_motion();
Vector2 get_collision_pos() const; Vector2 get_collision_pos() const;
Vector2 get_collision_normal() const; Vector2 get_collision_normal() const;
Vector2 get_collider_velocity() const; Vector2 get_collider_velocity() const;

View file

@ -519,6 +519,7 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const
q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC); q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC);
Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID()); Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID());
Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer);
Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask);
Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction);
Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,bounce);
@ -790,7 +791,7 @@ Rect2 TileMap::get_item_rect() const {
return rect_cache; return rect_cache;
} }
void TileMap::set_collision_layer_mask(uint32_t p_layer) { void TileMap::set_collision_layer(uint32_t p_layer) {
collision_layer=p_layer; collision_layer=p_layer;
for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
@ -800,6 +801,16 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) {
} }
} }
void TileMap::set_collision_mask(uint32_t p_mask) {
collision_mask=p_mask;
for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
Quadrant &q=E->get();
Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask);
}
}
bool TileMap::get_collision_use_kinematic() const{ bool TileMap::get_collision_use_kinematic() const{
return use_kinematic; return use_kinematic;
@ -844,11 +855,16 @@ float TileMap::get_collision_bounce() const{
} }
uint32_t TileMap::get_collision_layer_mask() const { uint32_t TileMap::get_collision_layer() const {
return collision_layer; return collision_layer;
} }
uint32_t TileMap::get_collision_mask() const {
return collision_mask;
}
void TileMap::set_mode(Mode p_mode) { void TileMap::set_mode(Mode p_mode) {
_clear_quadrants(); _clear_quadrants();
@ -1077,8 +1093,11 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic); ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic);
ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic); ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic);
ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); ObjectTypeDB::bind_method(_MD("set_collision_layer","mask"),&TileMap::set_collision_layer);
ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); ObjectTypeDB::bind_method(_MD("get_collision_layer"),&TileMap::get_collision_layer);
ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&TileMap::set_collision_mask);
ObjectTypeDB::bind_method(_MD("get_collision_mask"),&TileMap::get_collision_mask);
ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction);
ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction);
@ -1117,7 +1136,9 @@ void TileMap::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer"),_SCS("get_collision_layer"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data"));
ADD_SIGNAL(MethodInfo("settings_changed")); ADD_SIGNAL(MethodInfo("settings_changed"));
@ -1146,6 +1167,7 @@ TileMap::TileMap() {
center_x=false; center_x=false;
center_y=false; center_y=false;
collision_layer=1; collision_layer=1;
collision_mask=1;
friction=1; friction=1;
bounce=0; bounce=0;
mode=MODE_SQUARE; mode=MODE_SQUARE;

View file

@ -146,6 +146,8 @@ private:
float friction; float friction;
float bounce; float bounce;
uint32_t collision_layer; uint32_t collision_layer;
uint32_t collision_mask;
TileOrigin tile_origin; TileOrigin tile_origin;
void _fix_cell_transform(Matrix32& xform, const Cell& p_cell, const Vector2 &p_offset, const Size2 &p_sc); void _fix_cell_transform(Matrix32& xform, const Cell& p_cell, const Vector2 &p_offset, const Size2 &p_sc);
@ -207,8 +209,11 @@ public:
Rect2 get_item_rect() const; Rect2 get_item_rect() const;
void set_collision_layer_mask(uint32_t p_layer); void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer_mask() const; uint32_t get_collision_layer() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
void set_collision_use_kinematic(bool p_use_kinematic); void set_collision_use_kinematic(bool p_use_kinematic);
bool get_collision_use_kinematic() const; bool get_collision_use_kinematic() const;

View file

@ -30,6 +30,7 @@ void Navigation::_navmesh_link(int p_id) {
p.edges.resize(plen); p.edges.resize(plen);
Vector3 center; Vector3 center;
float sum=0;
for(int j=0;j<plen;j++) { for(int j=0;j<plen;j++) {
@ -44,8 +45,19 @@ void Navigation::_navmesh_link(int p_id) {
center+=ep; center+=ep;
e.point=_get_point(ep); e.point=_get_point(ep);
p.edges[j]=e; p.edges[j]=e;
if (j>=2) {
Vector3 epa = nm.xform.xform(r[indices[j-2]]);
Vector3 epb = nm.xform.xform(r[indices[j-1]]);
sum+=up.dot((epb-epa).cross(ep-epa));
}
} }
p.clockwise=sum>0;
if (!valid) { if (!valid) {
nm.polygons.pop_back(); nm.polygons.pop_back();
ERR_CONTINUE(!valid); ERR_CONTINUE(!valid);
@ -399,7 +411,8 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3& p_start, const Vector
left = _get_vertex(p->edges[prev].point); left = _get_vertex(p->edges[prev].point);
right = _get_vertex(p->edges[prev_n].point); right = _get_vertex(p->edges[prev_n].point);
if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){ //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
if (p->clockwise) {
SWAP(left,right); SWAP(left,right);
} }
} }

View file

@ -59,6 +59,8 @@ class Navigation : public Spatial {
float distance; float distance;
int prev_edge; int prev_edge;
bool clockwise;
NavMesh *owner; NavMesh *owner;
}; };

View file

@ -292,7 +292,7 @@ SpriteBase3D::SpriteBase3D() {
parent_sprite=NULL; parent_sprite=NULL;
pI=NULL; pI=NULL;
for(int i=0;i<4;i++) for(int i=0;i<FLAG_MAX;i++)
flags[i]=i==FLAG_TRANSPARENT; flags[i]=i==FLAG_TRANSPARENT;
axis=Vector3::AXIS_Z; axis=Vector3::AXIS_Z;

View file

@ -29,6 +29,81 @@
#include "tween.h" #include "tween.h"
#include "method_bind_ext.inc" #include "method_bind_ext.inc"
void Tween::_add_pending_command(StringName p_key
,const Variant& p_arg1 ,const Variant& p_arg2 ,const Variant& p_arg3 ,const Variant& p_arg4 ,const Variant& p_arg5
,const Variant& p_arg6 ,const Variant& p_arg7 ,const Variant& p_arg8 ,const Variant& p_arg9 ,const Variant& p_arg10
) {
pending_commands.push_back(PendingCommand());
PendingCommand& cmd = pending_commands.back()->get();
cmd.key = p_key;
int& count = cmd.args;
if(p_arg10.get_type() != Variant::NIL)
count = 10;
else if(p_arg9.get_type() != Variant::NIL)
count = 9;
else if(p_arg8.get_type() != Variant::NIL)
count = 8;
else if(p_arg7.get_type() != Variant::NIL)
count = 7;
else if(p_arg6.get_type() != Variant::NIL)
count = 6;
else if(p_arg5.get_type() != Variant::NIL)
count = 5;
else if(p_arg4.get_type() != Variant::NIL)
count = 4;
else if(p_arg3.get_type() != Variant::NIL)
count = 3;
else if(p_arg2.get_type() != Variant::NIL)
count = 2;
else if(p_arg1.get_type() != Variant::NIL)
count = 1;
if(count > 0)
cmd.arg[0] = p_arg1;
if(count > 1)
cmd.arg[1] = p_arg2;
if(count > 2)
cmd.arg[2] = p_arg3;
if(count > 3)
cmd.arg[3] = p_arg4;
if(count > 4)
cmd.arg[4] = p_arg5;
if(count > 5)
cmd.arg[5] = p_arg6;
if(count > 6)
cmd.arg[6] = p_arg7;
if(count > 7)
cmd.arg[7] = p_arg8;
if(count > 8)
cmd.arg[8] = p_arg9;
if(count > 9)
cmd.arg[9] = p_arg10;
}
void Tween::_process_pending_commands() {
for(List<PendingCommand>::Element *E=pending_commands.front();E;E=E->next()) {
PendingCommand& cmd = E->get();
Variant::CallError err;
Variant *arg[10] = {
&cmd.arg[0],
&cmd.arg[1],
&cmd.arg[2],
&cmd.arg[3],
&cmd.arg[4],
&cmd.arg[5],
&cmd.arg[6],
&cmd.arg[7],
&cmd.arg[8],
&cmd.arg[9],
};
this->call(cmd.key, (const Variant **) arg, cmd.args, err);
}
pending_commands.clear();
}
bool Tween::_set(const StringName& p_name, const Variant& p_value) { bool Tween::_set(const StringName& p_name, const Variant& p_value) {
String name=p_name; String name=p_name;
@ -456,6 +531,8 @@ bool Tween::_apply_tween_value(InterpolateData& p_data, Variant& value) {
void Tween::_tween_process(float p_delta) { void Tween::_tween_process(float p_delta) {
_process_pending_commands();
if (speed_scale == 0) if (speed_scale == 0)
return; return;
p_delta *= speed_scale; p_delta *= speed_scale;
@ -551,8 +628,12 @@ void Tween::_tween_process(float p_delta) {
_apply_tween_value(data, result); _apply_tween_value(data, result);
if(data.finish) if (data.finish) {
emit_signal("tween_complete",object,data.key); emit_signal("tween_complete",object,data.key);
// not repeat mode, remove completed action
if (!repeat)
call_deferred("remove", object, data.key);
}
} }
pending_update --; pending_update --;
} }
@ -734,7 +815,10 @@ bool Tween::resume_all() {
bool Tween::remove(Object *p_object, String p_key) { bool Tween::remove(Object *p_object, String p_key) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
call_deferred("remove", p_object, p_key);
return true;
}
for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) { for(List<InterpolateData>::Element *E=interpolates.front();E;E=E->next()) {
InterpolateData& data = E->get(); InterpolateData& data = E->get();
@ -751,7 +835,10 @@ bool Tween::remove(Object *p_object, String p_key) {
bool Tween::remove_all() { bool Tween::remove_all() {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
call_deferred("remove_all");
return true;
}
set_active(false); set_active(false);
_set_process(false); _set_process(false);
interpolates.clear(); interpolates.clear();
@ -940,7 +1027,19 @@ bool Tween::interpolate_property(Object *p_object
, EaseType p_ease_type , EaseType p_ease_type
, real_t p_delay , real_t p_delay
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("interpolate_property"
, p_object
, p_property
, p_initial_val
, p_final_val
, p_times_in_sec
, p_trans_type
, p_ease_type
, p_delay
);
return true;
}
// convert INT to REAL is better for interpolaters // 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_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(); if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
@ -987,7 +1086,19 @@ bool Tween::interpolate_method(Object *p_object
, EaseType p_ease_type , EaseType p_ease_type
, real_t p_delay , real_t p_delay
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("interpolate_method"
, p_object
, p_method
, p_initial_val
, p_final_val
, p_times_in_sec
, p_trans_type
, p_ease_type
, p_delay
);
return true;
}
// convert INT to REAL is better for interpolaters // 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_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(); if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
@ -999,6 +1110,7 @@ bool Tween::interpolate_method(Object *p_object
ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_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_delay < 0, false);
ERR_EXPLAIN("Object has no method named: %s" + p_method);
ERR_FAIL_COND_V(!p_object->has_method(p_method), false); ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
InterpolateData data; InterpolateData data;
@ -1029,10 +1141,23 @@ bool Tween::interpolate_callback(Object *p_object
, VARIANT_ARG_DECLARE , VARIANT_ARG_DECLARE
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("interpolate_callback"
, p_object
, p_times_in_sec
, p_callback
, p_arg1
, p_arg2
, p_arg3
, p_arg4
, p_arg5
);
return true;
}
ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_object == NULL, false);
ERR_FAIL_COND_V(p_times_in_sec < 0, false); ERR_FAIL_COND_V(p_times_in_sec < 0, false);
ERR_EXPLAIN("Object has no callback named: %s" + p_callback);
ERR_FAIL_COND_V(!p_object->has_method(p_callback), false); ERR_FAIL_COND_V(!p_object->has_method(p_callback), false);
InterpolateData data; InterpolateData data;
@ -1080,10 +1205,23 @@ bool Tween::interpolate_deferred_callback(Object *p_object
, VARIANT_ARG_DECLARE , VARIANT_ARG_DECLARE
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("interpolate_deferred_callback"
, p_object
, p_times_in_sec
, p_callback
, p_arg1
, p_arg2
, p_arg3
, p_arg4
, p_arg5
);
return true;
}
ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_object == NULL, false);
ERR_FAIL_COND_V(p_times_in_sec < 0, false); ERR_FAIL_COND_V(p_times_in_sec < 0, false);
ERR_EXPLAIN("Object has no callback named: %s" + p_callback);
ERR_FAIL_COND_V(!p_object->has_method(p_callback), false); ERR_FAIL_COND_V(!p_object->has_method(p_callback), false);
InterpolateData data; InterpolateData data;
@ -1135,7 +1273,20 @@ bool Tween::follow_property(Object *p_object
, EaseType p_ease_type , EaseType p_ease_type
, real_t p_delay , real_t p_delay
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("follow_property"
, p_object
, p_property
, p_initial_val
, p_target
, p_target_property
, p_times_in_sec
, p_trans_type
, p_ease_type
, p_delay
);
return true;
}
// convert INT to REAL is better for interpolaters // 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_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
@ -1188,7 +1339,20 @@ bool Tween::follow_method(Object *p_object
, EaseType p_ease_type , EaseType p_ease_type
, real_t p_delay , real_t p_delay
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("follow_method"
, p_object
, p_method
, p_initial_val
, p_target
, p_target_method
, p_times_in_sec
, p_trans_type
, p_ease_type
, p_delay
);
return true;
}
// convert INT to REAL is better for interpolaters // 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_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
@ -1199,7 +1363,9 @@ bool Tween::follow_method(Object *p_object
ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_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_delay < 0, false);
ERR_EXPLAIN("Object has no method named: %s" + p_method);
ERR_FAIL_COND_V(!p_object->has_method(p_method), false); ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
ERR_EXPLAIN("Target has no method named: %s" + p_target_method);
ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false); ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false);
Variant::CallError error; Variant::CallError error;
@ -1240,7 +1406,20 @@ bool Tween::targeting_property(Object *p_object
, EaseType p_ease_type , EaseType p_ease_type
, real_t p_delay , real_t p_delay
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("targeting_property"
, p_object
, p_property
, p_initial
, p_initial_property
, p_final_val
, p_times_in_sec
, p_trans_type
, p_ease_type
, p_delay
);
return true;
}
// convert INT to REAL is better for interpolaters // 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(); if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
@ -1298,7 +1477,20 @@ bool Tween::targeting_method(Object *p_object
, EaseType p_ease_type , EaseType p_ease_type
, real_t p_delay , real_t p_delay
) { ) {
ERR_FAIL_COND_V(pending_update != 0, false); if(pending_update != 0) {
_add_pending_command("targeting_method"
, p_object
, p_method
, p_initial
, p_initial_method
, p_final_val
, p_times_in_sec
, p_trans_type
, p_ease_type
, p_delay
);
return true;
}
// convert INT to REAL is better for interpolaters // 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(); if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
@ -1309,7 +1501,9 @@ bool Tween::targeting_method(Object *p_object
ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_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_delay < 0, false);
ERR_EXPLAIN("Object has no method named: %s" + p_method);
ERR_FAIL_COND_V(!p_object->has_method(p_method), false); ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
ERR_EXPLAIN("Initial Object has no method named: %s" + p_initial_method);
ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false); ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false);
Variant::CallError error; Variant::CallError error;

View file

@ -110,6 +110,27 @@ private:
List<InterpolateData> interpolates; List<InterpolateData> interpolates;
struct PendingCommand {
StringName key;
int args;
Variant arg[10];
};
List<PendingCommand> pending_commands;
void _add_pending_command(StringName p_key
,const Variant& p_arg1=Variant()
,const Variant& p_arg2=Variant()
,const Variant& p_arg3=Variant()
,const Variant& p_arg4=Variant()
,const Variant& p_arg5=Variant()
,const Variant& p_arg6=Variant()
,const Variant& p_arg7=Variant()
,const Variant& p_arg8=Variant()
,const Variant& p_arg9=Variant()
,const Variant& p_arg10=Variant()
);
void _process_pending_commands();
typedef real_t (*interpolater)(real_t t, real_t b, real_t c, real_t d); typedef real_t (*interpolater)(real_t t, real_t b, real_t c, real_t d);
static interpolater interpolaters[TRANS_COUNT][EASE_COUNT]; static interpolater interpolaters[TRANS_COUNT][EASE_COUNT];

View file

@ -285,18 +285,18 @@ namespace cubic {
namespace circ { namespace circ {
static real_t in(real_t t, real_t b, real_t c, real_t d) static real_t in(real_t t, real_t b, real_t c, real_t d)
{ {
return -c * (sqrt(1 - (t /= d) * t) - 1) + b; return -c * (sqrt(1 - (t /= d) * t) - 1) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t out(real_t t, real_t b, real_t c, real_t d) static real_t out(real_t t, real_t b, real_t c, real_t d)
{ {
return c * sqrt(1 - (t = t / d - 1) * t) + b; return c * sqrt(1 - (t = t / d - 1) * t) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t in_out(real_t t, real_t b, real_t c, real_t d) static real_t in_out(real_t t, real_t b, real_t c, real_t d)
{ {
if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b; if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b;
return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t out_in(real_t t, real_t b, real_t c, real_t d) static real_t out_in(real_t t, real_t b, real_t c, real_t d)
@ -364,15 +364,15 @@ namespace back {
static real_t out(real_t t, real_t b, real_t c, real_t d) static real_t out(real_t t, real_t b, real_t c, real_t d)
{ {
float s = 1.70158f; float s = 1.70158f;
return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t in_out(real_t t, real_t b, real_t c, real_t d) static real_t in_out(real_t t, real_t b, real_t c, real_t d)
{ {
float s = 1.70158f; float s = 1.70158f;
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; // TODO: ehrich: operation with s is undefined
float postFix = t -= 2; float postFix = t -= 2;
return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; // TODO: ehrich: operation with s is undefined
} }
static real_t out_in(real_t t, real_t b, real_t c, real_t d) static real_t out_in(real_t t, real_t b, real_t c, real_t d)

View file

@ -115,6 +115,8 @@ void Button::_notification(int p_what) {
text_ofs.y+=style->get_offset().y; text_ofs.y+=style->get_offset().y;
} break; } break;
case ALIGN_CENTER: { case ALIGN_CENTER: {
if (text_ofs.x<0)
text_ofs.x=0;
text_ofs+=icon_ofs; text_ofs+=icon_ofs;
text_ofs+=style->get_offset(); text_ofs+=style->get_offset();
} break; } break;

View file

@ -59,7 +59,7 @@ bool CheckBox::is_radio()
Node* parent = this; Node* parent = this;
do { do {
parent = parent->get_parent(); parent = parent->get_parent();
if (dynamic_cast< ButtonGroup* >(parent)) if (parent->cast_to<ButtonGroup>())
break; break;
} while (parent); } while (parent);

View file

@ -92,7 +92,6 @@ void FileDialog::_file_entered(const String& p_file) {
} }
void FileDialog::_save_confirm_pressed() { void FileDialog::_save_confirm_pressed() {
String f=dir_access->get_current_dir().plus_file(file->get_text()); String f=dir_access->get_current_dir().plus_file(file->get_text());
emit_signal("file_selected",f); emit_signal("file_selected",f);
hide(); hide();

View file

@ -99,7 +99,7 @@ void Label::_notification(int p_what) {
int chars_total=0; int chars_total=0;
int vbegin=0,vsep=0; int vbegin=0,vsep=0;
if (lines_total && lines_total < lines_visible) { if (lines_total && lines_total < lines_visible) {
@ -136,10 +136,9 @@ void Label::_notification(int p_what) {
if (!wc) if (!wc)
return; return;
int c = 0;
int line=0; int line=0;
while(wc) { while(wc) {
/* handle lines not meant to be drawn quickly */ /* handle lines not meant to be drawn quickly */
if (line>line_to) if (line>line_to)
break; break;
@ -170,8 +169,8 @@ void Label::_notification(int p_what) {
while(to && to->char_pos>=0) { while(to && to->char_pos>=0) {
taken+=to->pixel_width; taken+=to->pixel_width;
if (to!=from) { if (to!=from && to->space_count) {
spaces++; spaces+=to->space_count;
} }
to=to->next; to=to->next;
} }
@ -212,15 +211,15 @@ void Label::_notification(int p_what) {
ERR_PRINT("BUG"); ERR_PRINT("BUG");
return; return;
} }
if (from!=wc) { if (from->space_count) {
/* spacing */ /* spacing */
x_ofs+=space_w; x_ofs+=space_w*from->space_count;
if (can_fill && align==ALIGN_FILL && spaces) { if (can_fill && align==ALIGN_FILL && spaces) {
x_ofs+=int((size.width-(taken+space_w*spaces))/spaces); x_ofs+=int((size.width-(taken+space_w*spaces))/spaces);
} }
} }
@ -253,7 +252,7 @@ void Label::_notification(int p_what) {
} }
for (int i=0;i<from->word_len;i++) { for (int i=0;i<from->word_len;i++) {
if (visible_chars < 0 || chars_total<visible_chars) { if (visible_chars < 0 || chars_total<visible_chars) {
CharType c = text[i+pos]; CharType c = text[i+pos];
CharType n = text[i+pos+1]; CharType n = text[i+pos+1];
@ -361,11 +360,12 @@ void Label::regenerate_word_cache() {
int width=autowrap?get_size().width:get_longest_line_width(); int width=autowrap?get_size().width:get_longest_line_width();
Ref<Font> font = get_font("font"); Ref<Font> font = get_font("font");
int current_word_size=0; int current_word_size=0;
int word_pos=0; int word_pos=0;
int line_width=0; int line_width=0;
int last_width=0; int space_count=0;
int space_width=font->get_char_size(' ').width;
line_count=1; line_count=1;
total_char_cache=0; total_char_cache=0;
@ -374,16 +374,17 @@ void Label::regenerate_word_cache() {
for (int i=0;i<text.size()+1;i++) { for (int i=0;i<text.size()+1;i++) {
CharType current=i<text.length()?text[i]:' '; //always a space at the end, so the algo works CharType current=i<text.length()?text[i]:' '; //always a space at the end, so the algo works
if (uppercase) if (uppercase)
current=String::char_uppercase(current); current=String::char_uppercase(current);
bool not_latin = current>=33 && (current < 65||current >90) && (current<97||current>122) && (current<48||current>57);
bool insert_newline=false; bool insert_newline=false;
int char_width;
if (current<33) { if (current<33) {
if (current_word_size>0) { if (current_word_size>0) {
WordCache *wc = memnew( WordCache ); WordCache *wc = memnew( WordCache );
if (word_cache) { if (word_cache) {
last->next=wc; last->next=wc;
@ -391,14 +392,16 @@ void Label::regenerate_word_cache() {
word_cache=wc; word_cache=wc;
} }
last=wc; last=wc;
wc->pixel_width=current_word_size; wc->pixel_width=current_word_size;
wc->char_pos=word_pos; wc->char_pos=word_pos;
wc->word_len=i-word_pos; wc->word_len=i-word_pos;
wc->space_count = space_count;
current_word_size=0; current_word_size=0;
space_count=0;
} }
if (current=='\n') { if (current=='\n') {
insert_newline=true; insert_newline=true;
@ -408,26 +411,49 @@ void Label::regenerate_word_cache() {
if (i<text.length() && text[i] == ' ') { if (i<text.length() && text[i] == ' ') {
total_char_cache--; // do not count spaces total_char_cache--; // do not count spaces
if (line_width > 0 || last==NULL || last->char_pos!=WordCache::CHAR_WRAPLINE) {
space_count++;
line_width+=space_width;
}else {
space_count=0;
}
} }
} else { } else {
// latin characters
if (current_word_size==0) { if (current_word_size==0) {
if (line_width>0) // add a space before the new word if a word existed before
line_width+=font->get_char_size(' ').width;
word_pos=i; word_pos=i;
} }
int char_width=font->get_char_size(current).width; char_width=font->get_char_size(current).width;
current_word_size+=char_width; current_word_size+=char_width;
line_width+=char_width; line_width+=char_width;
total_char_cache++; total_char_cache++;
} }
if ((autowrap && line_width>=width && last_width<width) || insert_newline) { if ((autowrap && (line_width >= width) && ((last && last->char_pos >= 0) || not_latin)) || insert_newline) {
if (not_latin) {
if (current_word_size>0) {
WordCache *wc = memnew( WordCache );
if (word_cache) {
last->next=wc;
} else {
word_cache=wc;
}
last=wc;
wc->pixel_width=current_word_size-char_width;
wc->char_pos=word_pos;
wc->word_len=i-word_pos;
wc->space_count = space_count;
current_word_size=char_width;
space_count=0;
word_pos=i;
}
}
WordCache *wc = memnew( WordCache ); WordCache *wc = memnew( WordCache );
if (word_cache) { if (word_cache) {
last->next=wc; last->next=wc;
@ -435,18 +461,16 @@ void Label::regenerate_word_cache() {
word_cache=wc; word_cache=wc;
} }
last=wc; last=wc;
wc->pixel_width=0; wc->pixel_width=0;
wc->char_pos=insert_newline?WordCache::CHAR_NEWLINE:WordCache::CHAR_WRAPLINE; wc->char_pos=insert_newline?WordCache::CHAR_NEWLINE:WordCache::CHAR_WRAPLINE;
line_width=current_word_size; line_width=current_word_size;
line_count++; line_count++;
space_count=0;
} }
last_width=line_width;
} }
//total_char_cache -= line_count + 1; // do not count new lines (including the first one) //total_char_cache -= line_count + 1; // do not count new lines (including the first one)
@ -465,7 +489,7 @@ void Label::regenerate_word_cache() {
set_max(line_count); set_max(line_count);
word_cache_dirty=false; word_cache_dirty=false;
} }

View file

@ -75,8 +75,9 @@ private:
int char_pos; // if -1, then newline int char_pos; // if -1, then newline
int word_len; int word_len;
int pixel_width; int pixel_width;
int space_count;
WordCache *next; WordCache *next;
WordCache() { char_pos=0; word_len=0; pixel_width=0; next=0; } WordCache() { char_pos=0; word_len=0; pixel_width=0; next=0; space_count=0;}
}; };
bool word_cache_dirty; bool word_cache_dirty;

View file

@ -272,7 +272,7 @@ void LineEdit::_input_event(InputEvent p_event) {
if (editable) { if (editable) {
selection_delete(); selection_delete();
CharType ucodestr[2]={k.unicode,0}; CharType ucodestr[2]={(CharType)k.unicode,0};
append_at_cursor(ucodestr); append_at_cursor(ucodestr);
emit_signal("text_changed",text); emit_signal("text_changed",text);
_change_notify("text"); _change_notify("text");

View file

@ -235,6 +235,9 @@ if (m_height > line_height) {\
while (c[end]!=0 && !(end && c[end-1]==' ' && c[end]!=' ')) { while (c[end]!=0 && !(end && c[end-1]==' ' && c[end]!=' ')) {
int cw = font->get_char_size(c[end],c[end+1]).width; int cw = font->get_char_size(c[end],c[end+1]).width;
if (c[end]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
w+=cw; w+=cw;
if (c[end]==' ') { if (c[end]==' ') {
@ -268,7 +271,9 @@ if (m_height > line_height) {\
} }
if (found_space) { if (found_space) {
fw+=l.offset_caches[line]/l.space_caches[line]; int ln = MIN(l.offset_caches.size()-1,line);
fw+=l.offset_caches[ln]/l.space_caches[ln];
} }
} }
@ -290,6 +295,9 @@ if (m_height > line_height) {\
int cw=font->get_char_size(c[i],c[i+1]).x; int cw=font->get_char_size(c[i],c[i+1]).x;
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
if (p_click_pos.x-cw/2>pofs) { if (p_click_pos.x-cw/2>pofs) {
@ -330,6 +338,10 @@ if (m_height > line_height) {\
cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color); cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color);
} }
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
//print_line("draw char: "+String::chr(c[i])); //print_line("draw char: "+String::chr(c[i]));

View file

@ -489,7 +489,7 @@ void TextEdit::_notification(int p_what) {
CharType cc = text[i][j]; CharType cc = text[i][j];
//ignore any brackets inside a string //ignore any brackets inside a string
if (cc== '"' | cc == '\'') { if (cc== '"' || cc == '\'') {
CharType quotation = cc; CharType quotation = cc;
do { do {
j++; j++;
@ -560,7 +560,7 @@ void TextEdit::_notification(int p_what) {
CharType cc = text[i][j]; CharType cc = text[i][j];
//ignore any brackets inside a string //ignore any brackets inside a string
if (cc== '"' | cc == '\'') { if (cc== '"' || cc == '\'') {
CharType quotation = cc; CharType quotation = cc;
do { do {
j--; j--;
@ -1249,7 +1249,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} }
if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600) { if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600 && cursor.line==prev_line) {
//tripleclick select line //tripleclick select line
select(cursor.line,0,cursor.line,text[cursor.line].length()); select(cursor.line,0,cursor.line,text[cursor.line].length());
last_dblclk=0; last_dblclk=0;
@ -1440,7 +1440,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else { } else {
//different char, go back //different char, go back
const CharType chr[2] = {k.unicode, 0}; const CharType chr[2] = {(CharType)k.unicode, 0};
if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]); _consume_pair_symbol(chr[0]);
} else { } else {
@ -2062,7 +2062,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (readonly) if (readonly)
break; break;
const CharType chr[2] = {k.unicode, 0}; const CharType chr[2] = {(CharType)k.unicode, 0};
if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]); _consume_pair_symbol(chr[0]);
@ -3494,6 +3494,9 @@ void TextEdit::set_line(int line, String new_text)
return; return;
_remove_text(line, 0, line, text[line].length()); _remove_text(line, 0, line, text[line].length());
_insert_text(line, 0, new_text); _insert_text(line, 0, new_text);
if (cursor.line==line) {
cursor.column=MIN(cursor.column,new_text.length());
}
} }
void TextEdit::insert_at(const String &p_text, int at) void TextEdit::insert_at(const String &p_text, int at)

View file

@ -1417,6 +1417,41 @@ void Node::_duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_re
} }
void Node::_duplicate_signals(const Node* p_original,Node* p_copy) const {
if (this!=p_original && get_owner()!=p_original)
return;
List<Connection> conns;
get_all_signal_connections(&conns);
for (List<Connection>::Element *E=conns.front();E;E=E->next()) {
if (E->get().flags&CONNECT_PERSIST) {
//user connected
NodePath p = p_original->get_path_to(this);
Node *copy = p_copy->get_node(p);
Node *target = E->get().target->cast_to<Node>();
if (!target)
continue;
NodePath ptarget = p_original->get_path_to(target);
Node *copytarget = p_copy->get_node(ptarget);
if (copy && copytarget) {
copy->connect(E->get().signal,copytarget,E->get().method,E->get().binds,CONNECT_PERSIST);
}
}
}
for(int i=0;i<get_child_count();i++) {
get_child(i)->_duplicate_signals(p_original,p_copy);
}
}
Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const { Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
@ -1455,6 +1490,7 @@ Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
get_child(i)->_duplicate_and_reown(node,p_reown_map); get_child(i)->_duplicate_and_reown(node,p_reown_map);
} }
_duplicate_signals(this,node);
return node; return node;
} }

View file

@ -126,6 +126,7 @@ private:
void _propagate_pause_owner(Node*p_owner); void _propagate_pause_owner(Node*p_owner);
Array _get_node_and_resource(const NodePath& p_path); Array _get_node_and_resource(const NodePath& p_path);
void _duplicate_signals(const Node* p_original,Node* p_copy) const;
void _duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_reown_map) const; void _duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_reown_map) const;
Array _get_children() const; Array _get_children() const;
Array _get_groups() const; Array _get_groups() const;
@ -170,6 +171,7 @@ public:
NOTIFICATION_PROCESS = 17, NOTIFICATION_PROCESS = 17,
NOTIFICATION_PARENTED=18, NOTIFICATION_PARENTED=18,
NOTIFICATION_UNPARENTED=19, NOTIFICATION_UNPARENTED=19,
NOTIFICATION_INSTANCED=20,
}; };
/* NODE/TREE */ /* NODE/TREE */

View file

@ -45,14 +45,14 @@ void Timer::_notification(int p_what) {
} }
} break; } break;
case NOTIFICATION_PROCESS: { case NOTIFICATION_PROCESS: {
if (timer_process_mode == TIMER_PROCESS_FIXED || !is_processing())
if (!is_processing())
return; return;
time_left -= get_process_delta_time(); time_left -= get_process_delta_time();
if (time_left<0) { if (time_left<0) {
if (!one_shot) if (!one_shot)
time_left=wait_time+time_left; //time_left=wait_time+time_left;
time_left = wait_time;
else else
stop(); stop();
@ -60,13 +60,27 @@ void Timer::_notification(int p_what) {
} }
} break; } break;
case NOTIFICATION_FIXED_PROCESS: {
if (timer_process_mode == TIMER_PROCESS_IDLE || !is_fixed_processing())
return;
time_left -= get_fixed_process_delta_time();
if (time_left<0) {
if (!one_shot)
//time_left = wait_time + time_left;
time_left = wait_time;
else
stop();
emit_signal("timeout");
}
} break;
} }
} }
void Timer::set_wait_time(float p_time) { void Timer::set_wait_time(float p_time) {
ERR_EXPLAIN("time should be greater than zero."); ERR_EXPLAIN("time should be greater than zero.");
ERR_FAIL_COND(p_time<=0); ERR_FAIL_COND(p_time<=0);
wait_time=p_time; wait_time=p_time;
@ -96,14 +110,13 @@ bool Timer::has_autostart() const {
} }
void Timer::start() { void Timer::start() {
time_left=wait_time; time_left=wait_time;
set_process(true); _set_process(true);
} }
void Timer::stop() { void Timer::stop() {
time_left=-1; time_left=-1;
set_process(false); _set_process(false);
autostart=false; autostart=false;
} }
@ -112,6 +125,41 @@ float Timer::get_time_left() const {
return time_left >0 ? time_left : 0; return time_left >0 ? time_left : 0;
} }
void Timer::set_timer_process_mode(TimerProcessMode p_mode) {
if (timer_process_mode == p_mode)
return;
switch (timer_process_mode) {
case TIMER_PROCESS_FIXED:
if (is_fixed_processing()) {
set_fixed_process(false);
set_process(true);
}
break;
case TIMER_PROCESS_IDLE:
if (is_processing()) {
set_process(false);
set_fixed_process(true);
}
break;
}
timer_process_mode = p_mode;
}
Timer::TimerProcessMode Timer::get_timer_process_mode() const{
return timer_process_mode;
}
void Timer::_set_process(bool p_process, bool p_force)
{
switch (timer_process_mode) {
case TIMER_PROCESS_FIXED: set_fixed_process(p_process); break;
case TIMER_PROCESS_IDLE: set_process(p_process); break;
}
}
void Timer::_bind_methods() { void Timer::_bind_methods() {
@ -129,8 +177,12 @@ void Timer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_time_left"),&Timer::get_time_left); ObjectTypeDB::bind_method(_MD("get_time_left"),&Timer::get_time_left);
ObjectTypeDB::bind_method(_MD("set_timer_process_mode", "mode"), &Timer::set_timer_process_mode);
ObjectTypeDB::bind_method(_MD("get_timer_process_mode"), &Timer::get_timer_process_mode);
ADD_SIGNAL( MethodInfo("timeout") ); ADD_SIGNAL( MethodInfo("timeout") );
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_timer_process_mode"), _SCS("get_timer_process_mode"));
ADD_PROPERTY( PropertyInfo(Variant::REAL, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.01,4096,0.01" ), _SCS("set_wait_time"), _SCS("get_wait_time") ); ADD_PROPERTY( PropertyInfo(Variant::REAL, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.01,4096,0.01" ), _SCS("set_wait_time"), _SCS("get_wait_time") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "one_shot" ), _SCS("set_one_shot"), _SCS("is_one_shot") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL, "one_shot" ), _SCS("set_one_shot"), _SCS("is_one_shot") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "autostart" ), _SCS("set_autostart"), _SCS("has_autostart") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL, "autostart" ), _SCS("set_autostart"), _SCS("has_autostart") );
@ -138,8 +190,7 @@ void Timer::_bind_methods() {
} }
Timer::Timer() { Timer::Timer() {
timer_process_mode = TIMER_PROCESS_IDLE;
autostart=false; autostart=false;
wait_time=1; wait_time=1;
one_shot=false; one_shot=false;

View file

@ -46,6 +46,11 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
enum TimerProcessMode {
TIMER_PROCESS_FIXED,
TIMER_PROCESS_IDLE,
};
void set_wait_time(float p_time); void set_wait_time(float p_time);
float get_wait_time() const; float get_wait_time() const;
@ -60,7 +65,16 @@ public:
float get_time_left() const; float get_time_left() const;
void set_timer_process_mode(TimerProcessMode p_mode);
TimerProcessMode get_timer_process_mode() const;
Timer(); Timer();
private:
TimerProcessMode timer_process_mode;
void _set_process(bool p_process, bool p_force = false);
}; };
VARIANT_ENUM_CAST(Timer::TimerProcessMode);
#endif // TIMER_H #endif // TIMER_H

View file

@ -1216,8 +1216,8 @@ T Animation::_interpolate( const Vector< TKey<T> >& p_keys, float p_time, Inter
if (p_ok) if (p_ok)
*p_ok=true; *p_ok=true;
int next; int next=0;
float c=0; float c=0;
// prepare for all cases of interpolation // prepare for all cases of interpolation

View file

@ -182,6 +182,8 @@ Node *PackedScene::instance(bool p_gen_edit_state) const {
if (get_path()!="" && get_path().find("::")==-1) if (get_path()!="" && get_path().find("::")==-1)
s->set_filename(get_path()); s->set_filename(get_path());
s->notification(Node::NOTIFICATION_INSTANCED);
return ret_nodes[0]; return ret_nodes[0];
} }

View file

@ -2160,7 +2160,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str
"floor($)", "floor($)",
"round($)", "round($)",
"ceil($)", "ceil($)",
"frac($)", "fract($)",
"min(max($,0),1)", "min(max($,0),1)",
"-($)", "-($)",
}; };
@ -2378,7 +2378,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str
String name = p_node->param1; String name = p_node->param1;
Vector3 dv=p_node->param2; Vector3 dv=p_node->param2;
code +="uniform float "+name+"=vec3("+rtos(dv.x)+","+rtos(dv.y)+","+rtos(dv.z)+");\n"; code +="uniform vec3 "+name+"=vec3("+rtos(dv.x)+","+rtos(dv.y)+","+rtos(dv.z)+");\n";
code += OUTNAME(p_node->id,0)+"="+name+";\n"; code += OUTNAME(p_node->id,0)+"="+name+";\n";
}break; }break;
case NODE_RGB_INPUT: { case NODE_RGB_INPUT: {

View file

@ -105,6 +105,9 @@ bool Theme::_get(const StringName& p_name,Variant &r_ret) const {
void Theme::_get_property_list( List<PropertyInfo> *p_list) const { void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
List<PropertyInfo> list;
const StringName *key=NULL; const StringName *key=NULL;
while((key=icon_map.next(key))) { while((key=icon_map.next(key))) {
@ -113,7 +116,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
while((key2=icon_map[*key].next(key2))) { while((key2=icon_map[*key].next(key2))) {
p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) ); list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) );
} }
} }
@ -125,7 +128,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
while((key2=style_map[*key].next(key2))) { while((key2=style_map[*key].next(key2))) {
p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) ); list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) );
} }
} }
@ -138,7 +141,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
while((key2=font_map[*key].next(key2))) { while((key2=font_map[*key].next(key2))) {
p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) ); list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) );
} }
} }
@ -150,7 +153,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
while((key2=color_map[*key].next(key2))) { while((key2=color_map[*key].next(key2))) {
p_list->push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) ); list.push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) );
} }
} }
@ -162,9 +165,14 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
while((key2=constant_map[*key].next(key2))) { while((key2=constant_map[*key].next(key2))) {
p_list->push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) ); list.push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) );
} }
} }
list.sort();
for(List<PropertyInfo>::Element *E=list.front();E;E=E->next()) {
p_list->push_back(E->get());
}
} }

View file

@ -34,8 +34,10 @@
#include "self_list.h" #include "self_list.h"
#include "broad_phase_sw.h" #include "broad_phase_sw.h"
#define MAX_OBJECT_DISTANCE 10000000 #ifdef DEBUG_ENABLED
#define MAX_OBJECT_DISTANCE 10000000.0
#define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE*MAX_OBJECT_DISTANCE) #define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE*MAX_OBJECT_DISTANCE)
#endif
class SpaceSW; class SpaceSW;

View file

@ -551,7 +551,7 @@ bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx)
ERR_FAIL_COND_V(!body,false); ERR_FAIL_COND_V(!body,false);
ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false); ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false);
body->is_shape_set_as_trigger(p_shape_idx); return body->is_shape_set_as_trigger(p_shape_idx);
} }

Some files were not shown because too many files have changed in this diff Show more