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('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('vsproj', 'Generate Visual Studio Project. (yes/no)', 'no')
# add platform specific options
@ -177,6 +178,25 @@ if selected_platform in platform_list:
else:
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=""
if env["extra_suffix"] != '' :
@ -330,6 +350,32 @@ if selected_platform in platform_list:
SConscript("main/SCsub")
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:

View file

@ -1381,7 +1381,7 @@ Globals::Globals() {
set("application/name","" );
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/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) {
files = memnew((Map<String, Vector<uint8_t> >));
};
}
String name;
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);
(*files)[name] = p_data;
};
}
void FileAccessMemory::cleanup() {
@ -57,13 +57,13 @@ void FileAccessMemory::cleanup() {
return;
memdelete(files);
};
}
FileAccess* FileAccessMemory::create() {
return memnew(FileAccessMemory);
};
}
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);
return files && (files->find(name) != NULL);
};
}
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;
return OK;
};
}
void FileAccessMemory::close() {
data = NULL;
};
}
bool FileAccessMemory::is_open() const {
return data != NULL;
};
}
void FileAccessMemory::seek(size_t p_position) {
ERR_FAIL_COND(!data);
pos = p_position;
};
}
void FileAccessMemory::seek_end(int64_t p_position) {
ERR_FAIL_COND(!data);
pos = length + p_position;
};
}
size_t FileAccessMemory::get_pos() const {
ERR_FAIL_COND_V(!data, 0);
return pos;
};
}
size_t FileAccessMemory::get_len() const {
ERR_FAIL_COND_V(!data, 0);
return length;
};
}
bool FileAccessMemory::eof_reached() const {
return pos >= length;
};
}
uint8_t FileAccessMemory::get_8() const {
uint8_t ret;
uint8_t ret = 0;
if (pos < length) {
ret = data[pos];
};
}
++pos;
return ret;
};
}
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;
return read;
};
}
Error FileAccessMemory::get_error() const {
return pos >= length ? ERR_FILE_EOF : OK;
};
}
void FileAccessMemory::store_8(uint8_t p_byte) {
ERR_FAIL_COND(!data);
ERR_FAIL_COND(pos >= length);
data[pos++] = p_byte;
};
}
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);
if (write < p_length) {
WARN_PRINT("Writing less data than requested");
};
}
copymem(&data[pos], p_src, write);
pos += p_length;
};
}
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) {
sources.push_back(p_source);
if (p_source != NULL) {
sources.push_back(p_source);
}
};
PackedData *PackedData::singleton=NULL;

View file

@ -309,6 +309,7 @@ Error ResourceInteractiveLoaderXML::_parse_array_element(Vector<char> &buff,bool
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("'","&apos;");
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};
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;
res->get_property_list(&property_list);
property_list.sort();
// property_list.sort();
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) {
String path=p_path;
//or this must be implemented
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) {
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());
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) {
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();
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>());
@ -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) {
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 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 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);
@ -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 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 extension=remapped_path.extension();

View file

@ -36,8 +36,9 @@ uint32_t Math::default_seed=1;
#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) {
@ -269,7 +270,7 @@ bool Math::is_inf(double p_val) {
uint32_t Math::larger_prime(uint32_t p_val) {
static const int primes[] = {
static const uint32_t primes[] = {
5,
13,
23,

View file

@ -98,7 +98,7 @@ struct VariantCaster<m_enum> {\
#define CHECK_ARG(m_arg)\
if ((m_arg-1)<p_arg_count) {\
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.argument=m_arg-1;\
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 {
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 get_signal_list(List<MethodInfo> *p_signals ) 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);
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 dst=p_path.replace("\\","/").get_base_dir();
return src.path_to(dst)+p_path.get_file();
String rel = src.path_to(dst);
if (rel==dst) // failed
return p_path;
else
return rel+p_path.get_file();
}
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 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;
src=src.substr(src_begin.length(),src.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: {
static const Type invalid[]={
static const Type valid[]={
TRANSFORM,
NIL
};
invalid_types=invalid;
valid_types=valid;
} break;
case QUAT: {
@ -299,6 +299,256 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
} 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: {
static const Type valid[] = {
@ -532,7 +782,7 @@ bool Variant::is_zero() const {
} break;
case QUAT: {
*reinterpret_cast<const Quat*>(_data._mem)==Quat();
return *reinterpret_cast<const Quat*>(_data._mem)==Quat();
} break;
case MATRIX3: {

View file

@ -165,7 +165,8 @@ public:
_FORCE_INLINE_ Type get_type() const { return 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]
name="Isometric 2D + Lighting"
main_scene="res://map.scn"
[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_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 on_air_time=100
var jumping=false
@ -31,8 +34,6 @@ func _fixed_process(delta):
#create forces
var force = Vector2(0,GRAVITY)
var stop = velocity.x!=0.0
var walk_left = Input.is_action_pressed("move_left")
var walk_right = Input.is_action_pressed("move_right")
@ -86,25 +87,42 @@ func _fixed_process(delta):
#char is on floor
on_air_time=0
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"
#by the normal
motion = n.slide(motion)
velocity = n.slide(velocity)
#then move again
move(motion)
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()):
#Since this formula will always slide the character around,
#a special case must be considered to to stop it from moving
#if standing on an inclined floor. Conditions are:
# 1) Standing on floor (on_air_time==0)
# 2) Did not move more than one pixel (get_travel().length() < SLIDE_STOP_MIN_TRAVEL)
# 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 moves, move with floor
move(floor_velocity*delta)
if (jumping and velocity.y>0):
#if falling, no longer jumping
jumping=false
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
jumping=true

View file

@ -56,7 +56,7 @@ func _integrate_forces(s):
state=STATE_DYING
#lv=s.get_contact_local_normal(i)*400
s.set_angular_velocity(sign(dp.x)*33.0)
set_friction(true)
set_friction(1)
cc.disable()
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_DEACCEL= 800.0
var WALK_MAX_VELOCITY= 200.0
var GRAVITY = 700.0
var AIR_ACCEL = 200.0
var AIR_DEACCEL= 200.0
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()
get_node("gameover").set_text("")
piece_active=true
get_node("../restart").release_focus()
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)
get_node("AnimationPlayer").play("impact")
get_node("AnimationPlayer").queue("explode")
set_friction(true)
set_friction(1)
cc.disabled=true
get_node("sound").play("hit")
return

Binary file not shown.

View file

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

View file

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

View file

@ -1,6 +1,8 @@
extends Control
var mousepos
func _fixed_process(delta):
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_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() ) )
@ -126,6 +128,12 @@ func check_wm_api():
func _ready():
if( check_wm_api() ):
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():

View file

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

View file

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

View file

@ -1,91 +1,94 @@
Import('env')
env.drivers_sources=[]
#env.add_source_files(env.drivers_sources,"*.cpp")
env.Append(CPPPATH=["vorbis"])
Export('env')
SConscript('unix/SCsub');
SConscript('alsa/SCsub');
SConscript('pulseaudio/SCsub');
SConscript('windows/SCsub');
SConscript('gles2/SCsub');
SConscript('gl_context/SCsub');
SConscript('openssl/SCsub');
if (env["png"]=="yes"):
SConscript("png/SCsub");
if (env["jpg"]=="yes"):
SConscript("jpg/SCsub");
if (env["webp"]=="yes"):
SConscript("webp/SCsub");
SConscript("dds/SCsub");
SConscript("pvr/SCsub");
SConscript("etc1/SCsub")
if (env["builtin_zlib"]=="yes"):
SConscript("builtin_zlib/SCsub");
if (env["openssl"]=="builtin"):
SConscript("builtin_openssl2/SCsub");
SConscript("rtaudio/SCsub");
SConscript("nedmalloc/SCsub");
SConscript("trex/SCsub");
SConscript("chibi/SCsub");
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"):
SConscript("ogg/SCsub");
if (env["vorbis"]=="yes"):
SConscript("vorbis/SCsub");
if (env["tools"]=="yes"):
SConscript("convex_decomp/SCsub");
if env["theora"]=="yes":
SConscript("theoraplayer/SCsub")
if (env["theora"]=="yes"):
SConscript("theora/SCsub");
if (env['speex']=='yes'):
SConscript("speex/SCsub");
if (env['musepack']=='yes'):
SConscript("mpc/SCsub");
if (env["squish"]=="yes" and env["tools"]=="yes"):
SConscript("squish/SCsub");
num = 0
cur_base = ""
total = len(env.drivers_sources)
max_src = 64
list = []
lib_list = []
import string
for f in env.drivers_sources:
fname = ""
if type(f) == type(""):
fname = env.File(f).path
else:
fname = env.File(f)[0].path
#base = string.join(fname.split("/")[:-1], "/")
fname = fname.replace("\\", "/")
base = string.join(fname.split("/")[:2], "/")
if base != cur_base and len(list) > max_src:
lib = env.Library("drivers"+str(num), list)
lib_list.append(lib)
list = []
num = num+1
cur_base = base
list.append(f)
if len(list) > 0:
lib = env.Library("drivers"+str(num), list)
lib_list.append(lib)
drivers_base=[]
env.add_source_files(drivers_base,"*.cpp")
lib_list.insert(0, env.Library("drivers", drivers_base))
env.Prepend(LIBS=lib_list)
#lib = env.Library("drivers",env.drivers_sources)
#env.Prepend(LIBS=[lib])
Import('env')
env.drivers_sources=[]
#env.add_source_files(env.drivers_sources,"*.cpp")
env.Append(CPPPATH=["vorbis"])
Export('env')
SConscript('unix/SCsub');
SConscript('alsa/SCsub');
SConscript('pulseaudio/SCsub');
SConscript('windows/SCsub');
SConscript('gles2/SCsub');
SConscript('gl_context/SCsub');
SConscript('openssl/SCsub');
if (env["png"]=="yes"):
SConscript("png/SCsub");
if (env["jpg"]=="yes"):
SConscript("jpg/SCsub");
if (env["webp"]=="yes"):
SConscript("webp/SCsub");
SConscript("dds/SCsub");
SConscript("pvr/SCsub");
SConscript("etc1/SCsub")
if (env["builtin_zlib"]=="yes"):
SConscript("builtin_zlib/SCsub");
if (env["openssl"]=="builtin"):
SConscript("builtin_openssl2/SCsub");
SConscript("rtaudio/SCsub");
SConscript("nedmalloc/SCsub");
SConscript("trex/SCsub");
SConscript("chibi/SCsub");
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"):
SConscript("ogg/SCsub");
if (env["vorbis"]=="yes"):
SConscript("vorbis/SCsub");
if (env["tools"]=="yes"):
SConscript("convex_decomp/SCsub");
if env["theora"]=="yes":
SConscript("theoraplayer/SCsub")
if (env["theora"]=="yes"):
SConscript("theora/SCsub");
if (env['speex']=='yes'):
SConscript("speex/SCsub");
if (env['musepack']=='yes'):
SConscript("mpc/SCsub");
if (env["squish"]=="yes" and env["tools"]=="yes"):
SConscript("squish/SCsub");
num = 0
cur_base = ""
total = len(env.drivers_sources)
max_src = 64
list = []
lib_list = []
import string
if env['vsproj']=="yes":
env.AddToVSProject(env.drivers_sources)
for f in env.drivers_sources:
fname = ""
if type(f) == type(""):
fname = env.File(f).path
else:
fname = env.File(f)[0].path
#base = string.join(fname.split("/")[:-1], "/")
fname = fname.replace("\\", "/")
base = string.join(fname.split("/")[:2], "/")
if base != cur_base and len(list) > max_src:
lib = env.Library("drivers"+str(num), list)
lib_list.append(lib)
list = []
num = num+1
cur_base = base
list.append(f)
if len(list) > 0:
lib = env.Library("drivers"+str(num), list)
lib_list.append(lib)
drivers_base=[]
env.add_source_files(drivers_base,"*.cpp")
lib_list.insert(0, env.Library("drivers", drivers_base))
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 *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) {
//Still no luck? Oh well...
delete[] triangulated;
return -1;
}
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="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb";
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 {
@ -634,6 +670,9 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
r_flags.use_var2_interp=false;
r_flags.uses_normalmap=false;
r_flags.uses_normal=false;
sinh_used=false;
tanh_used=false;
cosh_used=false;
String error;
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_code_line=code;
r_globals_line=global_code;
return OK;
}
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["float" ]= "float";
replace_table["vec2" ]= "vec2";
@ -686,9 +731,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
replace_table["acos" ]= "acos";
replace_table["atan" ]= "atan";
replace_table["atan2"]= "atan";
replace_table["sinh" ]= "sinh";
replace_table["cosh" ]= "cosh";
replace_table["tanh" ]= "tanh";
if (custom_h) {
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["exp" ]= "exp";
replace_table["log" ]= "log";

View file

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

View file

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

View file

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

View file

@ -46,6 +46,7 @@
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
// Static variable definitions.
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_LOCK(A) EnterCriticalSection(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__)
// pthread API
#define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
@ -184,7 +201,7 @@ RtAudio :: RtAudio( RtAudio::Api api )
getCompiledApi( apis );
for ( unsigned int i=0; i<apis.size(); i++ ) {
openRtApi( apis[i] );
if ( rtapi_->getDeviceCount() ) break;
if ( rtapi_ && rtapi_->getDeviceCount() ) break;
}
if ( rtapi_ ) return;
@ -766,9 +783,14 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
bool haveValueRange = false;
info.sampleRates.clear();
for ( UInt32 i=0; i<nRanges; i++ ) {
if ( rangeList[i].mMinimum == rangeList[i].mMaximum )
info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum );
else {
if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) {
unsigned int tmpSr = (unsigned int) rangeList[i].mMinimum;
info.sampleRates.push_back( tmpSr );
if ( !info.preferredSampleRate || ( tmpSr <= 48000 && tmpSr > info.preferredSampleRate ) )
info.preferredSampleRate = tmpSr;
} else {
haveValueRange = true;
if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
@ -777,8 +799,12 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
if ( haveValueRange ) {
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] );
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;
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 )
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 )
@ -1396,6 +1434,18 @@ void RtApiCore :: closeStream( void )
}
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 )
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 )
@ -1989,7 +2039,9 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
// Get the current jack server sample rate.
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
// channels. Jack "input ports" equal RtAudio output channels.
@ -2769,8 +2821,12 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
if ( result == ASE_OK )
if ( result == ASE_OK ) {
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.
@ -2829,9 +2885,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options )
{
{////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isDuplexInput = mode == INPUT && stream_.mode == OUTPUT;
// 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!";
return FAILURE;
}
@ -2845,7 +2904,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
// 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
// because ASIO does not allow multiple devices to run at the same
// 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.
long inputChannels, outputChannels;
result = ASIOGetChannels( &inputChannels, &outputChannels );
if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
stream_.nDeviceChannels[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.
result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
// Get the current sample rate
ASIOSampleRate currentRate;
result = ASIOGetSampleRate( &currentRate );
if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
// Set the sample rate only if necessary
if ( currentRate != sampleRate ) {
result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
}
@ -2924,10 +2984,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
else channelInfo.isInput = true;
result = ASIOGetChannelInfo( &channelInfo );
if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
// 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 ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
// 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;
result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
errorText_ = errorStream_.str();
return FAILURE;
goto error;
}
if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
else if ( granularity == -1 ) {
// Make sure bufferSize is a power of two.
int log2_of_min_size = 0;
int log2_of_max_size = 0;
if ( isDuplexInput ) {
// When this is the duplex input (output was opened before), then we have to use the same
// buffersize as the output, because it might use the preferred buffer size, which most
// likely wasn't passed as input to this. The buffer sizes have to be identically anyway,
// So instead of throwing an error, make them equal. The caller uses the reference
// to the "bufferSize" param as usual to set up processing buffers.
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;
}
*bufferSize = stream_.bufferSize;
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 == 0 ) *bufferSize = preferSize;
else 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;
else if ( granularity == -1 ) {
// Make sure bufferSize is a power of two.
int log2_of_min_size = 0;
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!";
return FAILURE;
goto error;
}
*/
stream_.bufferSize = *bufferSize;
stream_.nBuffers = 2;
@ -3022,16 +3094,13 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.deviceInterleaved[mode] = false;
// Allocate, if necessary, our AsioHandle structure for the stream.
AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
if ( handle == 0 ) {
try {
handle = new AsioHandle;
}
catch ( std::bad_alloc& ) {
//if ( handle == NULL ) {
drivers.removeCurrentDriver();
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
return FAILURE;
goto error;
}
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
// and output separately, we'll have to dispose of previously
// created output buffers for a duplex stream.
long inputLatency, outputLatency;
if ( mode == INPUT && stream_.mode == OUTPUT ) {
ASIODisposeBuffers();
if ( handle->bufferInfos ) free( handle->bufferInfos );
}
// Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
bool buffersAllocated = false;
unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
unsigned int i;
nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
if ( handle->bufferInfos == NULL ) {
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;
}
// 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.
asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged;
asioCallbacks.asioMessage = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = NULL;
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 ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
errorText_ = errorStream_.str();
goto error;
}
buffersAllocated = true;
buffersAllocated = true;
stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion.
stream_.doConvertBuffer[mode] = false;
@ -3109,11 +3196,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
bool makeBuffer = true;
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
if ( mode == INPUT ) {
if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
if ( isDuplexInput && stream_.deviceBuffer ) {
unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
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
long inputLatency, outputLatency;
result = ASIOGetLatencies( &inputLatency, &outputLatency );
if ( result != ASE_OK ) {
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;
error:
if ( buffersAllocated )
ASIODisposeBuffers();
drivers.removeCurrentDriver();
if ( !isDuplexInput ) {
// the cleanup for error in the duplex input, is done by RtApi::openStream
// So we clean up for single channel only
if ( handle ) {
CloseHandle( handle->condition );
if ( handle->bufferInfos )
free( handle->bufferInfos );
delete handle;
stream_.apiHandle = 0;
}
if ( buffersAllocated )
ASIODisposeBuffers();
for ( int i=0; i<2; i++ ) {
if ( stream_.userBuffer[i] ) {
free( stream_.userBuffer[i] );
stream_.userBuffer[i] = 0;
drivers.removeCurrentDriver();
if ( handle ) {
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;
}
}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RtApiAsio :: closeStream()
{
@ -3635,12 +3716,12 @@ public:
outIndex_( 0 ) {}
~WasapiBuffer() {
delete buffer_;
free( buffer_ );
}
// sets the length of the internal ring buffer
void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
delete buffer_;
free( buffer_ );
buffer_ = ( char* ) calloc( bufferSize, formatBytes );
@ -3799,7 +3880,7 @@ void convertBufferWasapi( char* outBuffer,
float sampleStep = 1.0f / sampleRatio;
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
for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )
@ -3945,7 +4026,6 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
RtAudio::DeviceInfo info;
unsigned int captureDeviceCount = 0;
unsigned int renderDeviceCount = 0;
std::wstring deviceName;
std::string defaultDeviceName;
bool isCaptureDevice = false;
@ -4048,8 +4128,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit;
}
deviceName = defaultDeviceNameProp.pwszVal;
defaultDeviceName = std::string( deviceName.begin(), deviceName.end() );
defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal);
// name
hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
@ -4066,8 +4145,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit;
}
deviceName = deviceNameProp.pwszVal;
info.name = std::string( deviceName.begin(), deviceName.end() );
info.name =convertCharPointerToStdString(deviceNameProp.pwszVal);
// is default
if ( isCaptureDevice ) {
@ -4110,6 +4188,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
}
info.preferredSampleRate = deviceFormat->nSamplesPerSec;
// native format
info.nativeFormats = 0;
@ -5245,14 +5324,11 @@ unsigned int RtApiDs :: getDeviceCount( void )
error( RtAudioError::WARNING );
}
// Clean out any devices that may have disappeared.
std::vector< int > indices;
for ( unsigned int i=0; i<dsDevices.size(); i++ )
if ( dsDevices[i].found == false ) indices.push_back( 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++ );
// Clean out any devices that may have disappeared (code update submitted by Eli Zehngut).
for ( unsigned int i=0; i<dsDevices.size(); ) {
if ( dsDevices[i].found == false ) dsDevices.erase( dsDevices.begin() + i );
else i++;
}
return static_cast<unsigned int>(dsDevices.size());
}
@ -5308,8 +5384,12 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
info.sampleRates.clear();
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
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] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[k];
}
}
// Get format information.
@ -6264,6 +6344,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6271,6 +6352,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6279,6 +6361,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6286,6 +6369,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6307,6 +6391,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6399,6 +6484,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6412,6 +6498,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6448,6 +6535,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6509,6 +6597,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6523,6 +6612,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6544,6 +6634,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6582,21 +6673,6 @@ static unsigned __stdcall callbackHandler( void *ptr )
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,
LPCTSTR description,
LPCTSTR /*module*/,
@ -6638,7 +6714,7 @@ static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
}
// 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 ( lpguid == NULL )
name = "Default Device";
@ -6820,6 +6896,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Count cards and devices
card = -1;
subdevice = -1;
snd_card_next( &card );
while ( card >= 0 ) {
sprintf( name, "hw:%d", card );
@ -7033,8 +7110,12 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Test our discrete set of sample rate values.
info.sampleRates.clear();
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] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[i];
}
}
if ( info.sampleRates.size() == 0 ) {
snd_pcm_close( phandle );
@ -7959,6 +8040,8 @@ void RtApiAlsa :: callbackEvent()
errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
}
else
errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun.";
}
else {
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 )
info.sampleRates.push_back( *sr );
info.preferredSampleRate = 48000;
info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
return info;
@ -8429,7 +8513,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
int error;
if ( !options->streamName.empty() ) streamName = options->streamName;
if ( options && !options->streamName.empty() ) streamName = options->streamName;
switch ( mode ) {
case INPUT:
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++ ) {
if ( ainfo.rates[i] == 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;
}
}
@ -8643,8 +8731,12 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
else {
// Check min and max rate values;
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] );
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 isDefaultInput; /*!< true if this is the default input device. */
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. */
// Default constructor.
DeviceInfo()
: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.

View file

@ -388,7 +388,7 @@ void VideoStreamTheoraplayer::pop_frame(Ref<ImageTexture> p_tex) {
{
DVector<uint8_t>::Write wr = data.write();
uint8_t* ptr = wr.ptr();
memcpy(ptr, f->getBuffer(), imgsize);
copymem(ptr, f->getBuffer(), imgsize);
}
/*
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.
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
if(reM[j]+reA[j]<0){
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) {
GetCurrentDirectoryW(2048,real_current_dir_name);
current_dir=real_current_dir_name; // TODO, utf8 parser
current_dir=current_dir.replace("\\","/");
@ -190,9 +191,9 @@ Error DirAccessWindows::make_dir(String p_dir) {
#else
//p_dir=fix_path(p_dir);
p_dir=fix_path(p_dir);
p_dir.replace("/","\\");
//p_dir.replace("/","\\");
bool success;
int err;
@ -249,14 +250,14 @@ bool DirAccessWindows::file_exists(String 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;
fileAttr = GetFileAttributesExW(p_file.c_str(), GetFileExInfoStandard, &fileInfo);
if (0 == fileAttr)
fileAttr = GetFileAttributesW(p_file.c_str());
if (INVALID_FILE_ATTRIBUTES == fileAttr)
return false;
return !(fileAttr&FILE_ATTRIBUTE_DIRECTORY);
@ -272,17 +273,16 @@ bool DirAccessWindows::dir_exists(String p_dir) {
else
p_dir=fix_path(p_dir);
p_dir.replace("/","\\");
//p_dir.replace("/","\\");
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
//WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr;
fileAttr = GetFileAttributesExW(p_dir.c_str(), GetFileExInfoStandard, &fileInfo);
if (0 == fileAttr)
return false;
fileAttr = GetFileAttributesW(p_dir.c_str());
if (INVALID_FILE_ATTRIBUTES == fileAttr)
return false;
return (fileAttr&FILE_ATTRIBUTE_DIRECTORY);
}
@ -313,12 +313,15 @@ Error DirAccessWindows::remove(String p_path) {
p_path=fix_path(p_path);
printf("erasing %s\n",p_path.utf8().get_data());
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
if (fileAttr == INVALID_FILE_ATTRIBUTES)
return FAILED;
//WIN32_FILE_ATTRIBUTE_DATA fileInfo;
//DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
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;
else
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);
#ifdef MINIZIP_ENABLED
//XXX: always get_singleton() == 0x0
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);
#endif
@ -748,12 +755,12 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
if (file_access_network_client)
memdelete(file_access_network_client);
if (packed_data)
memdelete( packed_data );
#ifdef MINIZIP_ENABLED
if (zip_packed_data)
memdelete( zip_packed_data );
#endif
// Note 1: *zip_packed_data live into *packed_data
// Note 2: PackedData::~PackedData destroy this.
//#ifdef MINIZIP_ENABLED
// if (zip_packed_data)
// memdelete( zip_packed_data );
//#endif
unregister_core_types();

View file

@ -88,6 +88,7 @@ const char *GDFunctions::get_func_name(Function p_func) {
"str",
"print",
"printt",
"prints",
"printerr",
"printraw",
"var2str",
@ -561,6 +562,22 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
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;
case TEXT_PRINTERR: {
@ -1251,6 +1268,13 @@ MethodInfo GDFunctions::get_info(Function p_func) {
mi.return_val.type=Variant::NIL;
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;
case TEXT_PRINTERR: {

View file

@ -84,6 +84,7 @@ public:
TEXT_STR,
TEXT_PRINT,
TEXT_PRINT_TABBED,
TEXT_PRINT_SPACED,
TEXT_PRINTERR,
TEXT_PRINTRAW,
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) {

View file

@ -26,7 +26,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* 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");
* 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);
String get_package_name();
String get_project_name() const;
void _fix_manifest(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") {
print_line("FOUND PACKAGE");
string_table[attr_value]=package;
string_table[attr_value]=get_package_name();
}
//print_line("tname: "+tname);
@ -1169,7 +1171,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
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);
FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE);
if (!pf) {
@ -1514,7 +1516,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
args.push_back("-s");
args.push_back(devices[p_device].id);
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);
#if 0
@ -1552,7 +1554,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
args.push_back("-a");
args.push_back("android.intent.action.MAIN");
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);
if (err || rv!=0) {
@ -1564,12 +1566,37 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
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() {
version_code=1;
version_name="1.0";
package="com.android.noname";
package="org.godotengine.$genname";
name="";
_signed=true;
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];
[window_object makeKeyAndOrderFront:nil];
[window_object makeKeyAndOrderFront:nil];
if (p_desired.fullscreen)
zoomed = true;
/*** 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) {
[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;
};
bool OS_OSX::is_window_fullscreen() const {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
if ( [window_object respondsToSelector:@selector(isZoomed)] )
return [window_object isZoomed];
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
return zoomed;
};
@ -1509,6 +1519,11 @@ void OS_OSX::run() {
main_loop->init();
if (zoomed) {
zoomed = false;
set_window_fullscreen(true);
}
// uint64_t last_ticks=get_ticks_usec();
// int frames=0;

View file

@ -12,3 +12,9 @@ common_win=[
]
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"):
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=['/DEBUG'])

View file

@ -115,29 +115,24 @@ PCHAR*
return argv;
}
char* mb_to_utf8(const char* mbs) {
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* wc_to_utf8(const wchar_t* wc) {
int ulen = WideCharToMultiByte(CP_UTF8,0,wc,-1,NULL,0,NULL,NULL);
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;
return ubuf;
}
int main(int argc, char** argv) {
int widechar_main(int argc, wchar_t** argv) {
OS_Windows os(NULL);
setlocale(LC_CTYPE, "");
char ** argv_utf8 = new char*[argc];
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]);
@ -154,82 +149,30 @@ int main(int argc, char** argv) {
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;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
int argc;
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;
godot_hinstance = hInstance;
return main(0,NULL);
}

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 {
char* val = getenv(p_var.utf8().get_data());
if (val)
return val;
wchar_t wval[0x7Fff]; // MSDN says 32767 char is the maximum
int wlen = GetEnvironmentVariableW(p_var.c_str(),wval,0x7Fff);
if ( wlen > 0 ) {
return wval;
}
return "";
};
}
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 */
classHint = XAllocClassHint();
if (classHint) {
classHint->res_name = "Godot";
classHint->res_class = "Godot";
classHint->res_name = (char *)"Godot";
classHint->res_class = (char *)"Godot";
}
XSetClassHint(x11_display, x11_window, 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() {
@ -542,6 +565,12 @@ void Area2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_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("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_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::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;
monitoring=false;
monitorable=false;
collision_mask=1;
layer_mask=1;
set_enable_monitoring(true);
set_monitorable(true);
}
Area2D::~Area2D() {

View file

@ -51,6 +51,8 @@ private:
bool gravity_is_point;
real_t linear_damp;
real_t angular_damp;
uint32_t collision_mask;
uint32_t layer_mask;
int priority;
bool monitoring;
bool monitorable;
@ -151,6 +153,12 @@ public:
void set_monitorable(bool p_enable);
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_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());;
screen_offset;
Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());
float angle = get_global_transform().get_rotation();
if(rotating){

View file

@ -32,6 +32,7 @@ void Navigation2D::_navpoly_link(int p_id) {
p.edges.resize(plen);
Vector2 center;
float sum=0;
for(int j=0;j<plen;j++) {
@ -46,8 +47,23 @@ void Navigation2D::_navpoly_link(int p_id) {
center+=ep;
e.point=_get_point(ep);
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) {
nm.polygons.pop_back();
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);
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);
}
/*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){
SWAP(left,right);
}*/
}
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){
//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;
portal_left=left;
} 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)
path.push_back(apex_point);
skip=true;
//print_line("addpoint left");
}
}
if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){
//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;
portal_right=right;
} else {
@ -539,6 +569,8 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
portal_left=apex_point;
if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON)
path.push_back(apex_point);
//print_line("addpoint right");
}
}

View file

@ -60,6 +60,8 @@ class Navigation2D : public Node2D {
float distance;
int prev_edge;
bool clockwise;
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() {
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("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("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("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("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::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;
}
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) {
mask=1;
collision_mask=1;
set_one_way_collision_max_depth(0);
set_pickable(false);
@ -909,6 +939,19 @@ Variant KinematicBody2D::_get_collider() const {
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) {
@ -926,6 +969,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
Matrix32 gt = get_global_transform();
gt.elements[2]+=result.motion;
set_global_transform(gt);
travel=result.motion;
return result.remainder;
#else
@ -1157,6 +1201,8 @@ void KinematicBody2D::_bind_methods() {
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("get_travel"),&KinematicBody2D::get_travel);
ObjectTypeDB::bind_method(_MD("revert_motion"),&KinematicBody2D::revert_motion);
ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding);

View file

@ -39,8 +39,14 @@ class PhysicsBody2D : public CollisionObject2D {
OBJ_TYPE(PhysicsBody2D,CollisionObject2D);
uint32_t mask;
uint32_t collision_mask;
Vector2 one_way_collision_direction;
float one_way_collision_max_depth;
void _set_layers(uint32_t p_mask);
uint32_t _get_layers() const;
protected:
void _notification(int p_what);
@ -52,6 +58,9 @@ public:
void set_layer_mask(uint32_t p_mask);
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 remove_collision_exception_with(Node* p_node);
@ -276,6 +285,7 @@ class KinematicBody2D : public PhysicsBody2D {
ObjectID collider;
int collider_shape;
Variant collider_metadata;
Vector2 travel;
Variant _get_collider() const;
@ -290,6 +300,10 @@ public:
bool test_move(const Vector2& p_motion);
bool is_colliding() const;
Vector2 get_travel() const;
void revert_motion();
Vector2 get_collision_pos() const;
Vector2 get_collision_normal() 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);
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_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_BOUNCE,bounce);
@ -790,7 +791,7 @@ Rect2 TileMap::get_item_rect() const {
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;
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{
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;
}
uint32_t TileMap::get_collision_mask() const {
return collision_mask;
}
void TileMap::set_mode(Mode p_mode) {
_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("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("get_collision_layer_mask"),&TileMap::get_collision_layer_mask);
ObjectTypeDB::bind_method(_MD("set_collision_layer","mask"),&TileMap::set_collision_layer);
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("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::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::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_SIGNAL(MethodInfo("settings_changed"));
@ -1146,6 +1167,7 @@ TileMap::TileMap() {
center_x=false;
center_y=false;
collision_layer=1;
collision_mask=1;
friction=1;
bounce=0;
mode=MODE_SQUARE;

View file

@ -146,6 +146,8 @@ private:
float friction;
float bounce;
uint32_t collision_layer;
uint32_t collision_mask;
TileOrigin tile_origin;
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;
void set_collision_layer_mask(uint32_t p_layer);
uint32_t get_collision_layer_mask() const;
void set_collision_layer(uint32_t p_layer);
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);
bool get_collision_use_kinematic() const;

View file

@ -30,6 +30,7 @@ void Navigation::_navmesh_link(int p_id) {
p.edges.resize(plen);
Vector3 center;
float sum=0;
for(int j=0;j<plen;j++) {
@ -44,8 +45,19 @@ void Navigation::_navmesh_link(int p_id) {
center+=ep;
e.point=_get_point(ep);
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) {
nm.polygons.pop_back();
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);
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);
}
}

View file

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

View file

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

View file

@ -29,6 +29,81 @@
#include "tween.h"
#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) {
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) {
_process_pending_commands();
if (speed_scale == 0)
return;
p_delta *= speed_scale;
@ -551,8 +628,12 @@ void Tween::_tween_process(float p_delta) {
_apply_tween_value(data, result);
if(data.finish)
if (data.finish) {
emit_signal("tween_complete",object,data.key);
// not repeat mode, remove completed action
if (!repeat)
call_deferred("remove", object, data.key);
}
}
pending_update --;
}
@ -734,7 +815,10 @@ bool Tween::resume_all() {
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()) {
InterpolateData& data = E->get();
@ -751,7 +835,10 @@ bool Tween::remove(Object *p_object, String p_key) {
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_process(false);
interpolates.clear();
@ -940,7 +1027,19 @@ bool Tween::interpolate_property(Object *p_object
, EaseType p_ease_type
, 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
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();
@ -987,7 +1086,19 @@ bool Tween::interpolate_method(Object *p_object
, EaseType p_ease_type
, 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
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();
@ -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_delay < 0, false);
ERR_EXPLAIN("Object has no method named: %s" + p_method);
ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
InterpolateData data;
@ -1029,10 +1141,23 @@ bool Tween::interpolate_callback(Object *p_object
, 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_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);
InterpolateData data;
@ -1080,10 +1205,23 @@ bool Tween::interpolate_deferred_callback(Object *p_object
, 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_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);
InterpolateData data;
@ -1135,7 +1273,20 @@ bool Tween::follow_property(Object *p_object
, EaseType p_ease_type
, 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
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
, 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
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_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_EXPLAIN("Target has no method named: %s" + p_target_method);
ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false);
Variant::CallError error;
@ -1240,7 +1406,20 @@ bool Tween::targeting_property(Object *p_object
, EaseType p_ease_type
, 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
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
, 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
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_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_EXPLAIN("Initial Object has no method named: %s" + p_initial_method);
ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false);
Variant::CallError error;

View file

@ -110,6 +110,27 @@ private:
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);
static interpolater interpolaters[TRANS_COUNT][EASE_COUNT];

View file

@ -285,18 +285,18 @@ namespace cubic {
namespace circ {
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)
{
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)
{
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)
@ -364,15 +364,15 @@ namespace back {
static real_t out(real_t t, real_t b, real_t c, real_t d)
{
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)
{
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;
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)

View file

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

View file

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

View file

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

View file

@ -99,7 +99,7 @@ void Label::_notification(int p_what) {
int chars_total=0;
int vbegin=0,vsep=0;
if (lines_total && lines_total < lines_visible) {
@ -136,10 +136,9 @@ void Label::_notification(int p_what) {
if (!wc)
return;
int c = 0;
int line=0;
while(wc) {
/* handle lines not meant to be drawn quickly */
if (line>line_to)
break;
@ -170,8 +169,8 @@ void Label::_notification(int p_what) {
while(to && to->char_pos>=0) {
taken+=to->pixel_width;
if (to!=from) {
spaces++;
if (to!=from && to->space_count) {
spaces+=to->space_count;
}
to=to->next;
}
@ -212,15 +211,15 @@ void Label::_notification(int p_what) {
ERR_PRINT("BUG");
return;
}
if (from!=wc) {
if (from->space_count) {
/* spacing */
x_ofs+=space_w;
x_ofs+=space_w*from->space_count;
if (can_fill && align==ALIGN_FILL && 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++) {
if (visible_chars < 0 || chars_total<visible_chars) {
CharType c = text[i+pos];
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();
Ref<Font> font = get_font("font");
int current_word_size=0;
int word_pos=0;
int line_width=0;
int last_width=0;
int space_count=0;
int space_width=font->get_char_size(' ').width;
line_count=1;
total_char_cache=0;
@ -374,16 +374,17 @@ void Label::regenerate_word_cache() {
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
if (uppercase)
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;
int char_width;
if (current<33) {
if (current_word_size>0) {
WordCache *wc = memnew( WordCache );
if (word_cache) {
last->next=wc;
@ -391,14 +392,16 @@ void Label::regenerate_word_cache() {
word_cache=wc;
}
last=wc;
wc->pixel_width=current_word_size;
wc->char_pos=word_pos;
wc->word_len=i-word_pos;
wc->space_count = space_count;
current_word_size=0;
space_count=0;
}
if (current=='\n') {
insert_newline=true;
@ -408,26 +411,49 @@ void Label::regenerate_word_cache() {
if (i<text.length() && text[i] == ' ') {
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 {
// latin characters
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;
}
int char_width=font->get_char_size(current).width;
char_width=font->get_char_size(current).width;
current_word_size+=char_width;
line_width+=char_width;
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 );
if (word_cache) {
last->next=wc;
@ -435,18 +461,16 @@ void Label::regenerate_word_cache() {
word_cache=wc;
}
last=wc;
wc->pixel_width=0;
wc->char_pos=insert_newline?WordCache::CHAR_NEWLINE:WordCache::CHAR_WRAPLINE;
line_width=current_word_size;
line_count++;
space_count=0;
}
last_width=line_width;
}
//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);
word_cache_dirty=false;
}

View file

@ -75,8 +75,9 @@ private:
int char_pos; // if -1, then newline
int word_len;
int pixel_width;
int space_count;
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;

View file

@ -272,7 +272,7 @@ void LineEdit::_input_event(InputEvent p_event) {
if (editable) {
selection_delete();
CharType ucodestr[2]={k.unicode,0};
CharType ucodestr[2]={(CharType)k.unicode,0};
append_at_cursor(ucodestr);
emit_signal("text_changed",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]!=' ')) {
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;
if (c[end]==' ') {
@ -268,7 +271,9 @@ if (m_height > line_height) {\
}
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;
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
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);
}
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
//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];
//ignore any brackets inside a string
if (cc== '"' | cc == '\'') {
if (cc== '"' || cc == '\'') {
CharType quotation = cc;
do {
j++;
@ -560,7 +560,7 @@ void TextEdit::_notification(int p_what) {
CharType cc = text[i][j];
//ignore any brackets inside a string
if (cc== '"' | cc == '\'') {
if (cc== '"' || cc == '\'') {
CharType quotation = cc;
do {
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
select(cursor.line,0,cursor.line,text[cursor.line].length());
last_dblclk=0;
@ -1440,7 +1440,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
//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])) {
_consume_pair_symbol(chr[0]);
} else {
@ -2062,7 +2062,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (readonly)
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])) {
_consume_pair_symbol(chr[0]);
@ -3494,6 +3494,9 @@ void TextEdit::set_line(int line, String new_text)
return;
_remove_text(line, 0, line, text[line].length());
_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)

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 {
@ -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);
}
_duplicate_signals(this,node);
return node;
}

View file

@ -126,6 +126,7 @@ private:
void _propagate_pause_owner(Node*p_owner);
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;
Array _get_children() const;
Array _get_groups() const;
@ -170,6 +171,7 @@ public:
NOTIFICATION_PROCESS = 17,
NOTIFICATION_PARENTED=18,
NOTIFICATION_UNPARENTED=19,
NOTIFICATION_INSTANCED=20,
};
/* NODE/TREE */

View file

@ -45,14 +45,14 @@ void Timer::_notification(int p_what) {
}
} break;
case NOTIFICATION_PROCESS: {
if (!is_processing())
if (timer_process_mode == TIMER_PROCESS_FIXED || !is_processing())
return;
time_left -= get_process_delta_time();
if (time_left<0) {
if (!one_shot)
time_left=wait_time+time_left;
//time_left=wait_time+time_left;
time_left = wait_time;
else
stop();
@ -60,13 +60,27 @@ void Timer::_notification(int p_what) {
}
} 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) {
ERR_EXPLAIN("time should be greater than zero.");
ERR_FAIL_COND(p_time<=0);
wait_time=p_time;
@ -96,14 +110,13 @@ bool Timer::has_autostart() const {
}
void Timer::start() {
time_left=wait_time;
set_process(true);
_set_process(true);
}
void Timer::stop() {
time_left=-1;
set_process(false);
_set_process(false);
autostart=false;
}
@ -112,6 +125,41 @@ float Timer::get_time_left() const {
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() {
@ -129,8 +177,12 @@ void Timer::_bind_methods() {
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_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::BOOL, "one_shot" ), _SCS("set_one_shot"), _SCS("is_one_shot") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "autostart" ), _SCS("set_autostart"), _SCS("has_autostart") );
@ -138,8 +190,7 @@ void Timer::_bind_methods() {
}
Timer::Timer() {
timer_process_mode = TIMER_PROCESS_IDLE;
autostart=false;
wait_time=1;
one_shot=false;

View file

@ -46,6 +46,11 @@ protected:
static void _bind_methods();
public:
enum TimerProcessMode {
TIMER_PROCESS_FIXED,
TIMER_PROCESS_IDLE,
};
void set_wait_time(float p_time);
float get_wait_time() const;
@ -60,7 +65,16 @@ public:
float get_time_left() const;
void set_timer_process_mode(TimerProcessMode p_mode);
TimerProcessMode get_timer_process_mode() const;
Timer();
private:
TimerProcessMode timer_process_mode;
void _set_process(bool p_process, bool p_force = false);
};
VARIANT_ENUM_CAST(Timer::TimerProcessMode);
#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)
*p_ok=true;
int next;
int next=0;
float c=0;
// 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)
s->set_filename(get_path());
s->notification(Node::NOTIFICATION_INSTANCED);
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($)",
"round($)",
"ceil($)",
"frac($)",
"fract($)",
"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;
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";
}break;
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 {
List<PropertyInfo> list;
const StringName *key=NULL;
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))) {
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))) {
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))) {
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))) {
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))) {
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 "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)
#endif
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_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