Merge branch 'master' of github.com:okamstudio/godot

This commit is contained in:
Anton Yabchinskiy 2015-11-02 20:25:01 +03:00
commit 3b9868d2e4
926 changed files with 139154 additions and 100990 deletions

4
.gitattributes vendored Normal file
View file

@ -0,0 +1,4 @@
*.cpp eol=lf
*.h eol=lf
*.py eol=lf
*.hpp eol=lf

13
.gitignore vendored
View file

@ -23,6 +23,9 @@ tools/editor/editor_icons.cpp
make.bat
log.txt
# Doxygen generated documentation
doc/doxygen/*
# Javascript specific
*.bc
@ -50,6 +53,14 @@ platform/android/libs/play_licensing/gen/*
*.d
*.so
*.os
*.Plo
*.lo
*.Po
# Libs generated files
.deps/*
.dirstamp
# QT project files
*.config
@ -73,6 +84,8 @@ platform/android/libs/play_licensing/gen/*
*.suo
*.user
*.sln.docstates
*.sln
*.vcxproj*
# Build results
[Dd]ebug/

View file

@ -51,14 +51,14 @@ PROJECT_BRIEF = "Game Engine MIT"
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO = E:/development/godot/logo_small.png
PROJECT_LOGO = ./logo_small.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = E:/development/godot/doxygen
OUTPUT_DIRECTORY = ./doc/doxygen/
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@ -768,7 +768,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = E:/development/godot
INPUT = ./core/ ./main/ ./scene/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View file

@ -54,13 +54,16 @@ methods.save_active_platforms(active_platforms,active_platform_ids)
custom_tools=['default']
platform_arg = ARGUMENTS.get("platform", False)
if (os.name=="posix"):
pass
elif (os.name=="nt"):
if (os.getenv("VSINSTALLDIR")==None):
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
custom_tools=['mingw']
env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
#env_base=Environment(tools=custom_tools);
env_base.global_defaults=global_defaults
env_base.android_source_modules=[]
@ -99,6 +102,7 @@ opts.Add('p','Platform (same as platform=).',"")
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
opts.Add('gdscript','Build GDSCript support: (yes/no)','yes')
opts.Add('vorbis','Build Ogg Vorbis Support: (yes/no)','yes')
opts.Add('opus','Build Opus Audio Format Support: (yes/no)','yes')
opts.Add('minizip','Build Minizip Archive Support: (yes/no)','yes')
opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes')
opts.Add('theora','Theora Video (yes/no)','yes')
@ -218,14 +222,14 @@ if selected_platform in platform_list:
env.Append(LINKFLAGS=string.split(str(LINKFLAGS)))
detect.configure(env)
flag_list = platform_flags[selected_platform]
for f in flag_list:
if not (f[0] in ARGUMENTS): # allow command line to override platform flags
env[f[0]] = f[1]
#must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
detect.configure(env)
#env['platform_libsuffix'] = env['LIBSUFFIX']
suffix="."+selected_platform
@ -297,6 +301,8 @@ if selected_platform in platform_list:
if (env['vorbis']=='yes'):
env.Append(CPPFLAGS=['-DVORBIS_ENABLED']);
if (env['opus']=='yes'):
env.Append(CPPFLAGS=['-DOPUS_ENABLED']);
if (env['theora']=='yes'):
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
@ -364,8 +370,8 @@ if selected_platform in platform_list:
#env['MSVS_VERSION']='9.0'
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
env['MSVSCLEANCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes vsproj=true"
env['MSVSCLEANCOM'] = "scons --clean platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
debug_variants = ['Debug|Win32']+['Debug|x64']
release_variants = ['Release|Win32']+['Release|x64']

View file

@ -61,6 +61,7 @@ const char ** tests_get_names() {
"gui",
"io",
"shaderlang",
"physics",
NULL
};

View file

@ -494,6 +494,10 @@ uint64_t _OS::get_unix_time() const {
return OS::get_singleton()->get_unix_time();
};
uint64_t _OS::get_system_time_msec() const {
return OS::get_singleton()->get_system_time_msec();
}
void _OS::delay_usec(uint32_t p_usec) const {
OS::get_singleton()->delay_usec(p_usec);
@ -694,6 +698,17 @@ bool _OS::is_debug_build() const {
}
void _OS::set_screen_orientation(ScreenOrientation p_orientation) {
OS::get_singleton()->set_screen_orientation(OS::ScreenOrientation(p_orientation));
}
_OS::ScreenOrientation _OS::get_screen_orientation() const {
return ScreenOrientation(OS::get_singleton()->get_screen_orientation());
}
String _OS::get_system_dir(SystemDir p_dir) const {
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
@ -717,6 +732,11 @@ int _OS::find_scancode_from_string(const String& p_code) const {
return find_keycode(p_code);
}
void _OS::alert(const String& p_alert,const String& p_title) {
OS::get_singleton()->alert(p_alert,p_title);
}
_OS *_OS::singleton=NULL;
void _OS::_bind_methods() {
@ -752,6 +772,9 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_window_maximized", "enabled"),&_OS::set_window_maximized);
ObjectTypeDB::bind_method(_MD("is_window_maximized"),&_OS::is_window_maximized);
ObjectTypeDB::bind_method(_MD("set_screen_orientation","orientation"),&_OS::set_screen_orientation);
ObjectTypeDB::bind_method(_MD("get_screen_orientation"),&_OS::get_screen_orientation);
ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second);
ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second);
@ -787,6 +810,7 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_time","utc"),&_OS::get_time,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_time_zone_info"),&_OS::get_time_zone_info);
ObjectTypeDB::bind_method(_MD("get_unix_time"),&_OS::get_unix_time);
ObjectTypeDB::bind_method(_MD("get_system_time_msec"), &_OS::get_system_time_msec);
ObjectTypeDB::bind_method(_MD("set_icon"),&_OS::set_icon);
@ -840,6 +864,7 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_use_file_access_save_and_swap","enabled"),&_OS::set_use_file_access_save_and_swap);
ObjectTypeDB::bind_method(_MD("alert","text","title"),&_OS::alert,DEFVAL("Alert!"));
BIND_CONSTANT( DAY_SUNDAY );
@ -863,6 +888,14 @@ void _OS::_bind_methods() {
BIND_CONSTANT( MONTH_NOVEMBER );
BIND_CONSTANT( MONTH_DECEMBER );
BIND_CONSTANT( SCREEN_ORIENTATION_LANDSCAPE );
BIND_CONSTANT( SCREEN_ORIENTATION_PORTRAIT );
BIND_CONSTANT( SCREEN_ORIENTATION_REVERSE_LANDSCAPE );
BIND_CONSTANT( SCREEN_ORIENTATION_REVERSE_PORTRAIT );
BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR_LANDSCAPE );
BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR_PORTRAIT );
BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR );
BIND_CONSTANT( SYSTEM_DIR_DESKTOP);
BIND_CONSTANT( SYSTEM_DIR_DCIM );
BIND_CONSTANT( SYSTEM_DIR_DOCUMENTS );

View file

@ -208,6 +208,7 @@ public:
Dictionary get_time(bool utc) const;
Dictionary get_time_zone_info() const;
uint64_t get_unix_time() const;
uint64_t get_system_time_msec() const;
int get_static_memory_usage() const;
int get_static_memory_peak_usage() const;
@ -239,11 +240,28 @@ public:
SYSTEM_DIR_RINGTONES,
};
enum ScreenOrientation {
SCREEN_ORIENTATION_LANDSCAPE,
SCREEN_ORIENTATION_PORTRAIT,
SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
SCREEN_ORIENTATION_REVERSE_PORTRAIT,
SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
SCREEN_ORIENTATION_SENSOR_PORTRAIT,
SCREEN_ORIENTATION_SENSOR,
};
String get_system_dir(SystemDir p_dir) const;
String get_data_dir() const;
void alert(const String& p_alert,const String& p_title="ALERT!");
void set_screen_orientation(ScreenOrientation p_orientation);
ScreenOrientation get_screen_orientation() const;
void set_time_scale(float p_scale);
float get_time_scale();
@ -255,6 +273,7 @@ public:
};
VARIANT_ENUM_CAST(_OS::SystemDir);
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
class _Geometry : public Object {

View file

@ -54,6 +54,7 @@ enum Error {
ERR_FILE_CANT_READ,
ERR_FILE_UNRECOGNIZED, // (15)
ERR_FILE_CORRUPT,
ERR_FILE_MISSING_DEPENDENCIES,
ERR_FILE_EOF,
ERR_CANT_OPEN, ///< Can't open a resource/socket/file
ERR_CANT_CREATE,

View file

@ -104,7 +104,7 @@ extern bool _err_error_exists;
#define ERR_FAIL_INDEX(m_index,m_size) \
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index "_STR(m_index)" out of size ("_STR(m_size)")."); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
return; \
} else _err_error_exists=false; } while(0); \
@ -115,7 +115,7 @@ extern bool _err_error_exists;
#define ERR_FAIL_INDEX_V(m_index,m_size,m_retval) \
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index "_STR(m_index)" out of size ("_STR(m_size)")."); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
return m_retval; \
} else _err_error_exists=false;} while (0);
@ -125,14 +125,14 @@ extern bool _err_error_exists;
#define ERR_FAIL_NULL(m_param) \
{ if ( !m_param ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' "_STR(m_param)" ' is null."); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
return; \
}else _err_error_exists=false; } \
#define ERR_FAIL_NULL_V(m_param,m_retval) \
{ if ( !m_param ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' "_STR(m_param)" ' is null."); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
return m_retval; \
}else _err_error_exists=false; } \
@ -142,7 +142,7 @@ extern bool _err_error_exists;
#define ERR_FAIL_COND(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true."); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true."); \
return; \
}else _err_error_exists=false; } \
@ -154,7 +154,7 @@ extern bool _err_error_exists;
#define ERR_FAIL_COND_V(m_cond,m_retval) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true. returned: "_STR(m_retval)); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. returned: " _STR(m_retval)); \
return m_retval; \
}else _err_error_exists=false; } \
@ -164,7 +164,7 @@ extern bool _err_error_exists;
#define ERR_CONTINUE(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true. Continuing..:"); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Continuing..:"); \
continue;\
} else _err_error_exists=false;} \
@ -174,7 +174,7 @@ extern bool _err_error_exists;
#define ERR_BREAK(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true. Breaking..:"); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Breaking..:"); \
break;\
} else _err_error_exists=false;} \
@ -193,7 +193,7 @@ extern bool _err_error_exists;
#define ERR_FAIL_V(m_value) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: "__STR(m_value)); \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: " __STR(m_value)); \
_err_error_exists=false; \
return m_value;\
} \

View file

@ -31,8 +31,7 @@ void FuncRef::_bind_methods() {
{
MethodInfo mi;
mi.name="call";
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
mi.name="call_func";
Vector<Variant> defargs;
for(int i=0;i<10;i++) {
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));

View file

@ -422,6 +422,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( ERR_FILE_CANT_READ ),
BIND_GLOBAL_CONSTANT( ERR_FILE_UNRECOGNIZED ),
BIND_GLOBAL_CONSTANT( ERR_FILE_CORRUPT ),
BIND_GLOBAL_CONSTANT( ERR_FILE_MISSING_DEPENDENCIES),
BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),

View file

@ -54,7 +54,7 @@ String Globals::localize_path(const String& p_path) const {
if (resource_path=="")
return p_path; //not initialied yet
if (p_path.begins_with("res://"))
if (p_path.find(":/") != -1)
return p_path.simplify_path();
@ -1477,7 +1477,6 @@ Globals::Globals() {
custom_prop_info["render/mipmap_policy"]=PropertyInfo(Variant::INT,"render/mipmap_policy",PROPERTY_HINT_ENUM,"Allow,Allow For Po2,Disallow");
custom_prop_info["render/thread_model"]=PropertyInfo(Variant::INT,"render/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["physics_2d/thread_model"]=PropertyInfo(Variant::INT,"physics_2d/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
set("display/emulate_touchscreen",false);
using_datapack=false;
}

View file

@ -34,6 +34,33 @@
#include "print_string.h"
#include <stdio.h>
const char* Image::format_names[Image::FORMAT_MAX]={
"Grayscale",
"Intensity",
"GrayscaleAlpha",
"RGB",
"RGBA",
"Indexed",
"IndexedAlpha",
"YUV422",
"YUV444",
"BC1",
"BC2",
"BC3",
"BC4",
"BC5",
"PVRTC2",
"PVRTC2Alpha",
"PVRTC4",
"PVRTC4Alpha",
"ETC",
"ATC",
"ATCAlphaExp",
"ATCAlphaInterp",
};
SavePNGFunc Image::save_png_func = NULL;
void Image::_put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data) {
@ -400,6 +427,102 @@ Image::Format Image::get_format() const{
return format;
}
static double _bicubic_interp_kernel( double x ) {
x = ABS(x);
double bc = 0;
if ( x <= 1 )
bc = ( 1.5 * x - 2.5 ) * x * x + 1;
else if ( x < 2 )
bc = ( ( -0.5 * x + 2.5 ) * x - 4 ) * x + 2;
return bc;
}
template<int CC>
static void _scale_cubic(const uint8_t* p_src, uint8_t* p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
// get source image size
int width = p_src_width;
int height = p_src_height;
double xfac = (double) width / p_dst_width;
double yfac = (double) height / p_dst_height;
// coordinates of source points and cooefficiens
double ox, oy, dx, dy, k1, k2;
int ox1, oy1, ox2, oy2;
// destination pixel values
// width and height decreased by 1
int ymax = height - 1;
int xmax = width - 1;
// temporary pointer
for ( int y = 0; y < p_dst_height; y++ ) {
// Y coordinates
oy = (double) y * yfac - 0.5f;
oy1 = (int) oy;
dy = oy - (double) oy1;
for ( int x = 0; x < p_dst_width; x++ ) {
// X coordinates
ox = (double) x * xfac - 0.5f;
ox1 = (int) ox;
dx = ox - (double) ox1;
// initial pixel value
uint8_t *dst=p_dst + (y*p_dst_width+x)*CC;
double color[CC];
for(int i=0;i<CC;i++) {
color[i]=0;
}
for ( int n = -1; n < 3; n++ ) {
// get Y cooefficient
k1 = _bicubic_interp_kernel( dy - (double) n );
oy2 = oy1 + n;
if ( oy2 < 0 )
oy2 = 0;
if ( oy2 > ymax )
oy2 = ymax;
for ( int m = -1; m < 3; m++ ) {
// get X cooefficient
k2 = k1 * _bicubic_interp_kernel( (double) m - dx );
ox2 = ox1 + m;
if ( ox2 < 0 )
ox2 = 0;
if ( ox2 > xmax )
ox2 = xmax;
// get pixel of original image
const uint8_t *p = p_src + (oy2 * p_src_width + ox2)*CC;
for(int i=0;i<CC;i++) {
color[i]+=p[i]*k2;
}
}
}
for(int i=0;i<CC;i++) {
dst[i]=CLAMP(Math::fast_ftoi(color[i]),0,255);
}
}
}
}
template<int CC>
static void _scale_bilinear(const uint8_t* p_src, uint8_t* p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
@ -559,6 +682,17 @@ void Image::resize( int p_width, int p_height, Interpolation p_interpolation ) {
}
} break;
case INTERPOLATE_CUBIC: {
switch(get_format_pixel_size(format)) {
case 1: _scale_cubic<1>(r_ptr,w_ptr,width,height,p_width,p_height); break;
case 2: _scale_cubic<2>(r_ptr,w_ptr,width,height,p_width,p_height); break;
case 3: _scale_cubic<3>(r_ptr,w_ptr,width,height,p_width,p_height); break;
case 4: _scale_cubic<4>(r_ptr,w_ptr,width,height,p_width,p_height); break;
}
} break;
}
@ -2248,6 +2382,12 @@ void Image::fix_alpha_edges() {
}
String Image::get_format_name(Format p_format) {
ERR_FAIL_INDEX_V(p_format,FORMAT_MAX,String());
return format_names[p_format];
}
Image::Image(const uint8_t* p_png,int p_len) {
width=0;

View file

@ -87,10 +87,12 @@ public:
FORMAT_MAX
};
static const char* format_names[FORMAT_MAX];
enum Interpolation {
INTERPOLATE_NEAREST,
INTERPOLATE_BILINEAR,
INTERPOLATE_CUBIC,
/* INTERPOLATE GAUSS */
};
@ -351,6 +353,8 @@ public:
Image get_rect(const Rect2& p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *));
static String get_format_name(Format p_format);
Image(const uint8_t* p_mem_png, int p_len=-1);
Image(const char **p_xpm);
~Image();

View file

@ -26,12 +26,12 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "zlib.h"
#include "os/copymem.h"
#include "compression.h"
#include "fastlz.h"
#include "zlib.h"
#include "zip_io.h"
#include "os/copymem.h"
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode) {

View file

@ -50,9 +50,11 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
if (!f) {
Error err;
f=FileAccess::open(p_file,FileAccess::READ,&err);
if (!f)
if (!f) {
print_line("ERROR OPENING FILE: "+p_file);
return err;
}
}
String extension = p_file.extension();
@ -62,14 +64,19 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
if (!loader[i]->recognize(extension))
continue;
Error err = loader[i]->load_image(p_image,f);
if (err!=ERR_FILE_UNRECOGNIZED) {
if (!p_custom)
memdelete(f);
return err;
}
}
print_line("NO LOADER?");
if (!p_custom)
memdelete(f);

View file

@ -40,7 +40,6 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#include "zlib.h"
#if defined(USE_FILE32API)

View file

@ -36,7 +36,10 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
const uint8_t * buf=p_buffer;
int len=p_len;
if (len<4) {
ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
}
uint32_t type=decode_uint32(buf);
@ -299,10 +302,8 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA);
Vector<StringName> names;
Vector<StringName> subnames;
bool absolute;
StringName prop;
int i=0;
uint32_t namecount=strlen&=0x7FFFFFFF;
uint32_t subnamecount = decode_uint32(buf+4);
uint32_t flags = decode_uint32(buf+8);
@ -391,7 +392,6 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
ie.type=decode_uint32(&buf[0]);
ie.device=decode_uint32(&buf[4]);
uint32_t len = decode_uint32(&buf[8])-12;
if (r_len)
(*r_len)+=12;

View file

@ -156,7 +156,6 @@ Error PacketPeerStream::_poll_buffer() const {
Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read);
if (err)
return err;
if (read==0)
return OK;

View file

@ -31,6 +31,7 @@
#include "globals.h"
#include "io/file_access_compressed.h"
#include "io/marshalls.h"
#include "os/dir_access.h"
//#define print_bl(m_what) print_line(m_what)
#define print_bl(m_what)
@ -99,7 +100,9 @@ enum {
OBJECT_EMPTY=0,
OBJECT_EXTERNAL_RESOURCE=1,
OBJECT_INTERNAL_RESOURCE=2,
FORMAT_VERSION=0
OBJECT_EXTERNAL_RESOURCE_INDEX=3,
FORMAT_VERSION=1,
FORMAT_VERSION_CAN_RENAME_DEPS=1
};
@ -384,6 +387,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
} break;
case OBJECT_EXTERNAL_RESOURCE: {
//old file format, still around for compatibility
String type = get_unicode_string();
String path = get_unicode_string();
@ -394,12 +398,44 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
}
if (remaps.find(path)) {
path=remaps[path];
}
RES res=ResourceLoader::load(path,type);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
}
r_v=res;
} break;
case OBJECT_EXTERNAL_RESOURCE_INDEX: {
//new file format, just refers to an index in the external list
uint32_t erindex = f->get_32();
if (erindex>=external_resources.size()) {
WARN_PRINT("Broken external resource! (index out of size");
r_v=Variant();
} else {
String type = external_resources[erindex].type;
String path = external_resources[erindex].path;
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
}
RES res=ResourceLoader::load(path,type);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
}
r_v=res;
}
} break;
default: {
@ -628,17 +664,20 @@ Error ResourceInteractiveLoaderBinary::poll(){
if (s<external_resources.size()) {
RES res = ResourceLoader::load(external_resources[s].path,external_resources[s].type);
String path = external_resources[s].path;
if (remaps.has(path)) {
path=remaps[path];
}
RES res = ResourceLoader::load(path,external_resources[s].type);
if (res.is_null()) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
ResourceLoader::notify_load_error("Resource Not Found: "+external_resources[s].path);
ResourceLoader::notify_dependency_error(local_path,path,external_resources[s].type);
} else {
error=ERR_FILE_CORRUPT;
ERR_EXPLAIN("Can't load dependency: "+external_resources[s].path);
error=ERR_FILE_MISSING_DEPENDENCIES;
ERR_EXPLAIN("Can't load dependency: "+path);
ERR_FAIL_V(error);
}
@ -787,6 +826,27 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const {
return external_resources.size()+internal_resources.size();
}
static void save_ustring(FileAccess* f,const String& p_string) {
CharString utf8 = p_string.utf8();
f->store_32(utf8.length()+1);
f->store_buffer((const uint8_t*)utf8.get_data(),utf8.length()+1);
}
static String get_ustring(FileAccess *f) {
int len = f->get_32();
Vector<char> str_buf;
str_buf.resize(len);
f->get_buffer((uint8_t*)&str_buf[0],len);
String s;
s.parse_utf8(&str_buf[0]);
return s;
}
String ResourceInteractiveLoaderBinary::get_unicode_string() {
int len = f->get_32();
@ -801,7 +861,7 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies) {
void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies,bool p_add_types) {
open(p_f);
if (error)
@ -814,6 +874,10 @@ void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<Stri
dep=ResourceLoader::guess_full_filename(dep,external_resources[i].type);
}
if (p_add_types && external_resources[i].type!=String()) {
dep+="::"+external_resources[i].type;
}
p_dependencies->push_back(dep);
}
@ -866,7 +930,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
print_bl("minor: "+itos(ver_minor));
print_bl("format: "+itos(ver_format));
if (ver_format<FORMAT_VERSION || ver_major>VERSION_MAJOR) {
if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) {
f->close();
ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path);
@ -903,6 +967,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
}
//see if the exporter has different set of external resources for more efficient loading
/*
String preload_depts = "deps/"+res_path.md5_text();
if (Globals::get_singleton()->has(preload_depts)) {
external_resources.clear();
@ -913,7 +978,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
external_resources[i].path=depts.get_name(i);
}
print_line(res_path+" - EXTERNAL RESOURCES: "+itos(external_resources.size()));
}
}*/
print_bl("ext resources: "+itos(ext_resources_size));
uint32_t int_resources_size=f->get_32();
@ -973,7 +1038,7 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
uint32_t ver_minor=f->get_32();
uint32_t ver_format=f->get_32();
if (ver_format<FORMAT_VERSION || ver_major>VERSION_MAJOR) {
if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) {
f->close();
return "";
@ -1000,8 +1065,10 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
}
Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path) {
Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) {
if (r_error)
*r_error=ERR_FILE_CANT_OPEN;
Error err;
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@ -1114,7 +1181,7 @@ Error ResourceFormatLoaderBinary::load_import_metadata(const String &p_path, Ref
}
void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies) {
void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND(!f);
@ -1123,7 +1190,217 @@ void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<Stri
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
ria->get_dependencies(f,p_dependencies);
ria->get_dependencies(f,p_dependencies,p_add_types);
}
Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
// Error error=OK;
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);
FileAccess* fw=NULL;//=FileAccess::open(p_path+".depren");
String local_path=p_path.get_base_dir();
uint8_t header[4];
f->get_buffer(header,4);
if (header[0]=='R' && header[1]=='S' && header[2]=='C' && header[3]=='C') {
//compressed
FileAccessCompressed *fac = memnew( FileAccessCompressed );
fac->open_after_magic(f);
f=fac;
FileAccessCompressed *facw = memnew( FileAccessCompressed );
facw->configure("RSCC");
Error err = facw->_open(p_path+".depren",FileAccess::WRITE);
if (err) {
memdelete(fac);
memdelete(facw);
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
}
fw=facw;
} else if (header[0]!='R' || header[1]!='S' || header[2]!='R' || header[3]!='C') {
//not normal
//error=ERR_FILE_UNRECOGNIZED;
memdelete(f);
ERR_EXPLAIN("Unrecognized binary resource file: "+local_path);
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
} else {
fw = FileAccess::open(p_path+".depren",FileAccess::WRITE);
if (!fw) {
memdelete(f);
}
ERR_FAIL_COND_V(!fw,ERR_CANT_CREATE);
}
bool big_endian = f->get_32();
#ifdef BIG_ENDIAN_ENABLED
endian_swap = !big_endian;
#else
bool endian_swap = big_endian;
#endif
bool use_real64 = f->get_32();
f->set_endian_swap(big_endian!=0); //read big endian if saved as big endian
fw->store_32(endian_swap);
fw->set_endian_swap(big_endian!=0);
fw->store_32(use_real64); //use real64
uint32_t ver_major=f->get_32();
uint32_t ver_minor=f->get_32();
uint32_t ver_format=f->get_32();
if (ver_format<FORMAT_VERSION_CAN_RENAME_DEPS) {
memdelete(f);
memdelete(fw);
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->remove(p_path+".depren");
memdelete(da);
//fuck it, use the old approach;
WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data());
Error err;
f = FileAccess::open(p_path,FileAccess::READ,&err);
if (err!=OK) {
ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN);
}
Ref<ResourceInteractiveLoaderBinary> ria = memnew( ResourceInteractiveLoaderBinary );
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
ria->remaps=p_map;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
ria->open(f);
err = ria->poll();
while(err==OK) {
err=ria->poll();
}
ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT);
RES res = ria->get_resource();
ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT);
return ResourceFormatSaverBinary::singleton->save(p_path,res);
}
if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) {
memdelete(f);
memdelete(fw);
ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path);
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
}
fw->store_32( VERSION_MAJOR ); //current version
fw->store_32( VERSION_MINOR );
fw->store_32( FORMAT_VERSION );
save_ustring(fw,get_ustring(f)); //type
size_t md_ofs = f->get_pos();
size_t importmd_ofs = f->get_64();
fw->store_64(0); //metadata offset
for(int i=0;i<14;i++) {
fw->store_32(0);
f->get_32();
}
//string table
uint32_t string_table_size=f->get_32();
fw->store_32(string_table_size);
for(uint32_t i=0;i<string_table_size;i++) {
String s = get_ustring(f);
save_ustring(fw,s);
}
//external resources
uint32_t ext_resources_size=f->get_32();
fw->store_32(ext_resources_size);
for(uint32_t i=0;i<ext_resources_size;i++) {
String type = get_ustring(f);
String path = get_ustring(f);
bool relative=false;
if (!path.begins_with("res://")) {
path=local_path.plus_file(path).simplify_path();
relative=true;
}
if (p_map.has(path)) {
String np=p_map[path];
path=np;
}
if (relative) {
//restore relative
path=local_path.path_to_file(path);
}
save_ustring(fw,type);
save_ustring(fw,path);
}
int64_t size_diff = (int64_t)fw->get_pos() - (int64_t)f->get_pos();
//internal resources
uint32_t int_resources_size=f->get_32();
fw->store_32(int_resources_size);
for(uint32_t i=0;i<int_resources_size;i++) {
String path=get_ustring(f);
uint64_t offset=f->get_64();
save_ustring(fw,path);
fw->store_64(offset+size_diff);
}
//rest of file
uint8_t b = f->get_8();
while(!f->eof_reached()) {
fw->store_8(b);
b = f->get_8();
}
bool all_ok = fw->get_error()==OK;
fw->seek(md_ofs);
fw->store_64(importmd_ofs+size_diff);
memdelete(f);
memdelete(fw);
if (!all_ok) {
return ERR_CANT_CREATE;
}
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
da->remove(p_path);
da->rename(p_path+".depren",p_path);
memdelete(da);
return OK;
}
@ -1433,10 +1710,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
}
if (res->get_path().length() && res->get_path().find("::")==-1) {
f->store_32(OBJECT_EXTERNAL_RESOURCE);
save_unicode_string(res->get_save_type());
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
save_unicode_string(path);
f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX);
f->store_32(external_resources[res]);
} else {
if (!resource_set.has(res)) {
@ -1594,11 +1869,12 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant
RES res = p_variant.operator RefPtr();
if (res.is_null())
if (res.is_null() || external_resources.has(res))
return;
if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
external_resources.insert(res);
int idx = external_resources.size();
external_resources[res]=idx;
return;
}
@ -1842,10 +2118,18 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
// save external resource table
f->store_32(external_resources.size()); //amount of external resources
for(Set<RES>::Element *E=external_resources.front();E;E=E->next()) {
Vector<RES> save_order;
save_order.resize(external_resources.size());
save_unicode_string(E->get()->get_save_type());
String path = E->get()->get_path();
for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
save_order[E->get()]=E->key();
}
for(int i=0;i<save_order.size();i++) {
save_unicode_string(save_order[i]->get_save_type());
String path = save_order[i]->get_path();
path=relative_paths?local_path.path_to_file(path):path;
save_unicode_string(path);
}
// save internal resource table
@ -1888,10 +2172,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
save_unicode_string("local://"+itos(r->get_subindex()));
if (takeover_paths) {
r->set_path(p_path+"::"+itos(ofs_pos.size()),true);
r->set_path(p_path+"::"+itos(r->get_subindex()),true);
}
} else
} else {
save_unicode_string(r->get_path()); //actual external
}
ofs_pos.push_back(f->get_pos());
f->store_64(0); //offset in 64 bits
}
@ -1995,3 +2280,9 @@ void ResourceFormatSaverBinary::get_recognized_extensions(const RES& p_resource,
}
ResourceFormatSaverBinary* ResourceFormatSaverBinary::singleton=NULL;
ResourceFormatSaverBinary::ResourceFormatSaverBinary() {
singleton=this;
}

View file

@ -71,6 +71,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
String get_unicode_string();
void _advance_padding(uint32_t p_len);
Map<String,String> remaps;
Error error;
int stage;
@ -88,9 +89,10 @@ public:
virtual int get_stage() const;
virtual int get_stage_count() const;
void set_remaps(const Map<String,String>& p_remaps) { remaps=p_remaps; }
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f,List<String> *p_dependencies);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
ResourceInteractiveLoaderBinary();
@ -101,13 +103,14 @@ public:
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const;
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
@ -134,7 +137,7 @@ class ResourceFormatSaverBinaryInstance {
Vector<StringName> strings;
Set<RES> external_resources;
Map<RES,int> external_resources;
List<RES> saved_resources;
@ -174,11 +177,12 @@ class ResourceFormatSaverBinary : public ResourceFormatSaver {
public:
static ResourceFormatSaverBinary* singleton;
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
virtual bool recognize(const RES& p_resource) const;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
ResourceFormatSaverBinary();
};

View file

@ -29,10 +29,10 @@
#include "resource_format_xml.h"
#include "globals.h"
#include "version.h"
#include "os/dir_access.h"
ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit,bool p_printerr) {
ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit, bool p_printerr, List<String> *r_order) {
while(get_char()!='<' && !f->eof_reached()) {}
@ -107,7 +107,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool
if (r_value.size()) {
r_value.push_back(0);
tag.args[name].parse_utf8(r_value.get_data());
String str;
str.parse_utf8(r_value.get_data());
tag.args[name]=str;
if (r_order)
r_order->push_back(name);
}
break;
@ -119,7 +123,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool
} else if (reading_value && r_value.size()) {
r_value.push_back(0);
tag.args[name].parse_utf8(r_value.get_data());
String str;
str.parse_utf8(r_value.get_data());
tag.args[name]=str;
if (r_order)
r_order->push_back(name);
name="";
r_value.clear();
reading_value=false;
@ -463,6 +471,10 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
}
if (remaps.has(path)) {
path=remaps[path];
}
//take advantage of the resource loader cache. The resource is cached on it, even if
RES res=ResourceLoader::load(path,hint);
@ -473,8 +485,29 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
}
r_v=res.get_ref_ptr();
} else if (tag->args.has("external")) {
int index = tag->args["external"].to_int();
if (ext_resources.has(index)) {
String path=ext_resources[index].path;
String type=ext_resources[index].type;
//take advantage of the resource loader cache. The resource is cached on it, even if
RES res=ResourceLoader::load(path,type);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load externalresource: "+path).ascii().get_data());
}
r_v=res.get_ref_ptr();
} else {
WARN_PRINT(String("Invalid external resource index: "+itos(index)).ascii().get_data());
}
}
Error err=goto_end_of_tag();
@ -1364,32 +1397,6 @@ Error ResourceInteractiveLoaderXML::poll() {
if (error!=OK)
return error;
if (ext_resources.size()) {
error=ERR_FILE_CORRUPT;
String path=ext_resources.front()->get();
RES res = ResourceLoader::load(path);
if (res.is_null()) {
if (ResourceLoader::get_abort_on_missing_resources()) {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": editor exported nonexistent resource at: "+path);
ERR_FAIL_V(error);
} else {
ResourceLoader::notify_load_error("Resource Not Found: "+path);
}
} else {
resource_cache.push_back(res);
}
error=OK;
ext_resources.pop_front();
resource_current++;
return error;
}
bool exit;
Tag *tag = parse_tag(&exit);
@ -1413,12 +1420,13 @@ Error ResourceInteractiveLoaderXML::poll() {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT);
String type;
String type="Resource";
if (tag->args.has("type"))
type=tag->args["type"];
String path = tag->args["path"];
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?.");
ERR_FAIL_COND_V(path.begins_with("local://"),ERR_FILE_CORRUPT);
@ -1427,6 +1435,9 @@ Error ResourceInteractiveLoaderXML::poll() {
path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path));
}
if (remaps.has(path)) {
path=remaps[path];
}
RES res = ResourceLoader::load(path,type);
@ -1436,13 +1447,21 @@ Error ResourceInteractiveLoaderXML::poll() {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path);
ERR_FAIL_V(error);
} else {
ResourceLoader::notify_load_error("Resource Not Found: "+path);
ResourceLoader::notify_dependency_error(local_path,path,type);
}
} else {
resource_cache.push_back(res);
}
if (tag->args.has("index")) {
ExtResource er;
er.path=path;
er.type=type;
ext_resources[tag->args["index"].to_int()]=er;
}
Error err = close_tag("ext_resource");
if (err)
return error;
@ -1566,7 +1585,7 @@ int ResourceInteractiveLoaderXML::get_stage() const {
}
int ResourceInteractiveLoaderXML::get_stage_count() const {
return resources_total+ext_resources.size();
return resources_total;//+ext_resources;
}
ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
@ -1574,7 +1593,7 @@ ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
memdelete(f);
}
void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies) {
void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) {
open(f);
@ -1617,6 +1636,10 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
path = ResourceLoader::guess_full_filename(path,type);
}
if (p_add_types && tag->args.has("type")) {
path+="::"+tag->args["type"];
}
p_dependencies->push_back(path);
Error err = close_tag("ext_resource");
@ -1628,6 +1651,167 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
}
Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
open(p_f);
ERR_FAIL_COND_V(error!=OK,error);
//FileAccess
bool old_format=false;
FileAccess *fw = NULL;
String base_path=local_path.get_base_dir();
while(true) {
bool exit;
List<String> order;
Tag *tag = parse_tag(&exit,true,&order);
bool done=false;
if (!tag) {
if (fw) {
memdelete(fw);
}
error=ERR_FILE_CORRUPT;
ERR_FAIL_COND_V(!exit,error);
error=ERR_FILE_EOF;
return error;
}
if (tag->name=="ext_resource") {
if (!tag->args.has("index") || !tag->args.has("path") || !tag->args.has("type")) {
old_format=true;
break;
}
if (!fw) {
fw=FileAccess::open(p_path+".depren",FileAccess::WRITE);
fw->store_line("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); //no escape
fw->store_line("<resource_file type=\""+resource_type+"\" subresource_count=\""+itos(resources_total)+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\">");
}
String path = tag->args["path"];
String index = tag->args["index"];
String type = tag->args["type"];
bool relative=false;
if (!path.begins_with("res://")) {
path=base_path.plus_file(path).simplify_path();
relative=true;
}
if (p_map.has(path)) {
String np=p_map[path];
path=np;
}
if (relative) {
//restore relative
path=base_path.path_to_file(path);
}
tag->args["path"]=path;
tag->args["index"]=index;
tag->args["type"]=type;
} else {
done=true;
}
String tagt="\t<";
if (exit)
tagt+="/";
tagt+=tag->name;
for(List<String>::Element *E=order.front();E;E=E->next()) {
tagt+=" "+E->get()+"=\""+tag->args[E->get()]+"\"";
}
tagt+=">";
fw->store_line(tagt);
if (done)
break;
close_tag("ext_resource");
fw->store_line("\t</ext_resource>");
}
if (old_format) {
if (fw)
memdelete(fw);
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->remove(p_path+".depren");
memdelete(da);
//fuck it, use the old approach;
WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data());
Error err;
FileAccess *f2 = FileAccess::open(p_path,FileAccess::READ,&err);
if (err!=OK) {
ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN);
}
Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
ria->remaps=p_map;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
ria->open(f2);
err = ria->poll();
while(err==OK) {
err=ria->poll();
}
ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT);
RES res = ria->get_resource();
ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT);
return ResourceFormatSaverXML::singleton->save(p_path,res);
}
if (!fw) {
return OK; //nothing to rename, do nothing
}
uint8_t c=f->get_8();
while(!f->eof_reached()) {
fw->store_8(c);
c=f->get_8();
}
bool all_ok = fw->get_error()==OK;
memdelete(fw);
if (!all_ok) {
return ERR_CANT_CREATE;
}
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
da->remove(p_path);
da->rename(p_path+".depren",p_path);
memdelete(da);
return OK;
}
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
@ -1686,6 +1870,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
}
/*
String preload_depts = "deps/"+local_path.md5_text();
if (Globals::get_singleton()->has(preload_depts)) {
ext_resources.clear();
@ -1697,7 +1882,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
}
print_line(local_path+" - EXTERNAL RESOURCES: "+itos(ext_resources.size()));
}
*/
}
@ -1730,7 +1915,10 @@ String ResourceInteractiveLoaderXML::recognize(FileAccess *p_f) {
/////////////////////
Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path) {
Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
Error err;
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@ -1816,7 +2004,7 @@ String ResourceFormatLoaderXML::get_resource_type(const String &p_path) const{
}
void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies) {
void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
if (!f) {
@ -1828,11 +2016,27 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String>
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
ria->get_dependencies(f,p_dependencies);
ria->get_dependencies(f,p_dependencies,p_add_types);
}
Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
if (!f) {
ERR_FAIL_V(ERR_CANT_OPEN);
}
Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
return ria->rename_dependencies(f,p_path,p_map);
}
/****************************************************************************************/
/****************************************************************************************/
/****************************************************************************************/
@ -1852,8 +2056,8 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String>
void ResourceFormatSaverXMLInstance::escape(String& p_str) {
p_str=p_str.replace("&","&amp;");
p_str=p_str.replace("<","&gt;");
p_str=p_str.replace(">","&lt;");
p_str=p_str.replace("<","&lt;");
p_str=p_str.replace(">","&gt;");
p_str=p_str.replace("'","&apos;");
p_str=p_str.replace("\"","&quot;");
for (char i=1;i<32;i++) {
@ -2024,8 +2228,13 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
return; // don't save it
}
if (external_resources.has(res)) {
params="external=\""+itos(external_resources[res])+"\"";
} else {
params="resource_type=\""+res->get_save_type()+"\"";
if (res->get_path().length() && res->get_path().find("::")==-1) {
//external resource
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
@ -2039,6 +2248,7 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
params+=" path=\"local://"+itos(res->get_subindex())+"\"";
}
}
} break;
case Variant::INPUT_EVENT: type="input_event"; break;
@ -2441,11 +2651,12 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo
RES res = p_variant.operator RefPtr();
if (res.is_null())
if (res.is_null() || external_resources.has(res))
return;
if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
external_resources.push_back(res);
int index = external_resources.size();
external_resources[res]=index;
return;
}
@ -2533,12 +2744,12 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
enter_tag("resource_file","type=\""+p_resource->get_type()+"\" subresource_count=\""+itos(saved_resources.size()+external_resources.size())+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\"");
write_string("\n",false);
for(List<RES>::Element *E=external_resources.front();E;E=E->next()) {
for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
write_tabs();
String p = E->get()->get_path();
String p = E->key()->get_path();
enter_tag("ext_resource","path=\""+p+"\" type=\""+E->get()->get_save_type()+"\""); //bundled
enter_tag("ext_resource","path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" index=\""+itos(E->get())+"\""); //bundled
exit_tag("ext_resource"); //bundled
write_string("\n",false);
}
@ -2667,3 +2878,8 @@ void ResourceFormatSaverXML::get_recognized_extensions(const RES& p_resource,Lis
}
}
ResourceFormatSaverXML* ResourceFormatSaverXML::singleton=NULL;
ResourceFormatSaverXML::ResourceFormatSaverXML() {
singleton=this;
}

View file

@ -46,13 +46,21 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
String name;
HashMap<String,String> args;
};
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end);
struct ExtResource {
String path;
String type;
};
List<StringName> ext_resources;
Map<String,String> remaps;
Map<int,ExtResource> ext_resources;
int resources_total;
int resource_current;
@ -66,7 +74,7 @@ friend class ResourceFormatLoaderXML;
List<Tag> tag_stack;
List<RES> resource_cache;
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true);
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true,List<String> *r_order=NULL);
Error close_tag(const String& p_name);
_FORCE_INLINE_ void unquote(String& p_str);
Error goto_end_of_tag();
@ -87,7 +95,8 @@ public:
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f,List<String> *p_dependencies);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
~ResourceInteractiveLoaderXML();
@ -97,12 +106,13 @@ public:
class ResourceFormatLoaderXML : public ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
};
@ -125,7 +135,7 @@ class ResourceFormatSaverXMLInstance {
int depth;
Set<RES> resource_set;
List<RES> saved_resources;
List<RES> external_resources;
Map<RES,int> external_resources;
void enter_tag(const char* p_tag,const String& p_args=String());
void exit_tag(const char* p_tag);
@ -148,11 +158,12 @@ public:
class ResourceFormatSaverXML : public ResourceFormatSaver {
public:
static ResourceFormatSaverXML* singleton;
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
virtual bool recognize(const RES& p_resource) const;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
ResourceFormatSaverXML();
};

View file

@ -103,10 +103,10 @@ public:
Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path) {
Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) {
//either this
Ref<Resource> res = load(p_path);
Ref<Resource> res = load(p_path,p_path,r_error);
if (res.is_null())
return Ref<ResourceInteractiveLoader>();
@ -115,12 +115,13 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const Stri
return ril;
}
RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) {
RES ResourceFormatLoader::load(const String &p_path, const String& p_original_path, Error *r_error) {
String path=p_path;
//or this must be implemented
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path);
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path,r_error);
if (!ril.is_valid())
return RES();
ril->set_local_path(p_original_path);
@ -130,9 +131,14 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat
Error err = ril->poll();
if (err==ERR_FILE_EOF) {
if (r_error)
*r_error=OK;
return ril->get_resource();
}
if (r_error)
*r_error=err;
ERR_FAIL_COND_V(err!=OK,RES());
}
@ -140,7 +146,7 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat
}
void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
void ResourceFormatLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
//do nothing by default
}
@ -149,7 +155,10 @@ void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p
///////////////////////////////////
RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) {
RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
String local_path;
if (p_path.is_rel_path())
@ -183,7 +192,7 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
found=true;
RES res = loader[i]->load(remapped_path,local_path);
RES res = loader[i]->load(remapped_path,local_path,r_error);
if (res.is_null())
continue;
if (!p_no_cache)
@ -222,14 +231,12 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p
local_path = Globals::get_singleton()->localize_path(p_path);
String extension=p_path.extension();
bool found=false;
Ref<ResourceImportMetadata> ret;
for (int i=0;i<loader_count;i++) {
if (!loader[i]->recognize(extension))
continue;
found=true;
Error err = loader[i]->load_import_metadata(local_path,ret);
if (err==OK)
@ -289,9 +296,11 @@ String ResourceLoader::find_complete_path(const String& p_path,const String& p_t
return local_path;
}
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache) {
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache,Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
String local_path;
if (p_path.is_rel_path())
@ -327,7 +336,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
found=true;
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path);
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path,r_error);
if (ril.is_null())
continue;
if (!p_no_cache)
@ -352,7 +361,7 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l
loader[loader_count++]=p_format_loader;
}
void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
String local_path;
@ -372,11 +381,40 @@ void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_depen
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
// continue;
loader[i]->get_dependencies(remapped_path,p_dependencies);
loader[i]->get_dependencies(remapped_path,p_dependencies,p_add_types);
}
}
Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
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();
for (int i=0;i<loader_count;i++) {
if (!loader[i]->recognize(extension))
continue;
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
// continue;
return loader[i]->rename_dependencies(p_path,p_map);
}
return OK; // ??
}
String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {
String local_path;
@ -414,6 +452,9 @@ String ResourceLoader::get_resource_type(const String &p_path) {
ResourceLoadErrorNotify ResourceLoader::err_notify=NULL;
void *ResourceLoader::err_notify_ud=NULL;
DependencyErrorNotify ResourceLoader::dep_err_notify=NULL;
void *ResourceLoader::dep_err_notify_ud=NULL;
bool ResourceLoader::abort_on_missing_resource=true;
bool ResourceLoader::timestamp_on_load=false;

View file

@ -57,21 +57,23 @@ public:
class ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
virtual RES load(const String &p_path,const String& p_original_path="");
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
bool recognize(const String& p_extension) const;
virtual bool handles_type(const String& p_type) const=0;
virtual String get_resource_type(const String &p_path) const=0;
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const { return ERR_UNAVAILABLE; }
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map) { return OK; }
virtual ~ResourceFormatLoader() {}
};
typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
class ResourceLoader {
@ -86,6 +88,8 @@ class ResourceLoader {
static void* err_notify_ud;
static ResourceLoadErrorNotify err_notify;
static void* dep_err_notify_ud;
static DependencyErrorNotify dep_err_notify;
static bool abort_on_missing_resource;
static String find_complete_path(const String& p_path,const String& p_type);
@ -93,14 +97,15 @@ public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false);
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false);
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
static void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions);
static void add_resource_format_loader(ResourceFormatLoader *p_format_loader);
static String get_resource_type(const String &p_path);
static void get_dependencies(const String& p_path,List<String> *p_dependencies);
static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
static String guess_full_filename(const String &p_path,const String& p_type);
@ -108,6 +113,11 @@ public:
static void notify_load_error(const String& p_err) { if (err_notify) err_notify(err_notify_ud,p_err); }
static void set_error_notify_func(void* p_ud,ResourceLoadErrorNotify p_err_notify) { err_notify=p_err_notify; err_notify_ud=p_ud;}
static void notify_dependency_error(const String& p_path,const String& p_dependency,const String& p_type) { if (dep_err_notify) dep_err_notify(dep_err_notify_ud,p_path,p_dependency,p_type); }
static void set_dependency_error_notify_func(void* p_ud,DependencyErrorNotify p_err_notify) { dep_err_notify=p_err_notify; dep_err_notify_ud=p_ud;}
static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource=p_abort; }
static bool get_abort_on_missing_resources() { return abort_on_missing_resource; }
};

View file

@ -30,7 +30,10 @@
#include "os/file_access.h"
#include "translation.h"
RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path) {
RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!f,RES());
@ -49,6 +52,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path
String msg_id;
String msg_str;
String config;
if (r_error)
*r_error=ERR_FILE_CORRUPT;
Ref<Translation> translation = Ref<Translation>( memnew( Translation ));
int line = 1;
@ -174,6 +179,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path
}
}
if (r_error)
*r_error=OK;
return translation;

View file

@ -34,7 +34,7 @@
class TranslationLoaderPO : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path,const String& p_original_path="");
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;

View file

@ -1788,7 +1788,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
return UNZ_PARAMERROR;
if ((pfile_in_zip_read_info->read_buffer == NULL))
if (pfile_in_zip_read_info->read_buffer==NULL)
return UNZ_END_OF_LIST_OF_FILE;
if (len==0)
return 0;

View file

@ -1114,9 +1114,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
zi->ci.flag = flagBase;
if ((level==8) || (level==9))
zi->ci.flag |= 2;
if ((level==2))
if (level==2)
zi->ci.flag |= 4;
if ((level==1))
if (level==1)
zi->ci.flag |= 6;
if (password != NULL)
zi->ci.flag |= 1;

View file

@ -39,6 +39,8 @@
#ifndef _zip12_H
#define _zip12_H
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -34,6 +34,7 @@
#include "os/file_access.h"
#include "os/copymem.h"
static void* zipio_open(void* data, const char* p_fname, int mode) {
FileAccess *&f = *(FileAccess**)data;

View file

@ -518,10 +518,16 @@ public:
if (value->prev_ptr) {
value->prev_ptr->next_ptr = value->next_ptr;
};
}
else {
_data->first = value->next_ptr;
}
if (value->next_ptr) {
value->next_ptr->prev_ptr = value->prev_ptr;
};
}
else {
_data->last = value->prev_ptr;
}
value->next_ptr = where;
if (!where) {

View file

@ -79,9 +79,9 @@ public:
return Math::log( p_linear ) * 8.6858896380650365530225783783321;
}
static inline double db2linear(double p_linear) {
static inline double db2linear(double p_db) {
return Math::exp( p_linear * 0.11512925464970228420089957273422 );
return Math::exp( p_db * 0.11512925464970228420089957273422 );
}
static bool is_nan(double p_val);

View file

@ -107,6 +107,8 @@ struct Vector3 {
_FORCE_INLINE_ real_t dot(const Vector3& p_b) const;
_FORCE_INLINE_ Vector3 abs() const;
_FORCE_INLINE_ Vector3 floor() const;
_FORCE_INLINE_ Vector3 ceil() const;
_FORCE_INLINE_ real_t distance_to(const Vector3& p_b) const;
_FORCE_INLINE_ real_t distance_squared_to(const Vector3& p_b) const;
@ -174,6 +176,16 @@ Vector3 Vector3::abs() const {
return Vector3( Math::abs(x), Math::abs(y), Math::abs(z) );
}
Vector3 Vector3::floor() const {
return Vector3( Math::floor(x), Math::floor(y), Math::floor(z) );
}
Vector3 Vector3::ceil() const {
return Vector3( Math::ceil(x), Math::ceil(y), Math::ceil(z) );
}
Vector3 Vector3::linear_interpolate(const Vector3& p_b,float p_t) const {
return Vector3(

View file

@ -49,7 +49,7 @@
enum PropertyHint {
PROPERTY_HINT_NONE, ///< no hint provided.
PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step"
PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step,slider; //slider is optional"
PROPERTY_HINT_EXP_RANGE, ///< hint_text = "min,max,step", exponential edit
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease)

View file

@ -746,6 +746,25 @@ bool ObjectTypeDB::has_method(StringName p_type,StringName p_method,bool p_no_in
}
bool ObjectTypeDB::get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter) {
TypeInfo *type=types.getptr(p_class);
TypeInfo *check=type;
while(check) {
if (check->property_setget.has(p_prop)) {
r_class=check->name;
r_setter=check->property_setget[p_prop].setter;
return true;
}
check=check->inherits_ptr;
}
return false;
}
#ifdef DEBUG_METHODS_ENABLED
MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) {
StringName mdname=method_name.name;

View file

@ -476,6 +476,8 @@ public:
static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
static StringName get_category(const StringName& p_node);
static bool get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter);
static void set_type_enabled(StringName p_type,bool p_enable);
static bool is_type_enabled(StringName p_type);

View file

@ -64,6 +64,7 @@ void Input::_bind_methods() {
ObjectTypeDB::bind_method(_MD("warp_mouse_pos","to"),&Input::warp_mouse_pos);
ObjectTypeDB::bind_method(_MD("action_press"),&Input::action_press);
ObjectTypeDB::bind_method(_MD("action_release"),&Input::action_release);
ObjectTypeDB::bind_method(_MD("set_custom_mouse_cursor","image:Texture","hotspot"),&Input::set_custom_mouse_cursor,DEFVAL(Vector2()));
BIND_CONSTANT( MOUSE_MODE_VISIBLE );
BIND_CONSTANT( MOUSE_MODE_HIDDEN );
@ -104,266 +105,3 @@ Input::Input() {
//////////////////////////////////////////////////////////
void InputDefault::SpeedTrack::update(const Vector2& p_delta_p) {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
uint32_t tdiff = tick-last_tick;
float delta_t = tdiff / 1000000.0;
last_tick=tick;
accum+=p_delta_p;
accum_t+=delta_t;
if (accum_t>max_ref_frame*10)
accum_t=max_ref_frame*10;
while( accum_t>=min_ref_frame ) {
float slice_t = min_ref_frame / accum_t;
Vector2 slice = accum*slice_t;
accum=accum-slice;
accum_t-=min_ref_frame;
speed=(slice/min_ref_frame).linear_interpolate(speed,min_ref_frame/max_ref_frame);
}
}
void InputDefault::SpeedTrack::reset() {
last_tick = OS::get_singleton()->get_ticks_usec();
speed=Vector2();
accum_t=0;
}
InputDefault::SpeedTrack::SpeedTrack() {
min_ref_frame=0.1;
max_ref_frame=0.3;
reset();
}
bool InputDefault::is_key_pressed(int p_scancode) {
_THREAD_SAFE_METHOD_
return keys_pressed.has(p_scancode);
}
bool InputDefault::is_mouse_button_pressed(int p_button) {
_THREAD_SAFE_METHOD_
return (mouse_button_mask&(1<<p_button))!=0;
}
static int _combine_device(int p_value,int p_device) {
return p_value|(p_device<<20);
}
bool InputDefault::is_joy_button_pressed(int p_device, int p_button) {
_THREAD_SAFE_METHOD_
return joy_buttons_pressed.has(_combine_device(p_button,p_device));
}
bool InputDefault::is_action_pressed(const StringName& p_action) {
if (custom_action_press.has(p_action))
return true; //simpler
const List<InputEvent> *alist = InputMap::get_singleton()->get_action_list(p_action);
if (!alist)
return NULL;
for (const List<InputEvent>::Element *E=alist->front();E;E=E->next()) {
int device=E->get().device;
switch(E->get().type) {
case InputEvent::KEY: {
const InputEventKey &iek=E->get().key;
if ((keys_pressed.has(iek.scancode)))
return true;
} break;
case InputEvent::MOUSE_BUTTON: {
const InputEventMouseButton &iemb=E->get().mouse_button;
if(mouse_button_mask&(1<<iemb.button_index))
return true;
} break;
case InputEvent::JOYSTICK_BUTTON: {
const InputEventJoystickButton &iejb=E->get().joy_button;
int c = _combine_device(iejb.button_index,device);
if (joy_buttons_pressed.has(c))
return true;
} break;
}
}
return false;
}
float InputDefault::get_joy_axis(int p_device,int p_axis) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
if (joy_axis.has(c)) {
return joy_axis[c];
} else {
return 0;
}
}
String InputDefault::get_joy_name(int p_idx) {
_THREAD_SAFE_METHOD_
return joy_names[p_idx];
};
void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_name) {
_THREAD_SAFE_METHOD_
joy_names[p_idx] = p_connected ? p_name : "";
emit_signal("joy_connection_changed", p_idx, p_connected);
};
Vector3 InputDefault::get_accelerometer() {
_THREAD_SAFE_METHOD_
return accelerometer;
}
void InputDefault::parse_input_event(const InputEvent& p_event) {
_THREAD_SAFE_METHOD_
switch(p_event.type) {
case InputEvent::KEY: {
if (p_event.key.echo)
break;
if (p_event.key.scancode==0)
break;
// print_line(p_event);
if (p_event.key.pressed)
keys_pressed.insert(p_event.key.scancode);
else
keys_pressed.erase(p_event.key.scancode);
} break;
case InputEvent::MOUSE_BUTTON: {
if (p_event.mouse_button.doubleclick)
break;
if (p_event.mouse_button.pressed)
mouse_button_mask|=(1<<p_event.mouse_button.button_index);
else
mouse_button_mask&=~(1<<p_event.mouse_button.button_index);
} break;
case InputEvent::JOYSTICK_BUTTON: {
int c = _combine_device(p_event.joy_button.button_index,p_event.device);
if (p_event.joy_button.pressed)
joy_buttons_pressed.insert(c);
else
joy_buttons_pressed.erase(c);
} break;
case InputEvent::JOYSTICK_MOTION: {
set_joy_axis(p_event.device, p_event.joy_motion.axis, p_event.joy_motion.axis_value);
} break;
}
if (main_loop)
main_loop->input_event(p_event);
}
void InputDefault::set_joy_axis(int p_device,int p_axis,float p_value) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
joy_axis[c]=p_value;
}
void InputDefault::set_accelerometer(const Vector3& p_accel) {
_THREAD_SAFE_METHOD_
accelerometer=p_accel;
}
void InputDefault::set_main_loop(MainLoop *p_main_loop) {
main_loop=p_main_loop;
}
void InputDefault::set_mouse_pos(const Point2& p_posf) {
mouse_speed_track.update(p_posf-mouse_pos);
mouse_pos=p_posf;
}
Point2 InputDefault::get_mouse_pos() const {
return mouse_pos;
}
Point2 InputDefault::get_mouse_speed() const {
return mouse_speed_track.speed;
}
int InputDefault::get_mouse_button_mask() const {
return OS::get_singleton()->get_mouse_button_state();
}
void InputDefault::warp_mouse_pos(const Vector2& p_to) {
OS::get_singleton()->warp_mouse_pos(p_to);
}
void InputDefault::iteration(float p_step) {
}
void InputDefault::action_press(const StringName& p_action) {
if (custom_action_press.has(p_action)) {
custom_action_press[p_action]++;
} else {
custom_action_press[p_action]=1;
}
}
void InputDefault::action_release(const StringName& p_action){
ERR_FAIL_COND(!custom_action_press.has(p_action));
custom_action_press[p_action]--;
if (custom_action_press[p_action]==0) {
custom_action_press.erase(p_action);
}
}
InputDefault::InputDefault() {
mouse_button_mask=0;
main_loop=NULL;
}

View file

@ -78,77 +78,15 @@ public:
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
virtual bool is_emulating_touchscreen() const=0;
virtual void set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot=Vector2())=0;
virtual void set_mouse_in_window(bool p_in_window)=0;
Input();
};
VARIANT_ENUM_CAST(Input::MouseMode);
class InputDefault : public Input {
OBJ_TYPE( InputDefault, Input );
_THREAD_SAFE_CLASS_
int mouse_button_mask;
Set<int> keys_pressed;
Set<int> joy_buttons_pressed;
Map<int,float> joy_axis;
Map<StringName,int> custom_action_press;
Map<int, String> joy_names;
Vector3 accelerometer;
Vector2 mouse_pos;
MainLoop *main_loop;
struct SpeedTrack {
uint64_t last_tick;
Vector2 speed;
Vector2 accum;
float accum_t;
float min_ref_frame;
float max_ref_frame;
void update(const Vector2& p_delta_p);
void reset();
SpeedTrack();
};
SpeedTrack mouse_speed_track;
public:
virtual bool is_key_pressed(int p_scancode);
virtual bool is_mouse_button_pressed(int p_button);
virtual bool is_joy_button_pressed(int p_device, int p_button);
virtual bool is_action_pressed(const StringName& p_action);
virtual float get_joy_axis(int p_device,int p_axis);
String get_joy_name(int p_idx);
void joy_connection_changed(int p_idx, bool p_connected, String p_name);
virtual Vector3 get_accelerometer();
virtual Point2 get_mouse_pos() const;
virtual Point2 get_mouse_speed() const;
virtual int get_mouse_button_mask() const;
virtual void warp_mouse_pos(const Vector2& p_to);
void parse_input_event(const InputEvent& p_event);
void set_accelerometer(const Vector3& p_accel);
void set_joy_axis(int p_device,int p_axis,float p_value);
void set_main_loop(MainLoop *main_loop);
void set_mouse_pos(const Point2& p_posf);
void action_press(const StringName& p_action);
void action_release(const StringName& p_action);
void iteration(float p_step);
InputDefault();
};
#endif // INPUT_H

View file

@ -45,7 +45,8 @@ void MainLoop::_bind_methods() {
BIND_VMETHOD( MethodInfo("_idle",PropertyInfo(Variant::REAL,"delta")) );
BIND_VMETHOD( MethodInfo("_finalize") );
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER);
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT);
BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST);

View file

@ -47,6 +47,8 @@ protected:
public:
enum {
NOTIFICATION_WM_MOUSE_ENTER = 3,
NOTIFICATION_WM_MOUSE_EXIT = 4,
NOTIFICATION_WM_FOCUS_IN = 5,
NOTIFICATION_WM_FOCUS_OUT = 6,
NOTIFICATION_WM_QUIT_REQUEST = 7,

View file

@ -31,7 +31,7 @@
#include <stdarg.h>
#include "dir_access.h"
#include "globals.h"
#include "input.h"
OS* OS::singleton=NULL;
@ -50,7 +50,9 @@ uint64_t OS::get_unix_time() const {
return 0;
};
uint64_t OS::get_system_time_msec() const {
return 0;
}
void OS::debug_break() {
// something
@ -361,7 +363,7 @@ Error OS::set_cwd(const String& p_cwd) {
bool OS::has_touchscreen_ui_hint() const {
//return false;
return GLOBAL_DEF("display/emulate_touchscreen",false);
return Input::get_singleton() && Input::get_singleton()->is_emulating_touchscreen();
}
int OS::get_free_static_memory() const {
@ -514,6 +516,7 @@ OS::OS() {
_target_fps=0;
_render_thread_mode=RENDER_THREAD_SAFE;
_time_scale=1.0;
_pixel_snap=false;
Math::seed(1234567);
}

View file

@ -58,6 +58,7 @@ class OS {
float _fps;
int _target_fps;
float _time_scale;
bool _pixel_snap;
char *last_error;
@ -155,7 +156,7 @@ public:
virtual int get_screen_count() const{ return 1; }
virtual int get_current_screen() const { return 0; }
virtual void set_current_screen(int p_screen) { }
virtual Point2 get_screen_position(int p_screen=0) { return Point2(); }
virtual Point2 get_screen_position(int p_screen=0) const { return Point2(); }
virtual Size2 get_screen_size(int p_screen=0) const { return get_window_size(); }
virtual Point2 get_window_position() const { return Vector2(); }
virtual void set_window_position(const Point2& p_position) {}
@ -254,6 +255,7 @@ public:
virtual Time get_time(bool local=false) const=0;
virtual TimeZoneInfo get_time_zone_info() const=0;
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_msec() const;
virtual void delay_usec(uint32_t p_usec) const=0;
virtual uint64_t get_ticks_usec() const=0;
@ -392,7 +394,7 @@ public:
void set_time_scale(float p_scale);
float get_time_scale() const;
_FORCE_INLINE_ bool get_use_pixel_snap() const { return _pixel_snap; }
OS();
virtual ~OS();

View file

@ -286,6 +286,37 @@ NodePath::NodePath(const Vector<StringName>& p_path,const Vector<StringName>& p_
data->property=p_property;
}
void NodePath::simplify() {
if (!data)
return;
for(int i=0;i<data->path.size();i++) {
if (data->path.size()==1)
break;
if (data->path[i].operator String()==".") {
data->path.remove(i);
i--;
} else if (data->path[i].operator String()==".." && i>0 && data->path[i-1].operator String()!="." && data->path[i-1].operator String()!="..") {
//remove both
data->path.remove(i-1);
data->path.remove(i-1);
i-=2;
if (data->path.size()==0) {
data->path.push_back(".");
break;
}
}
}
}
NodePath NodePath::simplified() const {
NodePath np=*this;
np.simplify();
return np;
}
NodePath::NodePath(const String& p_path) {
data=NULL;

View file

@ -85,6 +85,9 @@ public:
bool operator!=(const NodePath& p_path) const;
void operator=(const NodePath& p_path);
void simplify();
NodePath simplified() const;
NodePath(const Vector<StringName>& p_path,bool p_absolute,const String& p_property="");
NodePath(const Vector<StringName>& p_path,const Vector<StringName>& p_subpath,bool p_absolute,const String& p_property="");
NodePath(const NodePath& p_path);

View file

@ -130,7 +130,7 @@ public:
void set_name(const String& p_name);
String get_name() const;
void set_path(const String& p_path,bool p_take_over=false);
virtual void set_path(const String& p_path,bool p_take_over=false);
String get_path() const;
void set_subindex(int p_sub_index);

View file

@ -141,15 +141,15 @@ public:
inline int space_left() {
int left = read_pos - write_pos;
if (left < 0) {
return size() + left;
return size() + left - 1;
};
if (left == 0) {
return size();
return size()-1;
};
return left;
return left -1;
};
inline int data_left() {
return size() - space_left();
return size() - space_left() - 1;
};
inline int size() {

View file

@ -31,10 +31,36 @@
#include "io/ip.h"
#include "globals.h"
void ScriptDebuggerRemote::_send_video_memory() {
List<ResourceUsage> usage;
if (resource_usage_func)
resource_usage_func(&usage);
usage.sort();
packet_peer_stream->put_var("message:video_mem");
packet_peer_stream->put_var(usage.size()*4);
for(List<ResourceUsage>::Element *E=usage.front();E;E=E->next()) {
packet_peer_stream->put_var(E->get().path);
packet_peer_stream->put_var(E->get().type);
packet_peer_stream->put_var(E->get().format);
packet_peer_stream->put_var(E->get().vram);
}
}
Error ScriptDebuggerRemote::connect_to_host(const String& p_host,uint16_t p_port) {
IP_Address ip = IP::get_singleton()->resolve_hostname(p_host);
IP_Address ip;
if (p_host.is_valid_ip_address())
ip=p_host;
else
ip = IP::get_singleton()->resolve_hostname(p_host);
int port = p_port;
@ -127,7 +153,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );
String command = cmd[0];
cmd.remove(0);
if (command=="get_stack_dump") {
@ -150,7 +176,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
} else if (command=="get_stack_frame_vars") {
cmd.remove(0);
ERR_CONTINUE( cmd.size()!=1 );
int lv = cmd[0];
@ -243,6 +269,20 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
if (request_scene_tree)
request_scene_tree(request_scene_tree_ud);
} else if (command=="request_video_mem") {
_send_video_memory();
} else if (command=="breakpoint") {
bool set = cmd[3];
if (set)
insert_breakpoint(cmd[2],cmd[1]);
else
remove_breakpoint(cmd[2],cmd[1]);
} else {
_parse_live_edit(cmd);
}
@ -287,6 +327,37 @@ void ScriptDebuggerRemote::_get_output() {
messages.pop_front();
locking=false;
}
while (errors.size()) {
locking=true;
packet_peer_stream->put_var("error");
OutputError oe = errors.front()->get();
packet_peer_stream->put_var(oe.callstack.size()+2);
Array error_data;
error_data.push_back(oe.hr);
error_data.push_back(oe.min);
error_data.push_back(oe.sec);
error_data.push_back(oe.msec);
error_data.push_back(oe.source_func);
error_data.push_back(oe.source_file);
error_data.push_back(oe.source_line);
error_data.push_back(oe.error);
error_data.push_back(oe.error_descr);
error_data.push_back(oe.warning);
packet_peer_stream->put_var(error_data);
packet_peer_stream->put_var(oe.callstack.size());
for(int i=0;i<oe.callstack.size();i++) {
packet_peer_stream->put_var(oe.callstack[i]);
}
errors.pop_front();
locking=false;
}
mutex->unlock();
}
@ -301,6 +372,160 @@ void ScriptDebuggerRemote::line_poll() {
}
void ScriptDebuggerRemote::_err_handler(void* ud,const char* p_func,const char*p_file,int p_line,const char *p_err, const char * p_descr,ErrorHandlerType p_type) {
if (p_type==ERR_HANDLER_SCRIPT)
return; //ignore script errors, those go through debugger
ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote*)ud;
OutputError oe;
oe.error=p_err;
oe.error_descr=p_descr;
oe.source_file=p_file;
oe.source_line=p_line;
oe.source_func=p_func;
oe.warning=p_type==ERR_HANDLER_WARNING;
uint64_t time = OS::get_singleton()->get_ticks_msec();
oe.hr=time/3600000;
oe.min=(time/60000)%60;
oe.sec=(time/1000)%60;
oe.msec=time%1000;
Array cstack;
Vector<ScriptLanguage::StackInfo> si;
for(int i=0;i<ScriptServer::get_language_count();i++) {
si=ScriptServer::get_language(i)->debug_get_current_stack_info();
if (si.size())
break;
}
cstack.resize(si.size()*2);
for(int i=0;i<si.size();i++) {
String path;
int line=0;
if (si[i].script.is_valid()) {
path=si[i].script->get_path();
line=si[i].line;
}
cstack[i*2+0]=path;
cstack[i*2+1]=line;
}
oe.callstack=cstack;
sdr->mutex->lock();
if (!sdr->locking && sdr->tcp_client->is_connected()) {
sdr->errors.push_back(oe);
}
sdr->mutex->unlock();
}
bool ScriptDebuggerRemote::_parse_live_edit(const Array& cmd) {
String cmdstr = cmd[0];
if (!live_edit_funcs || !cmdstr.begins_with("live_"))
return false;
//print_line(Variant(cmd).get_construct_string());
if (cmdstr=="live_set_root") {
if (!live_edit_funcs->root_func)
return true;
//print_line("root: "+Variant(cmd).get_construct_string());
live_edit_funcs->root_func(live_edit_funcs->udata,cmd[1],cmd[2]);
} else if (cmdstr=="live_node_path") {
if (!live_edit_funcs->node_path_func)
return true;
//print_line("path: "+Variant(cmd).get_construct_string());
live_edit_funcs->node_path_func(live_edit_funcs->udata,cmd[1],cmd[2]);
} else if (cmdstr=="live_res_path") {
if (!live_edit_funcs->res_path_func)
return true;
live_edit_funcs->res_path_func(live_edit_funcs->udata,cmd[1],cmd[2]);
} else if (cmdstr=="live_node_prop_res") {
if (!live_edit_funcs->node_set_res_func)
return true;
live_edit_funcs->node_set_res_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_node_prop") {
if (!live_edit_funcs->node_set_func)
return true;
live_edit_funcs->node_set_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_res_prop_res") {
if (!live_edit_funcs->res_set_res_func)
return true;
live_edit_funcs->res_set_res_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_res_prop") {
if (!live_edit_funcs->res_set_func)
return true;
live_edit_funcs->res_set_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_node_call") {
if (!live_edit_funcs->node_call_func)
return true;
live_edit_funcs->node_call_func(live_edit_funcs->udata,cmd[1],cmd[2], cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]);
} else if (cmdstr=="live_res_call") {
if (!live_edit_funcs->res_call_func)
return true;
live_edit_funcs->res_call_func(live_edit_funcs->udata,cmd[1],cmd[2], cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]);
} else if (cmdstr=="live_create_node") {
live_edit_funcs->tree_create_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_instance_node") {
live_edit_funcs->tree_instance_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_remove_node") {
live_edit_funcs->tree_remove_node_func(live_edit_funcs->udata,cmd[1]);
} else if (cmdstr=="live_remove_and_keep_node") {
live_edit_funcs->tree_remove_and_keep_node_func(live_edit_funcs->udata,cmd[1],cmd[2]);
} else if (cmdstr=="live_restore_node") {
live_edit_funcs->tree_restore_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
} else if (cmdstr=="live_duplicate_node") {
live_edit_funcs->tree_duplicate_node_func(live_edit_funcs->udata,cmd[1],cmd[2]);
} else if (cmdstr=="live_reparent_node") {
live_edit_funcs->tree_reparent_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3],cmd[4]);
} else {
return false;
}
return true;
}
void ScriptDebuggerRemote::_poll_events() {
while(packet_peer_stream->get_available_packet_count()>0) {
@ -321,7 +546,7 @@ void ScriptDebuggerRemote::_poll_events() {
ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );
String command = cmd[0];
cmd.remove(0);
//cmd.remove(0);
if (command=="break") {
@ -331,6 +556,18 @@ void ScriptDebuggerRemote::_poll_events() {
if (request_scene_tree)
request_scene_tree(request_scene_tree_ud);
} else if (command=="request_video_mem") {
_send_video_memory();
} else if (command=="breakpoint") {
bool set = cmd[3];
if (set)
insert_breakpoint(cmd[2],cmd[1]);
else
remove_breakpoint(cmd[2],cmd[1]);
} else {
_parse_live_edit(cmd);
}
}
@ -394,10 +631,35 @@ void ScriptDebuggerRemote::_print_handler(void *p_this,const String& p_string) {
ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote*)p_this;
uint64_t ticks = OS::get_singleton()->get_ticks_usec()/1000;
sdr->msec_count+=ticks-sdr->last_msec;
sdr->last_msec=ticks;
if (sdr->msec_count>1000) {
sdr->char_count=0;
sdr->msec_count=0;
}
String s = p_string;
int allowed_chars = MIN(MAX(sdr->max_cps - sdr->char_count,0), s.length());
if (allowed_chars==0)
return;
if (allowed_chars<s.length()) {
s=s.substr(0,allowed_chars);
}
sdr->char_count+=allowed_chars;
if (sdr->char_count>=sdr->max_cps) {
s+="\n[output overflow, print less text!]\n";
}
sdr->mutex->lock();
if (!sdr->locking && sdr->tcp_client->is_connected()) {
sdr->output_strings .push_back(p_string);
sdr->output_strings.push_back(s);
}
sdr->mutex->unlock();
}
@ -413,6 +675,13 @@ void ScriptDebuggerRemote::set_request_scene_tree_message_func(RequestSceneTreeM
request_scene_tree_ud=p_udata;
}
void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
live_edit_funcs=p_funcs;
}
ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func=NULL;
ScriptDebuggerRemote::ScriptDebuggerRemote() {
tcp_client = StreamPeerTCP::create_ref();
@ -429,13 +698,22 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
last_perf_time=0;
poll_every=0;
request_scene_tree=NULL;
live_edit_funcs=NULL;
max_cps = GLOBAL_DEF("debug/max_remote_stdout_chars_per_second",2048);
char_count=0;
msec_count=0;
last_msec=0;
eh.errfunc=_err_handler;
eh.userdata=this;
add_error_handler(&eh);
}
ScriptDebuggerRemote::~ScriptDebuggerRemote() {
remove_print_handler(&phl);
remove_error_handler(&eh);
memdelete(mutex);
}

View file

@ -34,6 +34,7 @@
#include "io/stream_peer_tcp.h"
#include "io/packet_peer.h"
#include "list.h"
class ScriptDebuggerRemote : public ScriptDebugger {
struct Message {
@ -42,6 +43,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
Array data;
};
Ref<StreamPeerTCP> tcp_client;
Ref<PacketPeerStream> packet_peer_stream;
@ -49,8 +52,31 @@ class ScriptDebuggerRemote : public ScriptDebugger {
Object *performance;
bool requested_quit;
Mutex *mutex;
struct OutputError {
int hr;
int min;
int sec;
int msec;
String source_file;
String source_func;
int source_line;
String error;
String error_descr;
bool warning;
Array callstack;
};
List<String> output_strings;
List<Message> messages;
List<OutputError> errors;
int max_cps;
int char_count;
uint64_t last_msec;
uint64_t msec_count;
bool locking; //hack to avoid a deadloop
static void _print_handler(void *p_this,const String& p_string);
@ -62,12 +88,34 @@ class ScriptDebuggerRemote : public ScriptDebugger {
uint32_t poll_every;
bool _parse_live_edit(const Array &p_command);
RequestSceneTreeMessageFunc request_scene_tree;
void *request_scene_tree_ud;
void _send_video_memory();
LiveEditFuncs *live_edit_funcs;
ErrorHandlerList eh;
static void _err_handler(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);
public:
struct ResourceUsage {
String path;
String format;
String type;
RID id;
int vram;
bool operator<(const ResourceUsage& p_img) const { return vram==p_img.vram ? id<p_img.id : vram > p_img.vram; }
};
typedef void (*ResourceUsageFunc)(List<ResourceUsage>*);
static ResourceUsageFunc resource_usage_func;
Error connect_to_host(const String& p_host,uint16_t p_port);
virtual void debug(ScriptLanguage *p_script,bool p_can_continue=true);
virtual void idle_poll();
@ -79,6 +127,7 @@ public:
virtual void send_message(const String& p_message, const Array& p_args);
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
ScriptDebuggerRemote();
~ScriptDebuggerRemote();

View file

@ -176,6 +176,13 @@ public:
virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems=-1,int p_max_depth=-1)=0;
virtual String debug_parse_stack_level_expression(int p_level,const String& p_expression,int p_max_subitems=-1,int p_max_depth=-1)=0;
struct StackInfo {
Ref<Script> script;
int line;
};
virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); }
/* LOADER FUNCTIONS */
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
@ -238,6 +245,32 @@ public:
typedef void (*RequestSceneTreeMessageFunc)(void *);
struct LiveEditFuncs {
void *udata;
void (*node_path_func)(void *,const NodePath &p_path,int p_id);
void (*res_path_func)(void *,const String &p_path,int p_id);
void (*node_set_func)(void *,int p_id,const StringName& p_prop,const Variant& p_value);
void (*node_set_res_func)(void *,int p_id,const StringName& p_prop,const String& p_value);
void (*node_call_func)(void *,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE);
void (*res_set_func)(void *,int p_id,const StringName& p_prop,const Variant& p_value);
void (*res_set_res_func)(void *,int p_id,const StringName& p_prop,const String& p_value);
void (*res_call_func)(void *,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE);
void (*root_func)(void*, const NodePath& p_scene_path,const String& p_scene_from);
void (*tree_create_node_func)(void*,const NodePath& p_parent,const String& p_type,const String& p_name);
void (*tree_instance_node_func)(void*,const NodePath& p_parent,const String& p_path,const String& p_name);
void (*tree_remove_node_func)(void*,const NodePath& p_at);
void (*tree_remove_and_keep_node_func)(void*,const NodePath& p_at,ObjectID p_keep_id);
void (*tree_restore_node_func)(void*,ObjectID p_id,const NodePath& p_at,int p_at_pos);
void (*tree_duplicate_node_func)(void*,const NodePath& p_at,const String& p_new_name);
void (*tree_reparent_node_func)(void*,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos);
};
_FORCE_INLINE_ static ScriptDebugger * get_singleton() { return singleton; }
void set_lines_left(int p_left);
int get_lines_left() const;
@ -252,10 +285,12 @@ public:
bool is_breakpoint_line(int p_line) const;
void clear_breakpoints();
virtual void debug(ScriptLanguage *p_script,bool p_can_continue=true)=0;
virtual void idle_poll();
virtual void line_poll();
void set_break_language(ScriptLanguage *p_lang);
ScriptLanguage* get_break_language() const;
@ -265,6 +300,7 @@ public:
virtual void request_quit() {}
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
ScriptDebugger();
virtual ~ScriptDebugger() {singleton=NULL;}

View file

@ -41,8 +41,8 @@
#define _MKSTR(m_x) _STR(m_x)
#endif
// have to include version.h for this to work, include it in the .cpp not the .h
#define VERSION_MKSTRING _MKSTR(VERSION_MAJOR)"."_MKSTR(VERSION_MINOR)"."_MKSTR(VERSION_STATUS)"."_MKSTR(VERSION_REVISION)
#define VERSION_FULL_NAME _MKSTR(VERSION_NAME)" v"VERSION_MKSTRING
#define VERSION_MKSTRING _MKSTR(VERSION_MAJOR)"." _MKSTR(VERSION_MINOR)"." _MKSTR(VERSION_STATUS)"." _MKSTR(VERSION_REVISION)
#define VERSION_FULL_NAME _MKSTR(VERSION_NAME)" v" VERSION_MKSTRING
#ifndef _ALWAYS_INLINE_

View file

@ -244,7 +244,12 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
Resource* res = obj->cast_to<Resource>();
if (res)
res->set_edited(true);
#endif
if (method_callback) {
method_callback(method_callbck_ud,obj,op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
}
} break;
case Operation::TYPE_PROPERTY: {
@ -254,6 +259,9 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
if (res)
res->set_edited(true);
#endif
if (property_callback) {
property_callback(prop_callback_ud,obj,op.name,op.args[0]);
}
} break;
case Operation::TYPE_REFERENCE: {
//do nothing
@ -325,6 +333,19 @@ void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback,void*
callback_ud=p_ud;
}
void UndoRedo::set_method_notify_callback(MethodNotifyCallback p_method_callback,void* p_ud) {
method_callback=p_method_callback;
method_callbck_ud=p_ud;
}
void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_callback,void* p_ud){
property_callback=p_property_callback;
prop_callback_ud=p_ud;
}
UndoRedo::UndoRedo() {
version=1;
@ -334,6 +355,12 @@ UndoRedo::UndoRedo() {
merging=true;
callback=NULL;
callback_ud=NULL;
method_callbck_ud=NULL;
prop_callback_ud=NULL;
method_callback=NULL;
property_callback=NULL;
}
UndoRedo::~UndoRedo() {

View file

@ -45,6 +45,9 @@ public:
Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
typedef void (*MethodNotifyCallback)(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE);
typedef void (*PropertyNotifyCallback)(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value);
private:
struct Operation {
@ -83,6 +86,11 @@ private:
CommitNotifyCallback callback;
void* callback_ud;
void* method_callbck_ud;
void* prop_callback_ud;
MethodNotifyCallback method_callback;
PropertyNotifyCallback property_callback;
protected:
@ -113,6 +121,9 @@ public:
void set_commit_notify_callback(CommitNotifyCallback p_callback,void* p_ud);
void set_method_notify_callback(MethodNotifyCallback p_method_callback,void* p_ud);
void set_property_notify_callback(PropertyNotifyCallback p_property_callback,void* p_ud);
UndoRedo();
~UndoRedo();
};

View file

@ -3048,6 +3048,37 @@ bool String::is_valid_identifier() const {
//kind of poor should be rewritten properly
String String::world_wrap(int p_chars_per_line) const {
int from=0;
int last_space=0;
String ret;
for(int i=0;i<length();i++) {
if (i-from>=p_chars_per_line) {
if (last_space==-1) {
ret+=substr(from,i-from+1)+"\n";
} else {
ret+=substr(from,last_space-from)+"\n";
i=last_space; //rewind
}
from=i+1;
last_space=-1;
} else if (operator[](i)==' ' || operator[](i)=='\t') {
last_space=i;
} else if (operator[](i)=='\n') {
ret+=substr(from,i-from)+"\n";
from=i+1;
last_space=-1;
}
}
if (from<length()) {
ret+=substr(from,length());
}
return ret;
}
String String::c_unescape() const {
String escaped=*this;
@ -3088,8 +3119,8 @@ String String::xml_escape(bool p_escape_quotes) const {
String str=*this;
str=str.replace("&","&amp;");
str=str.replace("<","&gt;");
str=str.replace(">","&lt;");
str=str.replace("<","&lt;");
str=str.replace(">","&gt;");
if (p_escape_quotes) {
str=str.replace("'","&apos;");
str=str.replace("\"","&quot;");
@ -3141,12 +3172,12 @@ static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src,int p_src_len,Char
} else if (p_src_len>=4 && p_src[1]=='g' && p_src[2]=='t' && p_src[3]==';') {
if (p_dst)
*p_dst='<';
*p_dst='>';
eat=4;
} else if (p_src_len>=4 && p_src[1]=='l' && p_src[2]=='t' && p_src[3]==';') {
if (p_dst)
*p_dst='>';
*p_dst='<';
eat=4;
} else if (p_src_len>=5 && p_src[1]=='a' && p_src[2]=='m' && p_src[3]=='p' && p_src[4]==';') {

View file

@ -209,6 +209,7 @@ public:
String xml_unescape() const;
String c_escape() const;
String c_unescape() const;
String world_wrap(int p_chars_per_line) const;
String percent_encode() const;
String percent_decode() const;

View file

@ -1592,9 +1592,17 @@ Variant::operator String() const {
} break;
case OBJECT: {
if (_get_obj().obj)
if (_get_obj().obj) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
//only if debugging!
if (!ObjectDB::instance_validate(_get_obj().obj)) {
return "[Deleted Object]";
};
};
#endif
return "["+_get_obj().obj->get_type()+":"+itos(_get_obj().obj->get_instance_ID())+"]";
else
} else
return "[Object:null]";
} break;

View file

@ -359,6 +359,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_LOCALMEM1R(Vector3, dot);
VCALL_LOCALMEM1R(Vector3, cross);
VCALL_LOCALMEM0R(Vector3, abs);
VCALL_LOCALMEM0R(Vector3, floor);
VCALL_LOCALMEM0R(Vector3, ceil);
VCALL_LOCALMEM1R(Vector3, distance_to);
VCALL_LOCALMEM1R(Vector3, distance_squared_to);
VCALL_LOCALMEM1R(Vector3, slide);
@ -1336,6 +1338,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC1(VECTOR3,REAL,Vector3,dot,VECTOR3,"b",varray());
ADDFUNC1(VECTOR3,VECTOR3,Vector3,cross,VECTOR3,"b",varray());
ADDFUNC0(VECTOR3,VECTOR3,Vector3,abs,varray());
ADDFUNC0(VECTOR3,VECTOR3,Vector3,floor,varray());
ADDFUNC0(VECTOR3,VECTOR3,Vector3,ceil,varray());
ADDFUNC1(VECTOR3,REAL,Vector3,distance_to,VECTOR3,"b",varray());
ADDFUNC1(VECTOR3,REAL,Vector3,distance_squared_to,VECTOR3,"b",varray());
ADDFUNC1(VECTOR3,VECTOR3,Vector3,slide,VECTOR3,"by",varray());
@ -1635,9 +1639,3 @@ void unregister_variant_methods() {
}

View file

@ -0,0 +1,21 @@
extends RigidBody2D
# member variables here, example:
# var a=2
# var b="textvar"
var timeout=5
func _process(delta):
timeout-=delta
if (timeout<1):
set_opacity(timeout)
if (timeout<0):
queue_free()
func _ready():
set_process(true)
# Initialization here
pass

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 889 B

View file

@ -0,0 +1,23 @@
extends Node2D
# member variables here, example:
# var a=2
# var b="textvar"
const EMIT_INTERVAL=0.1
var timeout=EMIT_INTERVAL
func _process(delta):
timeout-=delta
if (timeout<0):
timeout=EMIT_INTERVAL
var ball = preload("res://ball.scn").instance()
ball.set_pos( Vector2(randf() * get_viewport_rect().size.x, 0) )
add_child(ball)
func _ready():
set_process(true)
# Initialization here
pass

Binary file not shown.

View file

@ -0,0 +1,4 @@
[application]
name="Run-Time CollisionShape"
main_scene="res://dynamic_colobjs.scn"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

View file

@ -18,3 +18,11 @@ func _ready():
# Initalization here
pass
func _on_coin_area_enter( area ):
pass # replace with function body
func _on_coin_area_enter_shape( area_id, area, area_shape, area_shape ):
pass # replace with function body

View file

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<resource_file type="PackedScene" subresource_count="11" version="1.0" version_name="Godot Engine v1.0.3917-beta1">
<ext_resource path="res://sound_explode.*" type="Sample"></ext_resource>
<ext_resource path="res://enemy.*" type="Texture"></ext_resource>
<ext_resource path="res://enemy.*" type="Script"></ext_resource>
<ext_resource path="res://sound_hit.*" type="Sample"></ext_resource>
<ext_resource path="res://bullet.*" type="Texture"></ext_resource>
<resource_file type="PackedScene" subresource_count="12" version="2.0" version_name="Godot Engine v2.0.alpha.custom_build">
<ext_resource path="res://bullet.png" type="Texture" index="2"></ext_resource>
<ext_resource path="res://enemy.gd" type="Script" index="0"></ext_resource>
<ext_resource path="res://enemy.png" type="Texture" index="1"></ext_resource>
<ext_resource path="res://sound_hit.wav" type="Sample" index="4"></ext_resource>
<ext_resource path="res://sound_explode.wav" type="Sample" index="3"></ext_resource>
<resource type="CircleShape2D" path="local://1">
<real name="custom_solver_bias"> 0 </real>
<real name="radius"> 14 </real>
@ -21,6 +21,8 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="10"> 0, 0.75, 1.5, 2.25, 3, 3.75, 4.5, 5.25, 6, 6.75 </real_array>
<string> "transitions" </string>
<real_array len="10"> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
@ -36,8 +38,33 @@
<int> 7 </int>
<int> 5 </int>
</array>
</dictionary>
</resource>
<resource type="Animation" path="local://4">
<string name="resource/name"> "walk" </string>
<real name="length"> 1.25 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
<string name="tracks/0/type"> "value" </string>
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
<int name="tracks/0/interp"> 1 </int>
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="10"> 0, 0.75, 1.5, 2.25, 3, 3.75, 4.5, 5.25, 6, 6.75 </real_array>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
<string> "transitions" </string>
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
<array len="6" shared="false">
<int> 0 </int>
<int> 1 </int>
<int> 2 </int>
<int> 3 </int>
<int> 4 </int>
<int> 0 </int>
</array>
</dictionary>
</resource>
@ -52,6 +79,8 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> True </bool>
<string> "times" </string>
<real_array len="2"> 3.58422, 4.33851 </real_array>
<string> "transitions" </string>
<real_array len="2"> 1, 1 </real_array>
<string> "values" </string>
@ -59,8 +88,6 @@
<real> 1 </real>
<real> 0 </real>
</array>
<string> "times" </string>
<real_array len="2"> 3.58422, 4.33851 </real_array>
</dictionary>
<string name="tracks/1/type"> "value" </string>
<node_path name="tracks/1/path"> "sprite:frame" </node_path>
@ -68,14 +95,14 @@
<dictionary name="tracks/1/keys" shared="false">
<string> "cont" </string>
<bool> True </bool>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 4 </int>
</array>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
</dictionary>
<string name="tracks/2/type"> "value" </string>
<node_path name="tracks/2/path"> "Particles2D:config/emitting" </node_path>
@ -83,19 +110,21 @@
<dictionary name="tracks/2/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="1"> 3.47394 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<bool> True </bool>
</array>
<string> "times" </string>
<real_array len="1"> 3.47394 </real_array>
</dictionary>
<string name="tracks/3/type"> "method" </string>
<node_path name="tracks/3/path"> "." </node_path>
<int name="tracks/3/interp"> 1 </int>
<dictionary name="tracks/3/keys" shared="false">
<string> "times" </string>
<real_array len="2"> 3.20357, 5.07305 </real_array>
<string> "transitions" </string>
<real_array len="2"> 1, 1 </real_array>
<string> "values" </string>
@ -115,36 +144,12 @@
<string> "_die" </string>
</dictionary>
</array>
<string> "times" </string>
<real_array len="2"> 3.20357, 5.07305 </real_array>
</dictionary>
</resource>
<resource type="Animation" path="local://4">
<string name="resource/name"> "walk" </string>
<real name="length"> 1.25 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
<string name="tracks/0/type"> "value" </string>
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
<int name="tracks/0/interp"> 1 </int>
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "transitions" </string>
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
<array len="6" shared="false">
<int> 0 </int>
<int> 1 </int>
<int> 2 </int>
<int> 3 </int>
<int> 4 </int>
<int> 0 </int>
</array>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
</dictionary>
<resource type="ColorRamp" path="local://6">
<real_array name="offsets" len="2"> 0, 1 </real_array>
<color_array name="colors" len="2"> 1, 0.884956, 0.823009, 1, 0.768627, 0.389381, 0, 0 </color_array>
</resource>
<resource type="SampleLibrary" path="local://5">
@ -154,7 +159,7 @@
<string> "pitch" </string>
<real> 1 </real>
<string> "sample" </string>
<resource resource_type="Sample" path="res://sound_explode.*"> </resource>
<resource external="3"> </resource>
</dictionary>
<dictionary name="samples/hit" shared="false">
<string> "db" </string>
@ -162,24 +167,21 @@
<string> "pitch" </string>
<real> 1 </real>
<string> "sample" </string>
<resource resource_type="Sample" path="res://sound_hit.*"> </resource>
<resource external="4"> </resource>
</dictionary>
</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="132">
<string_array len="107">
<string> "enemy" </string>
<string> "RigidBody2D" </string>
<string> "visibility/visible" </string>
<string> "visibility/opacity" </string>
<string> "visibility/self_opacity" </string>
<string> "visibility/on_top" </string>
<string> "transform/pos" </string>
<string> "transform/rot" </string>
<string> "transform/scale" </string>
<string> "shape_count" </string>
<string> "input/pickable" </string>
<string> "shapes/0/shape" </string>
<string> "shapes/0/transform" </string>
<string> "shapes/0/trigger" </string>
@ -189,71 +191,71 @@
<string> "shapes/2/shape" </string>
<string> "shapes/2/transform" </string>
<string> "shapes/2/trigger" </string>
<string> "collision/layers" </string>
<string> "collision/mask" </string>
<string> "mode" </string>
<string> "mass" </string>
<string> "friction" </string>
<string> "bounce" </string>
<string> "gravity_scale" </string>
<string> "custom_integrator" </string>
<string> "continuous_cd" </string>
<string> "contacts_reported" </string>
<string> "contact_monitor" </string>
<string> "active" </string>
<string> "sleeping" </string>
<string> "can_sleep" </string>
<string> "velocity/linear" </string>
<string> "velocity/angular" </string>
<string> "damp_override/linear" </string>
<string> "damp_override/angular" </string>
<string> "script/script" </string>
<string> "__meta__" </string>
<string> "enabler" </string>
<string> "VisibilityEnabler2D" </string>
<string> "transform/pos" </string>
<string> "transform/scale" </string>
<string> "rect" </string>
<string> "enabler/pause_animations" </string>
<string> "enabler/freeze_bodies" </string>
<string> "enabler/pause_particles" </string>
<string> "enabler/process_parent" </string>
<string> "enabler/fixed_process_parent" </string>
<string> "anim" </string>
<string> "AnimationPlayer" </string>
<string> "playback/process_mode" </string>
<string> "playback/default_blend_time" </string>
<string> "root/root" </string>
<string> "anims/idle" </string>
<string> "anims/explode" </string>
<string> "anims/walk" </string>
<string> "anims/explode" </string>
<string> "playback/active" </string>
<string> "playback/speed" </string>
<string> "blend_times" </string>
<string> "autoplay" </string>
<string> "CollisionShape2D" </string>
<string> "shape" </string>
<string> "trigger" </string>
<string> "CollisionShape2D 2" </string>
<string> "CollisionShape2D 3" </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> "_update_shape_index" </string>
<string> "CollisionShape2D 2" </string>
<string> "CollisionShape2D 3" </string>
<string> "raycast_left" </string>
<string> "RayCast2D" </string>
<string> "enabled" </string>
<string> "cast_to" </string>
<string> "layer_mask" </string>
<string> "raycast_right" </string>
<string> "Particles2D" </string>
<string> "visibility/self_opacity" </string>
<string> "visibility/blend_mode" </string>
<string> "config/amount" </string>
<string> "config/lifetime" </string>
<string> "config/time_scale" </string>
<string> "config/preprocess" </string>
<string> "config/emit_timeout" </string>
<string> "config/emitting" </string>
<string> "config/offset" </string>
<string> "config/half_extents" </string>
<string> "config/local_space" </string>
<string> "config/explosiveness" </string>
<string> "config/texture" </string>
<string> "params/direction" </string>
@ -266,32 +268,14 @@
<string> "params/radial_accel" </string>
<string> "params/tangential_accel" </string>
<string> "params/damping" </string>
<string> "params/initial_angle" </string>
<string> "params/initial_size" </string>
<string> "params/final_size" </string>
<string> "params/hue_variation" </string>
<string> "randomness/direction" </string>
<string> "randomness/spread" </string>
<string> "randomness/linear_velocity" </string>
<string> "params/anim_speed_scale" </string>
<string> "params/anim_initial_pos" </string>
<string> "randomness/spin_velocity" </string>
<string> "randomness/orbit_velocity" </string>
<string> "randomness/gravity_direction" </string>
<string> "randomness/gravity_strength" </string>
<string> "randomness/radial_accel" </string>
<string> "randomness/tangential_accel" </string>
<string> "randomness/damping" </string>
<string> "randomness/initial_size" </string>
<string> "randomness/final_size" </string>
<string> "randomness/hue_variation" </string>
<string> "color_phases/count" </string>
<string> "phase_0/pos" </string>
<string> "phase_0/color" </string>
<string> "phase_1/pos" </string>
<string> "phase_1/color" </string>
<string> "phase_2/pos" </string>
<string> "phase_2/color" </string>
<string> "phase_3/pos" </string>
<string> "phase_3/color" </string>
<string> "emission_points" </string>
<string> "color/color_ramp" </string>
<string> "sound" </string>
<string> "SamplePlayer2D" </string>
<string> "params/volume_db" </string>
@ -303,125 +287,154 @@
<string> "config/samples" </string>
<string> "config/pitch_random" </string>
</string_array>
<string> "version" </string>
<int> 1 </int>
<string> "conn_count" </string>
<int> 0 </int>
<string> "node_count" </string>
<int> 11 </int>
<string> "nodes" </string>
<int_array len="285"> -1, -1, 1, 0, -1, 29, 2, 0, 3, 1, 4, 2, 5, 0, 6, 1, 7, 3, 8, 0, 9, 1, 10, 4, 11, 0, 12, 5, 13, 5, 14, 6, 15, 7, 16, 8, 17, 8, 18, 7, 19, 0, 20, 9, 21, 10, 22, 0, 23, 0, 24, 11, 25, 12, 26, 8, 27, 13, 28, 13, 29, 14, 30, 15, 0, 0, 0, 32, 31, -1, 8, 33, 16, 34, 17, 35, 18, 36, 11, 37, 11, 38, 11, 39, 0, 40, 0, 0, 0, 0, 42, 41, -1, 10, 43, 5, 44, 8, 45, 19, 46, 20, 47, 21, 48, 22, 49, 11, 50, 23, 51, 24, 52, 25, 0, 0, 0, 54, 53, -1, 3, 55, 26, 56, 27, 57, 10, 0, 0, 0, 58, 58, -1, 4, 33, 28, 59, 1, 60, 0, 61, 29, 0, 0, 0, 58, 62, -1, 4, 33, 30, 59, 1, 60, 0, 61, 29, 0, 0, 0, 58, 63, -1, 4, 33, 31, 59, 1, 60, 0, 61, 29, 0, 0, 0, 65, 64, -1, 4, 33, 32, 66, 11, 67, 33, 68, 5, 0, 0, 0, 65, 69, -1, 4, 33, 34, 66, 11, 67, 33, 68, 5, 0, 0, 0, 70, 70, -1, 26, 71, 35, 72, 5, 73, 36, 74, 37, 75, 37, 76, 0, 77, 38, 78, 39, 79, 8, 80, 40, 81, 41, 82, 42, 83, 8, 84, 8, 85, 43, 86, 8, 87, 8, 88, 8, 89, 8, 90, 42, 91, 23, 92, 8, 93, 7, 94, 8, 95, 7, 96, 44, 0, 0, 0, 98, 97, -1, 8, 99, 8, 100, 7, 101, 7, 102, 45, 103, 7, 104, 46, 105, 47, 106, 8, 0 </int_array>
<string> "variants" </string>
<array len="51" shared="false">
<bool> True </bool>
<real> 1 </real>
<vector2> 0, 0 </vector2>
<real> 0 </real>
<vector2> 1, 1 </vector2>
<int> 3 </int>
<array len="48" shared="false">
<bool> False </bool>
<resource resource_type="Shape2D" path="local://1"> </resource>
<matrix32> 1, -0, 0, 1, -1.08072, -2.16144 </matrix32>
<bool> False </bool>
<matrix32> 1, -0, 0, 1, 6.48431, 3.24216 </matrix32>
<matrix32> 1, -0, 0, 1, -12.495, 3.53415 </matrix32>
<int> 1 </int>
<int> 2 </int>
<real> 1 </real>
<real> 0 </real>
<int> 0 </int>
<int> 4 </int>
<resource resource_type="Script" path="res://enemy.*"> </resource>
<bool> True </bool>
<vector2> 0, 0 </vector2>
<real> -1 </real>
<resource external="0"> </resource>
<dictionary shared="false">
<string> "__editor_plugin_screen__" </string>
<string> "2D" </string>
<string> "__editor_plugin_states__" </string>
<dictionary shared="false">
<string> "Script" </string>
<dictionary shared="false">
<string> "current" </string>
<int> 0 </int>
<string> "sources" </string>
<array len="1" shared="false">
<string> "res://enemy.gd" </string>
</array>
</dictionary>
<string> "2D" </string>
<dictionary shared="false">
<string> "pixel_snap" </string>
<bool> False </bool>
<string> "zoom" </string>
<real> 1.108033 </real>
<string> "ofs" </string>
<vector2> -227.625, -197.9 </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> 1.108033 </real>
</dictionary>
<string> "3D" </string>
<dictionary shared="false">
<string> "zfar" </string>
<real> 500 </real>
<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>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "use_environment" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
</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>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "use_environment" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
</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>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "use_environment" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
</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>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "use_environment" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
</dictionary>
</array>
<string> "viewport_mode" </string>
<int> 1 </int>
<string> "default_light" </string>
<bool> True </bool>
<string> "show_grid" </string>
<bool> True </bool>
<string> "show_origin" </string>
<bool> True </bool>
<string> "zfar" </string>
<real> 500 </real>
<string> "znear" </string>
<real> 0.1 </real>
</dictionary>
<string> "Anim" </string>
<dictionary shared="false">
<string> "visible" </string>
<bool> False </bool>
</dictionary>
</dictionary>
<string> "__editor_run_settings__" </string>
<dictionary shared="false">
@ -430,28 +443,24 @@
<string> "run_mode" </string>
<int> 0 </int>
</dictionary>
<string> "__editor_plugin_screen__" </string>
<string> "2D" </string>
</dictionary>
<vector2> 16.2569, 11.0034 </vector2>
<vector2> 23.5056, 10.8629 </vector2>
<rect2> -10, -10, 20, 20 </rect2>
<int> 1 </int>
<node_path> ".." </node_path>
<resource resource_type="Animation" path="local://2"> </resource>
<resource resource_type="Animation" path="local://3"> </resource>
<resource resource_type="Animation" path="local://4"> </resource>
<resource resource_type="Animation" path="local://3"> </resource>
<real> 3 </real>
<array len="0" shared="false">
</array>
<string> "" </string>
<resource external="1"> </resource>
<int> 8 </int>
<vector2> -1.08072, -2.16144 </vector2>
<int> -1 </int>
<vector2> 6.48431, 3.24216 </vector2>
<vector2> -12.495, 3.53415 </vector2>
<resource resource_type="Texture" path="res://enemy.*"> </resource>
<int> 8 </int>
<color> 1, 1, 1, 1 </color>
<rect2> 0, 0, 0, 0 </rect2>
<vector2> -33.2868, -9.34363 </vector2>
<vector2> 0, 45 </vector2>
<vector2> 29.1987, -9.34363 </vector2>
@ -459,22 +468,18 @@
<int> 32 </int>
<real> 0.5 </real>
<real> 0.1 </real>
<resource resource_type="Texture" path="res://bullet.*"> </resource>
<resource external="2"> </resource>
<real> 180 </real>
<real> 90 </real>
<real> 2 </real>
<real> 9.8 </real>
<color> 1, 0.884956, 0.823009, 1 </color>
<color> 0.768627, 0.389381, 0, 0 </color>
<color> 0, 0, 0, 1 </color>
<vector2_array len="0"> </vector2_array>
<resource resource_type="ColorRamp" path="local://6"> </resource>
<real> 2048 </real>
<int> 3 </int>
<resource resource_type="SampleLibrary" path="local://5"> </resource>
</array>
<string> "nodes" </string>
<int_array len="445"> -1, -1, 1, 0, -1, 31, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 8, 13, 6, 14, 9, 15, 8, 16, 6, 17, 10, 18, 8, 19, 11, 20, 1, 21, 3, 22, 3, 23, 8, 24, 8, 25, 12, 26, 8, 27, 0, 28, 0, 29, 2, 30, 3, 31, 13, 32, 14, 0, 0, 0, 34, 33, -1, 10, 2, 0, 3, 1, 4, 1, 5, 0, 6, 15, 7, 3, 8, 16, 35, 17, 36, 0, 37, 0, 0, 0, 0, 39, 38, -1, 10, 40, 18, 41, 3, 42, 19, 43, 20, 44, 21, 45, 22, 46, 0, 47, 23, 48, 24, 49, 25, 0, 0, 0, 50, 50, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 26, 7, 3, 8, 4, 51, 6, 52, 8, 0, 0, 0, 50, 53, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 27, 7, 3, 8, 4, 51, 6, 52, 8, 0, 0, 0, 50, 54, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 28, 7, 3, 8, 4, 51, 6, 52, 8, 0, 0, 0, 56, 55, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 57, 29, 58, 0, 59, 2, 60, 8, 61, 8, 62, 18, 63, 30, 64, 12, 65, 31, 66, 8, 67, 32, 0, 0, 0, 69, 68, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 33, 7, 3, 8, 4, 70, 0, 71, 34, 0, 0, 0, 69, 72, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 35, 7, 3, 8, 4, 70, 0, 71, 34, 0, 0, 0, 73, 73, -1, 55, 2, 0, 3, 1, 4, 36, 5, 0, 74, 18, 6, 2, 7, 3, 8, 4, 75, 37, 76, 38, 77, 1, 78, 3, 79, 38, 80, 8, 81, 2, 82, 2, 83, 0, 84, 39, 85, 40, 86, 3, 87, 41, 88, 42, 89, 43, 90, 3, 91, 3, 92, 44, 93, 3, 94, 3, 95, 3, 96, 43, 97, 23, 98, 3, 99, 3, 100, 3, 101, 3, 102, 1, 103, 3, 104, 3, 105, 3, 106, 3, 107, 3, 108, 3, 109, 3, 110, 3, 111, 3, 112, 11, 113, 3, 114, 45, 115, 1, 116, 46, 117, 1, 118, 47, 119, 1, 120, 47, 121, 48, 0, 0, 0, 123, 122, -1, 15, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 124, 3, 125, 1, 126, 1, 127, 49, 128, 1, 129, 5, 130, 50, 131, 3, 0 </int_array>
<string> "conns" </string>
<int_array len="0"> </int_array>
<string> "version" </string>
<int> 1 </int>
</dictionary>
</main_resource>

View file

@ -4,14 +4,14 @@ name="Platformer"
main_scene="res://stage.xml"
icon="res://icon.png"
name_es="Plataformero"
target_fps="60"
[display]
width=800
height=480
stretch_2d=false
stretch_mode="viewport"
stretch_aspect="keep"
stretch_mode="2d"
stretch_aspect="keep_height"
[image_loader]

View file

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<resource_file type="PackedScene" subresource_count="24" version="1.0" version_name="Godot Engine v1.0.rc2.custom_build">
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
<resource_file type="PackedScene" subresource_count="25" version="1.1" version_name="Godot Engine v1.1.stable.custom_build">
<ext_resource path="res://player.gd" type="Script"></ext_resource>
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
<ext_resource path="res://bullet.png" type="Texture"></ext_resource>
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
<ext_resource path="res://sound_coin.wav" type="Sample"></ext_resource>
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
<ext_resource path="res://sound_shoot.wav" type="Sample"></ext_resource>
<ext_resource path="res://osb_left.png" type="Texture"></ext_resource>
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
<ext_resource path="res://player.gd" type="Script"></ext_resource>
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
<resource type="RayShape2D" path="local://1">
<real name="custom_solver_bias"> 0.5 </real>
<real name="length"> 20 </real>
@ -19,6 +19,11 @@
<real name="custom_solver_bias"> 0 </real>
<vector2_array name="points" len="3"> -19.902, -24.8691, 19.3625, -24.6056, -0.138023, 16.5036 </vector2_array>
</resource>
<resource type="ColorRamp" path="local://14">
<real_array name="offsets" len="2"> 0, 1 </real_array>
<color_array name="colors" len="2"> 1, 1, 1, 1, 0, 0, 0, 0.0442478 </color_array>
</resource>
<resource type="Animation" path="local://3">
<string name="resource/name"> "idle" </string>
@ -31,6 +36,8 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="8"> 0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25 </real_array>
<string> "transitions" </string>
<real_array len="8"> 1, 1, 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
@ -44,8 +51,6 @@
<int> 19 </int>
<int> 16 </int>
</array>
<string> "times" </string>
<real_array len="8"> 0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25 </real_array>
</dictionary>
</resource>
@ -60,6 +65,8 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="3"> 0, 0.25, 0.5 </real_array>
<string> "transitions" </string>
<real_array len="3"> 1, 1, 1 </real_array>
<string> "values" </string>
@ -68,8 +75,6 @@
<int> 24 </int>
<int> 23 </int>
</array>
<string> "times" </string>
<real_array len="3"> 0, 0.25, 0.5 </real_array>
</dictionary>
</resource>
@ -84,14 +89,14 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 25 </int>
</array>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
</dictionary>
</resource>
@ -105,6 +110,8 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
<string> "transitions" </string>
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
@ -116,56 +123,10 @@
<int> 4 </int>
<int> 0 </int>
</array>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
</dictionary>
</resource>
<resource type="Animation" path="local://7">
<string name="resource/name"> "crouch" </string>
<real name="length"> 0.01 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
<string name="tracks/0/type"> "value" </string>
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
<int name="tracks/0/interp"> 1 </int>
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 22 </int>
</array>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
</dictionary>
</resource>
<resource type="Animation" path="local://8">
<string name="resource/name"> "falling" </string>
<real name="length"> 0.01 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
<string name="tracks/0/type"> "value" </string>
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
<int name="tracks/0/interp"> 1 </int>
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 21 </int>
</array>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
</dictionary>
</resource>
<resource type="Animation" path="local://9">
<resource type="Animation" path="local://11">
<real name="length"> 1.25 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
@ -175,19 +136,19 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
<string> "transitions" </string>
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
<array len="6" shared="false">
<int> 10 </int>
<int> 11 </int>
<int> 12 </int>
<int> 13 </int>
<int> 14 </int>
<int> 5 </int>
<int> 6 </int>
<int> 7 </int>
<int> 8 </int>
<int> 9 </int>
<int> 5 </int>
</array>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
</dictionary>
</resource>
@ -202,18 +163,62 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 26 </int>
</array>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
</dictionary>
</resource>
<resource type="Animation" path="local://11">
<resource type="Animation" path="local://7">
<string name="resource/name"> "crouch" </string>
<real name="length"> 0.01 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
<string name="tracks/0/type"> "value" </string>
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
<int name="tracks/0/interp"> 1 </int>
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 22 </int>
</array>
</dictionary>
</resource>
<resource type="Animation" path="local://8">
<string name="resource/name"> "falling" </string>
<real name="length"> 0.01 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
<string name="tracks/0/type"> "value" </string>
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
<int name="tracks/0/interp"> 1 </int>
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 21 </int>
</array>
</dictionary>
</resource>
<resource type="Animation" path="local://9">
<real name="length"> 1.25 </real>
<bool name="loop"> True </bool>
<real name="step"> 0.25 </real>
@ -223,19 +228,19 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
<string> "transitions" </string>
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
<string> "values" </string>
<array len="6" shared="false">
<int> 5 </int>
<int> 6 </int>
<int> 7 </int>
<int> 8 </int>
<int> 9 </int>
<int> 10 </int>
<int> 11 </int>
<int> 12 </int>
<int> 13 </int>
<int> 14 </int>
<int> 5 </int>
</array>
<string> "times" </string>
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
</dictionary>
</resource>
@ -249,14 +254,14 @@
<dictionary name="tracks/0/keys" shared="false">
<string> "cont" </string>
<bool> False </bool>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
<string> "transitions" </string>
<real_array len="1"> 1 </real_array>
<string> "values" </string>
<array len="1" shared="false">
<int> 26 </int>
</array>
<string> "times" </string>
<real_array len="1"> 0 </real_array>
</dictionary>
</resource>
@ -289,30 +294,28 @@
</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="180">
<string_array len="142">
<string> "player" </string>
<string> "RigidBody2D" </string>
<string> "_import_path" </string>
<string> "visibility/visible" </string>
<string> "visibility/opacity" </string>
<string> "visibility/self_opacity" </string>
<string> "visibility/behind_parent" </string>
<string> "transform/pos" </string>
<string> "transform/rot" </string>
<string> "transform/scale" </string>
<string> "shape_count" </string>
<string> "input/pickable" </string>
<string> "shapes/0/shape" </string>
<string> "shapes/0/transform" </string>
<string> "shapes/0/trigger" </string>
<string> "shapes/1/shape" </string>
<string> "shapes/1/transform" </string>
<string> "shapes/1/trigger" </string>
<string> "layers" </string>
<string> "collision/layers" </string>
<string> "collision/mask" </string>
<string> "mode" </string>
<string> "mass" </string>
<string> "friction" </string>
<string> "bounce" </string>
<string> "gravity_scale" </string>
<string> "custom_integrator" </string>
<string> "continuous_cd" </string>
<string> "contacts_reported" </string>
@ -321,39 +324,28 @@
<string> "can_sleep" </string>
<string> "velocity/linear" </string>
<string> "velocity/angular" </string>
<string> "damp_override/linear" </string>
<string> "damp_override/angular" </string>
<string> "script/script" </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> "smoke" </string>
<string> "Particles2D" </string>
<string> "visibility/self_opacity" </string>
<string> "visibility/blend_mode" </string>
<string> "transform/pos" </string>
<string> "transform/rot" </string>
<string> "config/amount" </string>
<string> "config/lifetime" </string>
<string> "config/time_scale" </string>
<string> "config/preprocess" </string>
<string> "config/emit_timeout" </string>
<string> "config/emitting" </string>
<string> "config/offset" </string>
<string> "config/half_extents" </string>
<string> "config/local_space" </string>
<string> "config/explosiveness" </string>
<string> "config/flip_h" </string>
<string> "config/flip_v" </string>
<string> "config/texture" </string>
<string> "config/h_frames" </string>
<string> "config/v_frames" </string>
<string> "params/direction" </string>
<string> "params/spread" </string>
<string> "params/linear_velocity" </string>
@ -370,32 +362,8 @@
<string> "params/hue_variation" </string>
<string> "params/anim_speed_scale" </string>
<string> "params/anim_initial_pos" </string>
<string> "randomness/direction" </string>
<string> "randomness/spread" </string>
<string> "randomness/linear_velocity" </string>
<string> "randomness/spin_velocity" </string>
<string> "randomness/orbit_velocity" </string>
<string> "randomness/gravity_direction" </string>
<string> "randomness/gravity_strength" </string>
<string> "randomness/radial_accel" </string>
<string> "randomness/tangential_accel" </string>
<string> "randomness/damping" </string>
<string> "randomness/initial_angle" </string>
<string> "randomness/initial_size" </string>
<string> "randomness/final_size" </string>
<string> "randomness/hue_variation" </string>
<string> "randomness/anim_speed_scale" </string>
<string> "randomness/anim_initial_pos" </string>
<string> "color_phases/count" </string>
<string> "phase_0/pos" </string>
<string> "phase_0/color" </string>
<string> "phase_1/pos" </string>
<string> "phase_1/color" </string>
<string> "phase_2/pos" </string>
<string> "phase_2/color" </string>
<string> "phase_3/pos" </string>
<string> "phase_3/color" </string>
<string> "emission_points" </string>
<string> "color/color_ramp" </string>
<string> "anim" </string>
<string> "AnimationPlayer" </string>
<string> "playback/process_mode" </string>
@ -405,11 +373,11 @@
<string> "anims/jumping" </string>
<string> "anims/idle_weapon" </string>
<string> "anims/run" </string>
<string> "anims/run_weapon" </string>
<string> "anims/falling_weapon" </string>
<string> "anims/crouch" </string>
<string> "anims/falling" </string>
<string> "anims/standing_weapon_ready" </string>
<string> "anims/falling_weapon" </string>
<string> "anims/run_weapon" </string>
<string> "anims/jumping_weapon" </string>
<string> "playback/active" </string>
<string> "playback/speed" </string>
@ -417,6 +385,7 @@
<string> "autoplay" </string>
<string> "camera" </string>
<string> "Camera2D" </string>
<string> "anchor_mode" </string>
<string> "rotating" </string>
<string> "current" </string>
<string> "smoothing" </string>
@ -434,6 +403,7 @@
<string> "bullet_shoot" </string>
<string> "Position2D" </string>
<string> "CollisionShape2D" </string>
<string> "transform/scale" </string>
<string> "shape" </string>
<string> "trigger" </string>
<string> "sound" </string>
@ -458,6 +428,7 @@
<string> "ui" </string>
<string> "CanvasLayer" </string>
<string> "layer" </string>
<string> "offset" </string>
<string> "rotation" </string>
<string> "scale" </string>
<string> "left" </string>
@ -472,147 +443,149 @@
<string> "jump" </string>
<string> "fire" </string>
</string_array>
<string> "version" </string>
<int> 1 </int>
<string> "conn_count" </string>
<int> 0 </int>
<string> "node_count" </string>
<int> 14 </int>
<string> "nodes" </string>
<int_array len="394"> -1, -1, 1, 0, -1, 26, 2, 0, 3, 1, 4, 2, 5, 0, 6, 3, 7, 4, 8, 0, 9, 5, 10, 5, 11, 6, 12, 7, 13, 8, 14, 8, 15, 9, 16, 10, 17, 11, 18, 12, 19, 0, 20, 0, 21, 10, 22, 13, 23, 8, 24, 14, 25, 14, 26, 15, 27, 16, 0, 0, 0, 29, 28, -1, 3, 30, 17, 31, 6, 32, 18, 0, 1, 0, 34, 33, -1, 29, 35, 19, 36, 5, 37, 20, 38, 21, 39, 22, 40, 23, 41, 23, 42, 0, 43, 0, 44, 24, 45, 25, 46, 8, 47, 26, 48, 27, 49, 9, 50, 8, 51, 8, 52, 28, 53, 8, 54, 8, 55, 8, 56, 8, 57, 29, 58, 29, 59, 8, 60, 9, 61, 8, 62, 29, 63, 30, 0, 0, 0, 65, 64, -1, 17, 66, 5, 67, 8, 68, 31, 69, 32, 70, 33, 71, 34, 72, 35, 73, 36, 74, 37, 75, 38, 76, 39, 77, 40, 78, 41, 79, 10, 80, 29, 81, 42, 82, 43, 0, 0, 0, 84, 83, -1, 15, 85, 5, 86, 0, 87, 10, 88, 8, 89, 44, 90, 11, 91, 11, 92, 45, 93, 45, 94, 10, 95, 10, 96, 46, 97, 46, 98, 46, 99, 46, 0, 0, 0, 101, 100, -1, 1, 37, 47, 0, 0, 0, 102, 102, -1, 4, 37, 48, 103, 49, 104, 1, 105, 0, 0, 0, 0, 107, 106, -1, 14, 108, 12, 109, 50, 110, 8, 111, 9, 112, 8, 113, 8, 114, 8, 115, 51, 116, 51, 117, 51, 118, 51, 119, 6, 120, 8, 121, 8, 0, 0, 0, 122, 122, -1, 3, 123, 11, 124, 52, 105, 0, 0, 0, 0, 126, 125, -1, 4, 127, 11, 128, 13, 129, 8, 130, 44, 0, 9, 0, 132, 131, -1, 8, 37, 53, 103, 54, 133, 55, 134, 56, 135, 56, 136, 10, 137, 57, 138, 5, 0, 9, 0, 132, 139, -1, 8, 37, 58, 103, 54, 133, 59, 134, 56, 135, 56, 136, 10, 137, 60, 138, 5, 0, 9, 0, 132, 140, -1, 8, 37, 61, 103, 54, 133, 62, 134, 56, 135, 56, 136, 0, 137, 63, 138, 5, 0, 9, 0, 132, 141, -1, 8, 37, 64, 103, 54, 133, 65, 134, 56, 135, 56, 136, 0, 137, 66, 138, 5, 0 </int_array>
<string> "variants" </string>
<array len="72" shared="false">
<node_path> "" </node_path>
<bool> True </bool>
<real> 1 </real>
<array len="67" shared="false">
<bool> False </bool>
<vector2> 0, 0 </vector2>
<real> 0 </real>
<vector2> 1, 1 </vector2>
<int> 2 </int>
<resource resource_type="Shape2D" path="local://1"> </resource>
<matrix32> 1, -0, 0, 1.76469, 0.291992, -12.1587 </matrix32>
<resource resource_type="Shape2D" path="local://2"> </resource>
<matrix32> 1, -0, 0, 1, 0, 0 </matrix32>
<int> 1 </int>
<int> 2 </int>
<real> 3 </real>
<real> 0 </real>
<real> 1 </real>
<bool> True </bool>
<int> 0 </int>
<int> 3 </int>
<vector2> 0, 0 </vector2>
<real> -1 </real>
<resource resource_type="Script" path="res://player.gd"> </resource>
<dictionary shared="false">
<string> "__editor_plugin_screen__" </string>
<string> "2D" </string>
<string> "__editor_plugin_states__" </string>
<dictionary shared="false">
<string> "Script" </string>
<dictionary shared="false">
<string> "current" </string>
<int> 0 </int>
<string> "sources" </string>
<array len="1" shared="false">
<string> "res://player.gd" </string>
</array>
</dictionary>
<string> "2D" </string>
<dictionary shared="false">
<string> "pixel_snap" </string>
<bool> False </bool>
<string> "zoom" </string>
<real> 2.272073 </real>
<string> "use_snap" </string>
<bool> False </bool>
<string> "ofs" </string>
<vector2> -181.946, -86.2812 </vector2>
<string> "snap" </string>
<int> 10 </int>
<vector2> -110.795, -101.2 </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> "zfar" </string>
<real> 500 </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> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </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> "pos" </string>
<vector3> 0, 0, 0 </vector3>
</dictionary>
<dictionary shared="false">
<string> "distance" </string>
<real> 4 </real>
<string> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </real>
<string> "listener" </string>
<bool> False </bool>
<string> "use_environment" </string>
<bool> False </bool>
<string> "use_orthogonal" </string>
<bool> False </bool>
<string> "pos" </string>
<vector3> 0, 0, 0 </vector3>
</dictionary>
<dictionary shared="false">
<string> "distance" </string>
<real> 4 </real>
<string> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </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> "pos" </string>
<vector3> 0, 0, 0 </vector3>
<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> "x_rot" </string>
<real> 0 </real>
<string> "y_rot" </string>
<real> 0 </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> "viewport_mode" </string>
<int> 1 </int>
<string> "default_light" </string>
<bool> True </bool>
<string> "ambient_light_color" </string>
<color> 0.15, 0.15, 0.15, 1 </color>
<string> "show_grid" </string>
<bool> True </bool>
<string> "show_origin" </string>
<bool> True </bool>
<string> "zfar" </string>
<real> 500 </real>
<string> "znear" </string>
<real> 0.1 </real>
<string> "default_srgb" </string>
<bool> False </bool>
<string> "deflight_rot_x" </string>
<real> 0.942478 </real>
</dictionary>
</dictionary>
<string> "__editor_run_settings__" </string>
@ -622,13 +595,9 @@
<string> "run_mode" </string>
<int> 0 </int>
</dictionary>
<string> "__editor_plugin_screen__" </string>
<string> "Script" </string>
</dictionary>
<resource resource_type="Texture" path="res://robot_demo.png"> </resource>
<int> 16 </int>
<color> 1, 1, 1, 1 </color>
<rect2> 0, 0, 0, 0 </rect2>
<real> 0.363636 </real>
<vector2> 20.7312, 3.21187 </vector2>
<real> 83.450417 </real>
@ -640,24 +609,22 @@
<real> 20 </real>
<real> 9.8 </real>
<real> 2 </real>
<color> 0, 0, 0, 0.0442478 </color>
<color> 1, 0, 0, 1 </color>
<color> 0, 0, 0, 1 </color>
<vector2_array len="0"> </vector2_array>
<resource resource_type="ColorRamp" path="local://14"> </resource>
<node_path> ".." </node_path>
<resource resource_type="Animation" path="local://3"> </resource>
<resource resource_type="Animation" path="local://4"> </resource>
<resource resource_type="Animation" path="local://5"> </resource>
<resource resource_type="Animation" path="local://6"> </resource>
<resource resource_type="Animation" path="local://11"> </resource>
<resource resource_type="Animation" path="local://10"> </resource>
<resource resource_type="Animation" path="local://7"> </resource>
<resource resource_type="Animation" path="local://8"> </resource>
<resource resource_type="Animation" path="local://9"> </resource>
<resource resource_type="Animation" path="local://10"> </resource>
<resource resource_type="Animation" path="local://11"> </resource>
<resource resource_type="Animation" path="local://12"> </resource>
<array len="0" shared="false">
</array>
<string> "" </string>
<vector2> 1, 1 </vector2>
<int> 10000000 </int>
<real> 0.2 </real>
<vector2> 31.2428, 4.08784 </vector2>
@ -680,10 +647,8 @@
<resource resource_type="Texture" path="res://osb_fire.png"> </resource>
<string> "shoot" </string>
</array>
<string> "nodes" </string>
<int_array len="618"> -1, -1, 1, 0, -1, 30, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 8, 12, 9, 13, 3, 14, 10, 15, 11, 16, 3, 17, 12, 18, 7, 19, 13, 20, 5, 21, 5, 22, 1, 23, 14, 24, 15, 25, 3, 26, 3, 27, 1, 28, 4, 29, 5, 30, 16, 31, 17, 0, 0, 0, 33, 32, -1, 19, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 34, 18, 35, 1, 36, 4, 37, 3, 38, 3, 39, 7, 40, 19, 41, 14, 42, 20, 43, 3, 44, 21, 0, 1, 0, 46, 45, -1, 66, 2, 0, 3, 1, 4, 2, 5, 22, 6, 3, 47, 12, 7, 23, 8, 24, 9, 6, 48, 25, 49, 26, 50, 2, 51, 5, 52, 26, 53, 3, 54, 4, 55, 4, 56, 3, 57, 27, 58, 3, 59, 3, 60, 28, 61, 12, 62, 12, 63, 5, 64, 29, 65, 30, 66, 2, 67, 5, 68, 5, 69, 31, 70, 5, 71, 5, 72, 5, 73, 5, 74, 32, 75, 32, 76, 5, 77, 2, 78, 5, 79, 5, 80, 5, 81, 5, 82, 32, 83, 5, 84, 5, 85, 5, 86, 5, 87, 5, 88, 5, 89, 5, 90, 5, 91, 5, 92, 5, 93, 5, 94, 5, 95, 7, 96, 5, 97, 20, 98, 2, 99, 33, 100, 2, 101, 34, 102, 2, 103, 35, 104, 36, 0, 0, 0, 106, 105, -1, 18, 2, 0, 107, 12, 108, 5, 109, 37, 110, 38, 111, 39, 112, 40, 113, 41, 114, 42, 115, 43, 116, 44, 117, 45, 118, 46, 119, 47, 120, 1, 121, 32, 122, 48, 123, 49, 0, 0, 0, 125, 124, -1, 23, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 35, 1, 126, 3, 127, 1, 128, 5, 129, 6, 130, 14, 131, 14, 132, 50, 133, 50, 134, 1, 135, 1, 136, 51, 137, 51, 138, 51, 139, 51, 0, 0, 0, 141, 140, -1, 8, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 52, 8, 5, 9, 6, 0, 0, 0, 142, 142, -1, 10, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 53, 8, 5, 9, 54, 143, 8, 144, 3, 0, 0, 0, 146, 145, -1, 15, 2, 0, 147, 15, 148, 55, 149, 5, 150, 2, 151, 5, 152, 5, 153, 5, 154, 56, 155, 56, 156, 56, 157, 56, 158, 7, 159, 5, 160, 5, 0, 0, 0, 161, 161, -1, 10, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 162, 14, 163, 57, 0, 0, 0, 165, 164, -1, 5, 2, 0, 166, 14, 36, 4, 167, 5, 168, 6, 0, 9, 0, 170, 169, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 58, 8, 5, 9, 59, 171, 60, 172, 61, 173, 61, 174, 1, 175, 62, 176, 12, 0, 9, 0, 170, 177, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 63, 8, 5, 9, 59, 171, 64, 172, 61, 173, 61, 174, 1, 175, 65, 176, 12, 0, 9, 0, 170, 178, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 66, 8, 5, 9, 59, 171, 67, 172, 61, 173, 61, 174, 3, 175, 68, 176, 12, 0, 9, 0, 170, 179, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 69, 8, 5, 9, 59, 171, 70, 172, 61, 173, 61, 174, 3, 175, 71, 176, 12, 0 </int_array>
<string> "conns" </string>
<int_array len="0"> </int_array>
<string> "version" </string>
<int> 1 </int>
</dictionary>
</main_resource>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
filter=false

View file

@ -91,4 +91,5 @@ func _ready():
# Initalization here
pass
func _die():
queue_free()

Binary file not shown.

View file

@ -69,9 +69,9 @@ func _integrate_forces( state ):
var lv = state.get_linear_velocity() # linear velocity
var g = state.get_total_gravity()
var delta = state.get_step()
var d = 1.0 - delta*state.get_total_density()
if (d<0):
d=0
# var d = 1.0 - delta*state.get_total_density()
# if (d<0):
# d=0
lv += g * delta #apply gravity
var anim = ANIM_FLOOR

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -32,15 +32,17 @@ SConscript("rtaudio/SCsub");
SConscript("nedmalloc/SCsub");
SConscript("nrex/SCsub");
SConscript("chibi/SCsub");
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"):
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes" or env["opus"]=="yes"):
SConscript("ogg/SCsub");
if (env["vorbis"]=="yes"):
SConscript("vorbis/SCsub");
if (env["opus"]=="yes"):
SConscript('opus/SCsub');
if (env["tools"]=="yes"):
SConscript("convex_decomp/SCsub");
if env["theora"]=="yes":
SConscript("theoraplayer/SCsub")
#if env["theora"]=="yes":
# SConscript("theoraplayer/SCsub")
if (env["theora"]=="yes"):
SConscript("theora/SCsub");
if (env['speex']=='yes'):

View file

@ -779,8 +779,10 @@ EventStreamChibi::EventStreamChibi() {
RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_original_path) {
RES ResourceFormatLoaderChibi::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error)
*r_error=ERR_FILE_CANT_OPEN;
String el = p_path.extension().to_lower();
CPFileAccessWrapperImpl f;
@ -791,6 +793,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
CPLoader_IT loader(&f);
CPLoader::Error err = loader.load_song(p_path.utf8().get_data(),&esc->song,false);
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
if (r_error)
*r_error=OK;
return esc;
@ -800,6 +804,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
CPLoader_XM loader(&f);
CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
if (r_error)
*r_error=OK;
return esc;
} else if (el=="s3m") {
@ -808,6 +814,9 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
CPLoader_S3M loader(&f);
CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
if (r_error)
*r_error=OK;
return esc;
} else if (el=="mod") {
@ -816,6 +825,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
CPLoader_MOD loader(&f);
CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
if (r_error)
*r_error=OK;
return esc;
}

View file

@ -301,7 +301,7 @@ public:
class ResourceFormatLoaderChibi : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path,const String& p_original_path="");
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;

View file

@ -20,7 +20,8 @@
#define B2GLUE_H
#include "math_2d.h"
#include <limits>
#include <limits.h>
namespace b2ConvexDecomp {
typedef real_t float32;

View file

@ -21,8 +21,8 @@
#include "b2Triangle.h"
#include "b2Polygon.h"
#include <cmath>
#include <climits>
#include <math.h>
#include <limits.h>
#include <assert.h>
#define b2Assert assert

View file

@ -22,7 +22,7 @@
#include "b2Triangle.h"
#include "stdio.h"
#include <string.h>
#include <limits>
#include <limits.h>
namespace b2ConvexDecomp {
static bool B2_POLYGON_REPORT_ERRORS = false;

View file

@ -64,8 +64,10 @@ static const DDSFormatInfo dds_format_info[DDS_MAX]={
};
RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path) {
RES ResourceFormatDDS::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
Error err;
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@ -73,6 +75,8 @@ RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path)
return RES();
FileAccessRef fref(f);
if (r_error)
*r_error=ERR_FILE_CORRUPT;
ERR_EXPLAIN("Unable to open DDS texture file: "+p_path);
ERR_FAIL_COND_V(err!=OK,RES());
@ -427,6 +431,10 @@ RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path)
Ref<ImageTexture> texture = memnew( ImageTexture );
texture->create_from_image(img);
if (r_error)
*r_error=OK;
return texture;
}

View file

@ -7,7 +7,7 @@
class ResourceFormatDDS : public ResourceFormatLoader{
public:
virtual RES load(const String &p_path,const String& p_original_path="");
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;

View file

@ -1,3 +1,7 @@
#ifdef __HAIKU__
#undef GLEW_ENABLED
#endif
#ifdef GLEW_ENABLED
/*
** The OpenGL Extension Wrangler Library

View file

@ -1408,6 +1408,40 @@ GLuint RasterizerGLES2::_texture_get_name(RID p_tex) {
return texture->tex_id;
};
void RasterizerGLES2::texture_set_path(RID p_texture,const String& p_path) {
Texture * texture = texture_owner.get(p_texture);
ERR_FAIL_COND(!texture);
texture->path=p_path;
}
String RasterizerGLES2::texture_get_path(RID p_texture) const{
Texture * texture = texture_owner.get(p_texture);
ERR_FAIL_COND_V(!texture,String());
return texture->path;
}
void RasterizerGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info){
List<RID> textures;
texture_owner.get_owned_list(&textures);
for (List<RID>::Element *E=textures.front();E;E=E->next()) {
Texture *t = texture_owner.get(E->get());
if (!t)
continue;
VS::TextureInfo tinfo;
tinfo.path=t->path;
tinfo.format=t->format;
tinfo.size.x=t->alloc_width;
tinfo.size.y=t->alloc_height;
tinfo.bytes=t->total_data_size;
r_info->push_back(tinfo);
}
}
/* SHADER API */
@ -4145,7 +4179,7 @@ void RasterizerGLES2::begin_frame() {
//fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
#ifdef TOOLS_ENABLED
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("display/use_2d_pixel_snap",false));
shadow_filter=ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter")));
#endif
@ -4160,7 +4194,6 @@ void RasterizerGLES2::begin_frame() {
time_delta=time-last_time;
last_time=time;
frame++;
clear_viewport(Color(1,0,0.5));
_rinfo.vertex_count=0;
_rinfo.object_count=0;
@ -5970,6 +6003,10 @@ void RasterizerGLES2::_render(const Geometry *p_geometry,const Material *p_mater
if (element_count==0)
return;
if (mm->visible>=0) {
element_count=MIN(element_count,mm->visible);
}
const MultiMesh::Element *elements=&mm->elements[0];
_rinfo.vertex_count+=s->array_len*element_count;
@ -9161,7 +9198,11 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *mater
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
if (framebuffer.scale==1 && !canvas_texscreen_used) {
#ifdef GLEW_ENABLED
if (current_rt) {
glReadBuffer(GL_COLOR_ATTACHMENT0);
} else {
glReadBuffer(GL_BACK);
}
#endif
glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
// if (current_clip) {
@ -9341,7 +9382,11 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
#ifdef GLEW_ENABLED
if (current_rt) {
glReadBuffer(GL_COLOR_ATTACHMENT0);
} else {
glReadBuffer(GL_BACK);
}
#endif
glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,w,h);
// if (current_clip) {
@ -10804,7 +10849,7 @@ void RasterizerGLES2::init() {
copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR,!use_fp16_fb);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS,read_depth_supported);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("display/use_2d_pixel_snap",false));
npo2_textures_available=true;
//fragment_lighting=false;
@ -11188,6 +11233,12 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo
tc0_idx=0;
};
void RasterizerGLES2::restore_framebuffer() {
glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
}
RasterizerGLES2::~RasterizerGLES2() {
memdelete_arr(skinned_buffer);

View file

@ -115,6 +115,7 @@ class RasterizerGLES2 : public Rasterizer {
struct Texture {
String path;
uint32_t flags;
int width,height;
int alloc_width, alloc_height;
@ -1325,6 +1326,10 @@ public:
virtual void texture_set_size_override(RID p_texture,int p_width, int p_height);
virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
virtual void texture_set_path(RID p_texture,const String& p_path);
virtual String texture_get_path(RID p_texture) const;
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
GLuint _texture_get_name(RID p_tex);
/* SHADER API */
@ -1696,6 +1701,8 @@ public:
virtual bool has_feature(VS::Features p_feature) const;
virtual void restore_framebuffer();
static RasterizerGLES2* get_singleton();
RasterizerGLES2(bool p_compress_arrays=false,bool p_keep_ram_copy=true,bool p_default_fragment_lighting=true,bool p_use_reload_hooks=false);

View file

@ -132,18 +132,18 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
SL::BlockNode *bnode=(SL::BlockNode*)p_node;
//variables
code+="{"ENDL;
code+="{" ENDL;
for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) {
code+=_mktab(p_level)+_typestr(E->value())+" "+replace_string(E->key())+";"ENDL;
code+=_mktab(p_level)+_typestr(E->value())+" "+replace_string(E->key())+";" ENDL;
}
for(int i=0;i<bnode->statements.size();i++) {
code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";"ENDL;
code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";" ENDL;
}
code+="}"ENDL;
code+="}" ENDL;
} break;
case SL::Node::TYPE_VARIABLE: {
@ -489,15 +489,15 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
if (cfnode->flow_op==SL::FLOW_OP_IF) {
code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {"ENDL;
code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {" ENDL;
code+=dump_node_code(cfnode->statements[1],p_level+1);
if (cfnode->statements.size()==3) {
code+="} else {"ENDL;
code+="} else {" ENDL;
code+=dump_node_code(cfnode->statements[2],p_level+1);
}
code+="}"ENDL;
code+="}" ENDL;
} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {
@ -560,7 +560,7 @@ Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) {
ubase=uniforms->size();
for(Map<StringName,SL::Uniform>::Element *E=p_program->uniforms.front();E;E=E->next()) {
String uline="uniform "+_typestr(E->get().type)+" _"+E->key().operator String()+";"ENDL;
String uline="uniform "+_typestr(E->get().type)+" _"+E->key().operator String()+";" ENDL;
global_code+=uline;
if (uniforms) {
@ -593,10 +593,10 @@ Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) {
header+=_typestr(fnode->arguments[i].type)+" "+replace_string(fnode->arguments[i].name);
}
header+=") {"ENDL;
header+=") {" ENDL;
String fcode=header;
fcode+=dump_node_code(fnode->body,1);
fcode+="}"ENDL;
fcode+="}" ENDL;
global_code+=fcode;
}
@ -605,7 +605,7 @@ Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) {
StringName varname=E->key();
String newvarname=replace_string(varname);
global_code+="uniform "+_typestr(E->get())+" "+newvarname+";"ENDL;
global_code+="uniform "+_typestr(E->get())+" "+newvarname+";" ENDL;
}*/
code=dump_node_code(p_program,0);

View file

@ -1,7 +1,7 @@
#include "audio_stream_mpc.h"
Error AudioStreamMPC::_open_file() {
Error AudioStreamPlaybackMPC::_open_file() {
if (f) {
memdelete(f);
@ -41,7 +41,7 @@ Error AudioStreamMPC::_open_file() {
return OK;
}
void AudioStreamMPC::_close_file() {
void AudioStreamPlaybackMPC::_close_file() {
if (f) {
memdelete(f);
@ -52,7 +52,7 @@ void AudioStreamMPC::_close_file() {
data_ofs=0;
}
int AudioStreamMPC::_read_file(void *p_dst,int p_bytes) {
int AudioStreamPlaybackMPC::_read_file(void *p_dst,int p_bytes) {
if (f)
return f->get_buffer((uint8_t*)p_dst,p_bytes);
@ -68,7 +68,7 @@ int AudioStreamMPC::_read_file(void *p_dst,int p_bytes) {
return p_bytes;
}
bool AudioStreamMPC::_seek_file(int p_pos){
bool AudioStreamPlaybackMPC::_seek_file(int p_pos){
if (p_pos<0 || p_pos>streamlen)
return false;
@ -83,7 +83,7 @@ bool AudioStreamMPC::_seek_file(int p_pos){
return true;
}
int AudioStreamMPC::_tell_file() const{
int AudioStreamPlaybackMPC::_tell_file() const{
if (f)
return f->get_pos();
@ -93,13 +93,13 @@ int AudioStreamMPC::_tell_file() const{
}
int AudioStreamMPC::_sizeof_file() const{
int AudioStreamPlaybackMPC::_sizeof_file() const{
//print_line("sizeof file, get: "+itos(streamlen));
return streamlen;
}
bool AudioStreamMPC::_canseek_file() const{
bool AudioStreamPlaybackMPC::_canseek_file() const{
//print_line("canseek file, get true");
return true;
@ -107,51 +107,46 @@ bool AudioStreamMPC::_canseek_file() const{
/////////////////////
mpc_int32_t AudioStreamMPC::_mpc_read(mpc_reader *p_reader,void *p_dst, mpc_int32_t p_bytes) {
mpc_int32_t AudioStreamPlaybackMPC::_mpc_read(mpc_reader *p_reader,void *p_dst, mpc_int32_t p_bytes) {
AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data;
return smpc->_read_file(p_dst,p_bytes);
}
mpc_bool_t AudioStreamMPC::_mpc_seek(mpc_reader *p_reader,mpc_int32_t p_offset) {
mpc_bool_t AudioStreamPlaybackMPC::_mpc_seek(mpc_reader *p_reader,mpc_int32_t p_offset) {
AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data;
return smpc->_seek_file(p_offset);
}
mpc_int32_t AudioStreamMPC::_mpc_tell(mpc_reader *p_reader) {
mpc_int32_t AudioStreamPlaybackMPC::_mpc_tell(mpc_reader *p_reader) {
AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data;
return smpc->_tell_file();
}
mpc_int32_t AudioStreamMPC::_mpc_get_size(mpc_reader *p_reader) {
mpc_int32_t AudioStreamPlaybackMPC::_mpc_get_size(mpc_reader *p_reader) {
AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data;
return smpc->_sizeof_file();
}
mpc_bool_t AudioStreamMPC::_mpc_canseek(mpc_reader *p_reader) {
mpc_bool_t AudioStreamPlaybackMPC::_mpc_canseek(mpc_reader *p_reader) {
AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
AudioStreamPlaybackMPC *smpc=(AudioStreamPlaybackMPC *)p_reader->data;
return smpc->_canseek_file();
}
bool AudioStreamMPC::_can_mix() const {
return /*active &&*/ !paused;
}
void AudioStreamMPC::update() {
int AudioStreamPlaybackMPC::mix(int16_t* p_bufer,int p_frames) {
if (!active || paused)
return;
return 0;
int todo=get_todo();
int todo=p_frames;
while(todo>MPC_DECODER_BUFFER_LENGTH/si.channels) {
@ -162,7 +157,7 @@ void AudioStreamMPC::update() {
mpc_status err = mpc_demux_decode(demux, &frame);
if (frame.bits!=-1) {
int16_t *dst_buff = get_write_buffer();
int16_t *dst_buff = p_bufer;
#ifdef MPC_FIXED_POINT
@ -185,21 +180,21 @@ void AudioStreamMPC::update() {
#endif
int frames = frame.samples;
write(frames);
p_bufer+=si.channels*frames;
todo-=frames;
} else {
if (err != MPC_STATUS_OK) {
stop();
ERR_EXPLAIN("Error decoding MPC");
ERR_FAIL();
ERR_PRINT("Error decoding MPC");
break;
} else {
//finished
if (!loop) {
stop();
return;
break;
} else {
@ -213,9 +208,11 @@ void AudioStreamMPC::update() {
}
}
}
return p_frames-todo;
}
Error AudioStreamMPC::_reload() {
Error AudioStreamPlaybackMPC::_reload() {
ERR_FAIL_COND_V(demux!=NULL, ERR_FILE_ALREADY_IN_USE);
@ -224,31 +221,40 @@ Error AudioStreamMPC::_reload() {
demux = mpc_demux_init(&reader);
ERR_FAIL_COND_V(!demux,ERR_CANT_CREATE);
mpc_demux_get_info(demux, &si);
_setup(si.channels,si.sample_freq,MPC_DECODER_BUFFER_LENGTH*2/si.channels);
return OK;
}
void AudioStreamMPC::set_file(const String& p_file) {
void AudioStreamPlaybackMPC::set_file(const String& p_file) {
file=p_file;
Error err = _open_file();
ERR_FAIL_COND(err!=OK);
demux = mpc_demux_init(&reader);
ERR_FAIL_COND(!demux);
mpc_demux_get_info(demux, &si);
stream_min_size=MPC_DECODER_BUFFER_LENGTH*2/si.channels;
stream_rate=si.sample_freq;
stream_channels=si.channels;
mpc_demux_exit(demux);
demux=NULL;
_close_file();
}
String AudioStreamMPC::get_file() const {
String AudioStreamPlaybackMPC::get_file() const {
return file;
}
void AudioStreamMPC::play() {
void AudioStreamPlaybackMPC::play(float p_offset) {
_THREAD_SAFE_METHOD_
if (active)
stop();
active=false;
@ -262,9 +268,9 @@ void AudioStreamMPC::play() {
}
void AudioStreamMPC::stop() {
void AudioStreamPlaybackMPC::stop() {
_THREAD_SAFE_METHOD_
if (!active)
return;
if (demux) {
@ -275,70 +281,58 @@ void AudioStreamMPC::stop() {
active=false;
}
bool AudioStreamMPC::is_playing() const {
bool AudioStreamPlaybackMPC::is_playing() const {
return active || (get_total() - get_todo() -1 > 0);
return active;
}
void AudioStreamMPC::set_paused(bool p_paused) {
paused=p_paused;
}
bool AudioStreamMPC::is_paused(bool p_paused) const {
return paused;
}
void AudioStreamMPC::set_loop(bool p_enable) {
void AudioStreamPlaybackMPC::set_loop(bool p_enable) {
loop=p_enable;
}
bool AudioStreamMPC::has_loop() const {
bool AudioStreamPlaybackMPC::has_loop() const {
return loop;
}
float AudioStreamMPC::get_length() const {
float AudioStreamPlaybackMPC::get_length() const {
return 0;
}
String AudioStreamMPC::get_stream_name() const {
String AudioStreamPlaybackMPC::get_stream_name() const {
return "";
}
int AudioStreamMPC::get_loop_count() const {
int AudioStreamPlaybackMPC::get_loop_count() const {
return 0;
}
float AudioStreamMPC::get_pos() const {
float AudioStreamPlaybackMPC::get_pos() const {
return 0;
}
void AudioStreamMPC::seek_pos(float p_time) {
void AudioStreamPlaybackMPC::seek_pos(float p_time) {
}
AudioStream::UpdateMode AudioStreamMPC::get_update_mode() const {
return UPDATE_THREAD;
}
void AudioStreamPlaybackMPC::_bind_methods() {
void AudioStreamMPC::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_file","name"),&AudioStreamMPC::set_file);
ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamMPC::get_file);
ObjectTypeDB::bind_method(_MD("set_file","name"),&AudioStreamPlaybackMPC::set_file);
ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamPlaybackMPC::get_file);
ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"file",PROPERTY_HINT_FILE,"mpc"), _SCS("set_file"), _SCS("get_file"));
}
AudioStreamMPC::AudioStreamMPC() {
AudioStreamPlaybackMPC::AudioStreamPlaybackMPC() {
preload=true;
preload=false;
f=NULL;
streamlen=0;
data_ofs=0;
@ -356,7 +350,7 @@ AudioStreamMPC::AudioStreamMPC() {
}
AudioStreamMPC::~AudioStreamMPC() {
AudioStreamPlaybackMPC::~AudioStreamPlaybackMPC() {
stop();
@ -366,8 +360,9 @@ AudioStreamMPC::~AudioStreamMPC() {
RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path,const String& p_original_path) {
RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error)
*r_error=OK; //streamed so it will always work..
AudioStreamMPC *mpc_stream = memnew(AudioStreamMPC);
mpc_stream->set_file(p_path);
return Ref<AudioStreamMPC>(mpc_stream);

View file

@ -1,18 +1,17 @@
#ifndef AUDIO_STREAM_MPC_H
#define AUDIO_STREAM_MPC_H
#include "scene/resources/audio_stream_resampled.h"
#include "scene/resources/audio_stream.h"
#include "os/file_access.h"
#include "mpc/mpcdec.h"
#include "os/thread_safe.h"
#include "io/resource_loader.h"
//#include "../libmpcdec/decoder.h"
//#include "../libmpcdec/internal.h"
class AudioStreamMPC : public AudioStreamResampled {
OBJ_TYPE( AudioStreamMPC, AudioStreamResampled );
class AudioStreamPlaybackMPC : public AudioStreamPlayback {
_THREAD_SAFE_CLASS_
OBJ_TYPE( AudioStreamPlaybackMPC, AudioStreamPlayback );
bool preload;
FileAccess *f;
@ -39,7 +38,9 @@ class AudioStreamMPC : public AudioStreamResampled {
static mpc_int32_t _mpc_get_size(mpc_reader *p_reader);
static mpc_bool_t _mpc_canseek(mpc_reader *p_reader);
virtual bool _can_mix() const ;
int stream_min_size;
int stream_rate;
int stream_channels;
protected:
Error _open_file();
@ -59,12 +60,10 @@ public:
void set_file(const String& p_file);
String get_file() const;
virtual void play();
virtual void play(float p_offset=0);
virtual void stop();
virtual bool is_playing() const;
virtual void set_paused(bool p_paused);
virtual bool is_paused(bool p_paused) const;
virtual void set_loop(bool p_enable);
virtual bool has_loop() const;
@ -78,17 +77,39 @@ public:
virtual float get_pos() const;
virtual void seek_pos(float p_time);
virtual UpdateMode get_update_mode() const;
virtual void update();
virtual int get_channels() const { return stream_channels; }
virtual int get_mix_rate() const { return stream_rate; }
AudioStreamMPC();
~AudioStreamMPC();
virtual int get_minimum_buffer_size() const { return stream_min_size; }
virtual int mix(int16_t* p_bufer,int p_frames);
virtual void set_loop_restart_time(float p_time) { }
AudioStreamPlaybackMPC();
~AudioStreamPlaybackMPC();
};
class AudioStreamMPC : public AudioStream {
OBJ_TYPE( AudioStreamMPC, AudioStream );
String file;
public:
Ref<AudioStreamPlayback> instance_playback() {
Ref<AudioStreamPlaybackMPC> pb = memnew( AudioStreamPlaybackMPC );
pb->set_file(file);
return pb;
}
void set_file(const String& p_file) { file=p_file; }
};
class ResourceFormatLoaderAudioStreamMPC : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path,const String& p_original_path="");
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;

200
drivers/opus/SCsub Normal file
View file

@ -0,0 +1,200 @@
Import('env')
opus_sources = [
"opus/audio_stream_opus.cpp",
]
opus_sources_silk=[]
opus_sources_lib = [
"opus/celt/bands.c",
"opus/celt/celt_lpc.c",
"opus/celt/entenc.c",
"opus/celt/mdct.c",
"opus/celt/quant_bands.c",
"opus/celt/celt.c",
"opus/celt/cwrs.c",
"opus/celt/kiss_fft.c",
"opus/celt/modes.c",
"opus/celt/rate.c",
"opus/celt/celt_decoder.c",
"opus/celt/entcode.c",
"opus/celt/laplace.c",
#opus/celt/opus_custom_demo.c",
"opus/celt/vq.c",
"opus/celt/celt_encoder.c",
"opus/celt/entdec.c",
"opus/celt/mathops.c",
"opus/celt/pitch.c",
"opus/silk/A2NLSF.c",
"opus/silk/decoder_set_fs.c",
"opus/silk/NLSF_stabilize.c",
"opus/silk/sigm_Q15.c",
"opus/silk/ana_filt_bank_1.c",
"opus/silk/enc_API.c",
"opus/silk/NLSF_unpack.c",
"opus/silk/sort.c",
"opus/silk/biquad_alt.c",
"opus/silk/encode_indices.c",
"opus/silk/NLSF_VQ.c",
"opus/silk/stereo_decode_pred.c",
"opus/silk/bwexpander_32.c",
"opus/silk/encode_pulses.c",
"opus/silk/NLSF_VQ_weights_laroia.c",
"opus/silk/stereo_encode_pred.c",
"opus/silk/bwexpander.c",
"opus/silk/gain_quant.c",
"opus/silk/NSQ.c",
"opus/silk/stereo_find_predictor.c",
"opus/silk/check_control_input.c",
"opus/silk/HP_variable_cutoff.c",
"opus/silk/NSQ_del_dec.c",
"opus/silk/stereo_LR_to_MS.c",
"opus/silk/CNG.c",
"opus/silk/init_decoder.c",
"opus/silk/pitch_est_tables.c",
"opus/silk/stereo_MS_to_LR.c",
"opus/silk/code_signs.c",
"opus/silk/init_encoder.c",
"opus/silk/PLC.c",
"opus/silk/stereo_quant_pred.c",
"opus/silk/control_audio_bandwidth.c",
"opus/silk/inner_prod_aligned.c",
"opus/silk/process_NLSFs.c",
"opus/silk/sum_sqr_shift.c",
"opus/silk/control_codec.c",
"opus/silk/interpolate.c",
"opus/silk/quant_LTP_gains.c",
"opus/silk/table_LSF_cos.c",
"opus/silk/control_SNR.c",
"opus/silk/lin2log.c",
"opus/silk/resampler.c",
"opus/silk/tables_gain.c",
"opus/silk/debug.c",
"opus/silk/log2lin.c",
"opus/silk/resampler_down2_3.c",
"opus/silk/tables_LTP.c",
"opus/silk/dec_API.c",
"opus/silk/LPC_analysis_filter.c",
"opus/silk/resampler_down2.c",
"opus/silk/tables_NLSF_CB_NB_MB.c",
"opus/silk/decode_core.c",
"opus/silk/LPC_inv_pred_gain.c",
"opus/silk/resampler_private_AR2.c",
"opus/silk/tables_NLSF_CB_WB.c",
"opus/silk/decode_frame.c",
"opus/silk/LP_variable_cutoff.c",
"opus/silk/resampler_private_down_FIR.c",
"opus/silk/tables_other.c",
"opus/silk/decode_indices.c",
"opus/silk/NLSF2A.c",
"opus/silk/resampler_private_IIR_FIR.c",
"opus/silk/tables_pitch_lag.c",
"opus/silk/decode_parameters.c",
"opus/silk/NLSF_decode.c",
"opus/silk/resampler_private_up2_HQ.c",
"opus/silk/tables_pulses_per_block.c",
"opus/silk/decode_pitch.c",
"opus/silk/NLSF_del_dec_quant.c",
"opus/silk/resampler_rom.c",
"opus/silk/VAD.c",
"opus/silk/decode_pulses.c",
"opus/silk/NLSF_encode.c",
"opus/silk/shell_coder.c",
"opus/silk/VQ_WMat_EC.c",
"opus/analysis.c",
"opus/internal.c",
"opus/opus.c",
#"opus/opus_demo.c",
"opus/opus_multistream.c",
"opus/repacketizer.c",
"opus/wincerts.c",
"opus/http.c",
"opus/mlp.c",
#"opus/opus_compare.c",
"opus/opus_encoder.c",
"opus/opus_multistream_decoder.c",
#"opus/repacketizer_demo.c",
"opus/info.c",
"opus/mlp_data.c",
"opus/opus_decoder.c",
"opus/opusfile.c",
"opus/opus_multistream_encoder.c",
"opus/stream.c"
]
if("opus_fixed_point" in env and env.opus_fixed_point=="yes"):
env.Append(CPPPATH=["#drivers/opus/silk/fixed"], CFLAGS=["-DOPUS_FIXED_POINT"])
opus_sources_silk = [
"opus/silk/fixed/apply_sine_window_FIX.c",
"opus/silk/fixed/k2a_FIX.c",
"opus/silk/fixed/residual_energy16_FIX.c",
"opus/silk/fixed/autocorr_FIX.c",
"opus/silk/fixed/k2a_Q16_FIX.c",
"opus/silk/fixed/residual_energy_FIX.c",
"opus/silk/fixed/burg_modified_FIX.c",
"opus/silk/fixed/LTP_analysis_filter_FIX.c",
"opus/silk/fixed/schur64_FIX.c",
"opus/silk/fixed/corrMatrix_FIX.c",
"opus/silk/fixed/LTP_scale_ctrl_FIX.c",
"opus/silk/fixed/schur_FIX.c",
"opus/silk/fixed/encode_frame_FIX.c",
"opus/silk/fixed/noise_shape_analysis_FIX.c",
"opus/silk/fixed/solve_LS_FIX.c",
"opus/silk/fixed/find_LPC_FIX.c",
"opus/silk/fixed/pitch_analysis_core_FIX.c",
"opus/silk/fixed/vector_ops_FIX.c",
"opus/silk/fixed/find_LTP_FIX.c",
"opus/silk/fixed/prefilter_FIX.c",
"opus/silk/fixed/warped_autocorrelation_FIX.c",
"opus/silk/fixed/find_pitch_lags_FIX.c",
"opus/silk/fixed/process_gains_FIX.c",
"opus/silk/fixed/find_pred_coefs_FIX.c",
"opus/silk/fixed/regularize_correlations_FIX.c"
]
else:
env.Append(CPPPATH=["#drivers/opus/silk/float"])
opus_sources_silk = [
"opus/silk/float/apply_sine_window_FLP.c",
"opus/silk/float/inner_product_FLP.c",
"opus/silk/float/regularize_correlations_FLP.c",
"opus/silk/float/autocorrelation_FLP.c",
"opus/silk/float/k2a_FLP.c",
"opus/silk/float/residual_energy_FLP.c",
"opus/silk/float/burg_modified_FLP.c",
"opus/silk/float/levinsondurbin_FLP.c",
"opus/silk/float/scale_copy_vector_FLP.c",
"opus/silk/float/bwexpander_FLP.c",
"opus/silk/float/LPC_analysis_filter_FLP.c",
"opus/silk/float/scale_vector_FLP.c",
"opus/silk/float/corrMatrix_FLP.c",
"opus/silk/float/LPC_inv_pred_gain_FLP.c",
"opus/silk/float/schur_FLP.c",
"opus/silk/float/encode_frame_FLP.c",
"opus/silk/float/LTP_analysis_filter_FLP.c",
"opus/silk/float/solve_LS_FLP.c",
"opus/silk/float/energy_FLP.c",
"opus/silk/float/LTP_scale_ctrl_FLP.c",
"opus/silk/float/sort_FLP.c",
"opus/silk/float/find_LPC_FLP.c",
"opus/silk/float/noise_shape_analysis_FLP.c",
"opus/silk/float/warped_autocorrelation_FLP.c",
"opus/silk/float/find_LTP_FLP.c",
"opus/silk/float/pitch_analysis_core_FLP.c",
"opus/silk/float/wrappers_FLP.c",
"opus/silk/float/find_pitch_lags_FLP.c",
"opus/silk/float/prefilter_FLP.c",
"opus/silk/float/find_pred_coefs_FLP.c",
"opus/silk/float/process_gains_FLP.c"
]
opus_sources_lib+=opus_sources_silk
env.drivers_sources+=opus_sources_lib
env.drivers_sources+=opus_sources
env.Append(CPPPATH=["#drivers/opus"])
env.Append(CPPPATH=["#drivers/opus/celt","#drivers/opus/silk","#drivers/opus/silk/float"])
env.Append(CFLAGS=["-DOPUS_HAVE_CONFIG_H"])
Export('env')

645
drivers/opus/analysis.c Normal file
View file

@ -0,0 +1,645 @@
/* Copyright (c) 2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef OPUS_HAVE_CONFIG_H
#include "opus_config.h"
#endif
#include "kiss_fft.h"
#include "celt.h"
#include "opus_modes.h"
#include "arch.h"
#include "quant_bands.h"
#include <stdio.h>
#include "analysis.h"
#include "mlp.h"
#include "stack_alloc.h"
extern const MLP net;
#ifndef M_PI
#define M_PI 3.141592653
#endif
static const float dct_table[128] = {
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f,
-0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f,
0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f,
-0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f,
0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f,
0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f,
0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f,
-0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f,
0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f,
-0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f,
0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f,
0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f,
};
static const float analysis_window[240] = {
0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f,
0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f,
0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f,
0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f,
0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f,
0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f,
0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f,
0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f,
0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f,
0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f,
0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f,
0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f,
0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f,
0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f,
0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f,
0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f,
0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f,
0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f,
0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f,
0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f,
0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f,
0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f,
0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f,
0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f,
0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f,
0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f,
0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f,
0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f,
0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f,
0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f,
};
static const int tbands[NB_TBANDS+1] = {
2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120
};
static const int extra_bands[NB_TOT_BANDS+1] = {
1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200
};
/*static const float tweight[NB_TBANDS+1] = {
.3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5
};*/
#define NB_TONAL_SKIP_BANDS 9
#define cA 0.43157974f
#define cB 0.67848403f
#define cC 0.08595542f
#define cE ((float)M_PI/2)
static OPUS_INLINE float fast_atan2f(float y, float x) {
float x2, y2;
/* Should avoid underflow on the values we'll get */
if (ABS16(x)+ABS16(y)<1e-9f)
{
x*=1e12f;
y*=1e12f;
}
x2 = x*x;
y2 = y*y;
if(x2<y2){
float den = (y2 + cB*x2) * (y2 + cC*x2);
if (den!=0)
return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
else
return (y<0 ? -cE : cE);
}else{
float den = (x2 + cB*y2) * (x2 + cC*y2);
if (den!=0)
return x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
else
return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
}
}
void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)
{
int pos;
int curr_lookahead;
float psum;
int i;
pos = tonal->read_pos;
curr_lookahead = tonal->write_pos-tonal->read_pos;
if (curr_lookahead<0)
curr_lookahead += DETECT_SIZE;
if (len > 480 && pos != tonal->write_pos)
{
pos++;
if (pos==DETECT_SIZE)
pos=0;
}
if (pos == tonal->write_pos)
pos--;
if (pos<0)
pos = DETECT_SIZE-1;
OPUS_COPY(info_out, &tonal->info[pos], 1);
tonal->read_subframe += len/120;
while (tonal->read_subframe>=4)
{
tonal->read_subframe -= 4;
tonal->read_pos++;
}
if (tonal->read_pos>=DETECT_SIZE)
tonal->read_pos-=DETECT_SIZE;
/* Compensate for the delay in the features themselves.
FIXME: Need a better estimate the 10 I just made up */
curr_lookahead = IMAX(curr_lookahead-10, 0);
psum=0;
/* Summing the probability of transition patterns that involve music at
time (DETECT_SIZE-curr_lookahead-1) */
for (i=0;i<DETECT_SIZE-curr_lookahead;i++)
psum += tonal->pmusic[i];
for (;i<DETECT_SIZE;i++)
psum += tonal->pspeech[i];
psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;
/*printf("%f %f %f\n", psum, info_out->music_prob, info_out->tonality);*/
info_out->music_prob = psum;
}
void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
{
int i, b;
const kiss_fft_state *kfft;
VARDECL(kiss_fft_cpx, in);
VARDECL(kiss_fft_cpx, out);
int N = 480, N2=240;
float * OPUS_RESTRICT A = tonal->angle;
float * OPUS_RESTRICT dA = tonal->d_angle;
float * OPUS_RESTRICT d2A = tonal->d2_angle;
VARDECL(float, tonality);
VARDECL(float, noisiness);
float band_tonality[NB_TBANDS];
float logE[NB_TBANDS];
float BFCC[8];
float features[25];
float frame_tonality;
float max_frame_tonality;
/*float tw_sum=0;*/
float frame_noisiness;
const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI);
float slope=0;
float frame_stationarity;
float relativeE;
float frame_probs[2];
float alpha, alphaE, alphaE2;
float frame_loudness;
float bandwidth_mask;
int bandwidth=0;
float maxE = 0;
float noise_floor;
int remaining;
AnalysisInfo *info;
SAVE_STACK;
tonal->last_transition++;
alpha = 1.f/IMIN(20, 1+tonal->count);
alphaE = 1.f/IMIN(50, 1+tonal->count);
alphaE2 = 1.f/IMIN(1000, 1+tonal->count);
if (tonal->count<4)
tonal->music_prob = .5;
kfft = celt_mode->mdct.kfft[0];
if (tonal->count==0)
tonal->mem_fill = 240;
downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C);
if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
{
tonal->mem_fill += len;
/* Don't have enough to update the analysis */
RESTORE_STACK;
return;
}
info = &tonal->info[tonal->write_pos++];
if (tonal->write_pos>=DETECT_SIZE)
tonal->write_pos-=DETECT_SIZE;
ALLOC(in, 480, kiss_fft_cpx);
ALLOC(out, 480, kiss_fft_cpx);
ALLOC(tonality, 240, float);
ALLOC(noisiness, 240, float);
for (i=0;i<N2;i++)
{
float w = analysis_window[i];
in[i].r = (kiss_fft_scalar)(w*tonal->inmem[i]);
in[i].i = (kiss_fft_scalar)(w*tonal->inmem[N2+i]);
in[N-i-1].r = (kiss_fft_scalar)(w*tonal->inmem[N-i-1]);
in[N-i-1].i = (kiss_fft_scalar)(w*tonal->inmem[N+N2-i-1]);
}
OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);
tonal->mem_fill = 240 + remaining;
opus_fft(kfft, in, out);
for (i=1;i<N2;i++)
{
float X1r, X2r, X1i, X2i;
float angle, d_angle, d2_angle;
float angle2, d_angle2, d2_angle2;
float mod1, mod2, avg_mod;
X1r = (float)out[i].r+out[N-i].r;
X1i = (float)out[i].i-out[N-i].i;
X2r = (float)out[i].i+out[N-i].i;
X2i = (float)out[N-i].r-out[i].r;
angle = (float)(.5f/M_PI)*fast_atan2f(X1i, X1r);
d_angle = angle - A[i];
d2_angle = d_angle - dA[i];
angle2 = (float)(.5f/M_PI)*fast_atan2f(X2i, X2r);
d_angle2 = angle2 - angle;
d2_angle2 = d_angle2 - d_angle;
mod1 = d2_angle - (float)floor(.5+d2_angle);
noisiness[i] = ABS16(mod1);
mod1 *= mod1;
mod1 *= mod1;
mod2 = d2_angle2 - (float)floor(.5+d2_angle2);
noisiness[i] += ABS16(mod2);
mod2 *= mod2;
mod2 *= mod2;
avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);
tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
A[i] = angle2;
dA[i] = d_angle2;
d2A[i] = mod2;
}
frame_tonality = 0;
max_frame_tonality = 0;
/*tw_sum = 0;*/
info->activity = 0;
frame_noisiness = 0;
frame_stationarity = 0;
if (!tonal->count)
{
for (b=0;b<NB_TBANDS;b++)
{
tonal->lowE[b] = 1e10;
tonal->highE[b] = -1e10;
}
}
relativeE = 0;
frame_loudness = 0;
for (b=0;b<NB_TBANDS;b++)
{
float E=0, tE=0, nE=0;
float L1, L2;
float stationarity;
for (i=tbands[b];i<tbands[b+1];i++)
{
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
#ifdef OPUS_FIXED_POINT
/* FIXME: It's probably best to change the BFCC filter initial state instead */
binE *= 5.55e-17f;
#endif
E += binE;
tE += binE*tonality[i];
nE += binE*2.f*(.5f-noisiness[i]);
}
tonal->E[tonal->E_count][b] = E;
frame_noisiness += nE/(1e-15f+E);
frame_loudness += (float)sqrt(E+1e-10f);
logE[b] = (float)log(E+1e-10f);
tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
if (tonal->highE[b] < tonal->lowE[b]+1.f)
{
tonal->highE[b]+=.5f;
tonal->lowE[b]-=.5f;
}
relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]);
L1=L2=0;
for (i=0;i<NB_FRAMES;i++)
{
L1 += (float)sqrt(tonal->E[i][b]);
L2 += tonal->E[i][b];
}
stationarity = MIN16(0.99f,L1/(float)sqrt(1e-15+NB_FRAMES*L2));
stationarity *= stationarity;
stationarity *= stationarity;
frame_stationarity += stationarity;
/*band_tonality[b] = tE/(1e-15+E)*/;
band_tonality[b] = MAX16(tE/(1e-15f+E), stationarity*tonal->prev_band_tonality[b]);
#if 0
if (b>=NB_TONAL_SKIP_BANDS)
{
frame_tonality += tweight[b]*band_tonality[b];
tw_sum += tweight[b];
}
#else
frame_tonality += band_tonality[b];
if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS)
frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS];
#endif
max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality);
slope += band_tonality[b]*(b-8);
/*printf("%f %f ", band_tonality[b], stationarity);*/
tonal->prev_band_tonality[b] = band_tonality[b];
}
bandwidth_mask = 0;
bandwidth = 0;
maxE = 0;
noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
#ifdef OPUS_FIXED_POINT
noise_floor *= 1<<(15+SIG_SHIFT);
#endif
noise_floor *= noise_floor;
for (b=0;b<NB_TOT_BANDS;b++)
{
float E=0;
int band_start, band_end;
/* Keep a margin of 300 Hz for aliasing */
band_start = extra_bands[b];
band_end = extra_bands[b+1];
for (i=band_start;i<band_end;i++)
{
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
E += binE;
}
maxE = MAX32(maxE, E);
tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
E = MAX32(E, tonal->meanE[b]);
/* Use a simple follower with 13 dB/Bark slope for spreading function */
bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
/* Consider the band "active" only if all these conditions are met:
1) less than 10 dB below the simple follower
2) less than 90 dB below the peak band (maximal masking possible considering
both the ATH and the loudness-dependent slope of the spreading function)
3) above the PCM quantization noise floor
*/
if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start))
bandwidth = b;
}
if (tonal->count<=2)
bandwidth = 20;
frame_loudness = 20*(float)log10(frame_loudness);
tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);
tonal->lowECount *= (1-alphaE);
if (frame_loudness < tonal->Etracker-30)
tonal->lowECount += alphaE;
for (i=0;i<8;i++)
{
float sum=0;
for (b=0;b<16;b++)
sum += dct_table[i*16+b]*logE[b];
BFCC[i] = sum;
}
frame_stationarity /= NB_TBANDS;
relativeE /= NB_TBANDS;
if (tonal->count<10)
relativeE = .5;
frame_noisiness /= NB_TBANDS;
#if 1
info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
#else
info->activity = .5*(1+frame_noisiness-frame_stationarity);
#endif
frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS));
frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f);
tonal->prev_tonality = frame_tonality;
slope /= 8*8;
info->tonality_slope = slope;
tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
tonal->count++;
info->tonality = frame_tonality;
for (i=0;i<4;i++)
features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i];
for (i=0;i<4;i++)
tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i];
for (i=0;i<4;i++)
features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]);
for (i=0;i<3;i++)
features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8];
if (tonal->count > 5)
{
for (i=0;i<9;i++)
tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
}
for (i=0;i<8;i++)
{
tonal->mem[i+24] = tonal->mem[i+16];
tonal->mem[i+16] = tonal->mem[i+8];
tonal->mem[i+8] = tonal->mem[i];
tonal->mem[i] = BFCC[i];
}
for (i=0;i<9;i++)
features[11+i] = (float)sqrt(tonal->std[i]);
features[20] = info->tonality;
features[21] = info->activity;
features[22] = frame_stationarity;
features[23] = info->tonality_slope;
features[24] = tonal->lowECount;
#ifndef DISABLE_FLOAT_API
mlp_process(&net, features, frame_probs);
frame_probs[0] = .5f*(frame_probs[0]+1);
/* Curve fitting between the MLP probability and the actual probability */
frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);
/* Probability of active audio (as opposed to silence) */
frame_probs[1] = .5f*frame_probs[1]+.5f;
/* Consider that silence has a 50-50 probability. */
frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f;
/*printf("%f %f ", frame_probs[0], frame_probs[1]);*/
{
/* Probability of state transition */
float tau;
/* Represents independence of the MLP probabilities, where
beta=1 means fully independent. */
float beta;
/* Denormalized probability of speech (p0) and music (p1) after update */
float p0, p1;
/* Probabilities for "all speech" and "all music" */
float s0, m0;
/* Probability sum for renormalisation */
float psum;
/* Instantaneous probability of speech and music, with beta pre-applied. */
float speech0;
float music0;
/* One transition every 3 minutes of active audio */
tau = .00005f*frame_probs[1];
beta = .05f;
if (1) {
/* Adapt beta based on how "unexpected" the new prob is */
float p, q;
p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
}
/* p0 and p1 are the probabilities of speech and music at this frame
using only information from previous frame and applying the
state transition model */
p0 = (1-tonal->music_prob)*(1-tau) + tonal->music_prob *tau;
p1 = tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau;
/* We apply the current probability with exponent beta to work around
the fact that the probability estimates aren't independent. */
p0 *= (float)pow(1-frame_probs[0], beta);
p1 *= (float)pow(frame_probs[0], beta);
/* Normalise the probabilities to get the Marokv probability of music. */
tonal->music_prob = p1/(p0+p1);
info->music_prob = tonal->music_prob;
/* This chunk of code deals with delayed decision. */
psum=1e-20f;
/* Instantaneous probability of speech and music, with beta pre-applied. */
speech0 = (float)pow(1-frame_probs[0], beta);
music0 = (float)pow(frame_probs[0], beta);
if (tonal->count==1)
{
tonal->pspeech[0]=.5;
tonal->pmusic [0]=.5;
}
/* Updated probability of having only speech (s0) or only music (m0),
before considering the new observation. */
s0 = tonal->pspeech[0] + tonal->pspeech[1];
m0 = tonal->pmusic [0] + tonal->pmusic [1];
/* Updates s0 and m0 with instantaneous probability. */
tonal->pspeech[0] = s0*(1-tau)*speech0;
tonal->pmusic [0] = m0*(1-tau)*music0;
/* Propagate the transition probabilities */
for (i=1;i<DETECT_SIZE-1;i++)
{
tonal->pspeech[i] = tonal->pspeech[i+1]*speech0;
tonal->pmusic [i] = tonal->pmusic [i+1]*music0;
}
/* Probability that the latest frame is speech, when all the previous ones were music. */
tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0;
/* Probability that the latest frame is music, when all the previous ones were speech. */
tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0;
/* Renormalise probabilities to 1 */
for (i=0;i<DETECT_SIZE;i++)
psum += tonal->pspeech[i] + tonal->pmusic[i];
psum = 1.f/psum;
for (i=0;i<DETECT_SIZE;i++)
{
tonal->pspeech[i] *= psum;
tonal->pmusic [i] *= psum;
}
psum = tonal->pmusic[0];
for (i=1;i<DETECT_SIZE;i++)
psum += tonal->pspeech[i];
/* Estimate our confidence in the speech/music decisions */
if (frame_probs[1]>.75)
{
if (tonal->music_prob>.9)
{
float adapt;
adapt = 1.f/(++tonal->music_confidence_count);
tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500);
tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence);
}
if (tonal->music_prob<.1)
{
float adapt;
adapt = 1.f/(++tonal->speech_confidence_count);
tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);
tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);
}
} else {
if (tonal->music_confidence_count==0)
tonal->music_confidence = .9f;
if (tonal->speech_confidence_count==0)
tonal->speech_confidence = .1f;
}
}
if (tonal->last_music != (tonal->music_prob>.5f))
tonal->last_transition=0;
tonal->last_music = tonal->music_prob>.5f;
#else
info->music_prob = 0;
#endif
/*for (i=0;i<25;i++)
printf("%f ", features[i]);
printf("\n");*/
info->bandwidth = bandwidth;
/*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
info->noisiness = frame_noisiness;
info->valid = 1;
if (info_out!=NULL)
OPUS_COPY(info_out, info, 1);
RESTORE_STACK;
}
void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info)
{
int offset;
int pcm_len;
if (analysis_pcm != NULL)
{
/* Avoid overflow/wrap-around of the analysis buffer */
analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size);
pcm_len = analysis_frame_size - analysis->analysis_offset;
offset = analysis->analysis_offset;
do {
tonality_analysis(analysis, NULL, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
offset += 480;
pcm_len -= 480;
} while (pcm_len>0);
analysis->analysis_offset = analysis_frame_size;
analysis->analysis_offset -= frame_size;
}
analysis_info->valid = 0;
tonality_get_info(analysis, analysis_info, frame_size);
}

90
drivers/opus/analysis.h Normal file
View file

@ -0,0 +1,90 @@
/* Copyright (c) 2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ANALYSIS_H
#define ANALYSIS_H
#include "celt.h"
#include "opus_private.h"
#define NB_FRAMES 8
#define NB_TBANDS 18
#define NB_TOT_BANDS 21
#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */
#define DETECT_SIZE 200
typedef struct {
float angle[240];
float d_angle[240];
float d2_angle[240];
opus_val32 inmem[ANALYSIS_BUF_SIZE];
int mem_fill; /* number of usable samples in the buffer */
float prev_band_tonality[NB_TBANDS];
float prev_tonality;
float E[NB_FRAMES][NB_TBANDS];
float lowE[NB_TBANDS];
float highE[NB_TBANDS];
float meanE[NB_TOT_BANDS];
float mem[32];
float cmean[8];
float std[9];
float music_prob;
float Etracker;
float lowECount;
int E_count;
int last_music;
int last_transition;
int count;
float subframe_mem[3];
int analysis_offset;
/** Probability of having speech for time i to DETECT_SIZE-1 (and music before).
pspeech[0] is the probability that all frames in the window are speech. */
float pspeech[DETECT_SIZE];
/** Probability of having music for time i to DETECT_SIZE-1 (and speech before).
pmusic[0] is the probability that all frames in the window are music. */
float pmusic[DETECT_SIZE];
float speech_confidence;
float music_confidence;
int speech_confidence_count;
int music_confidence_count;
int write_pos;
int read_pos;
int read_subframe;
AnalysisInfo info[DETECT_SIZE];
} TonalityAnalysisState;
void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info,
const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix);
void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len);
void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info);
#endif

View file

@ -0,0 +1,376 @@
/*************************************************************************/
/* audio_stream_opus.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Author: George Marques <george@gmarqu.es> */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "audio_stream_opus.h"
const float AudioStreamPlaybackOpus::osrate=48000.0f;
int AudioStreamPlaybackOpus::_op_read_func(void *_stream, unsigned char *_ptr, int _nbytes) {
FileAccess *fa=(FileAccess*)_stream;
if(fa->eof_reached())
return 0;
uint8_t *dst = (uint8_t*)_ptr;
int read = fa->get_buffer(dst, _nbytes);
return read;
}
int AudioStreamPlaybackOpus::_op_seek_func(void *_stream, opus_int64 _offset, int _whence){
#ifdef SEEK_SET
FileAccess *fa=(FileAccess*)_stream;
switch (_whence) {
case SEEK_SET: {
fa->seek(_offset);
} break;
case SEEK_CUR: {
fa->seek(fa->get_pos()+_offset);
} break;
case SEEK_END: {
fa->seek_end(_offset);
} break;
default: {
ERR_PRINT("BUG, wtf was whence set to?\n");
}
}
int ret=fa->eof_reached()?-1:0;
return ret;
#else
return -1; // no seeking
#endif
}
int AudioStreamPlaybackOpus::_op_close_func(void *_stream) {
if (!_stream)
return 0;
FileAccess *fa=(FileAccess*)_stream;
if (fa->is_open())
fa->close();
return 0;
}
opus_int64 AudioStreamPlaybackOpus::_op_tell_func(void *_stream) {
FileAccess *_fa = (FileAccess*)_stream;
return (opus_int64)_fa->get_pos();
}
void AudioStreamPlaybackOpus::_clear_stream() {
if(!stream_loaded)
return;
op_free(opus_file);
_close_file();
stream_loaded=false;
stream_channels=1;
playing=false;
}
void AudioStreamPlaybackOpus::_close_file() {
if (f) {
memdelete(f);
f=NULL;
}
}
Error AudioStreamPlaybackOpus::_load_stream() {
ERR_FAIL_COND_V(!stream_valid,ERR_UNCONFIGURED);
_clear_stream();
if (file=="")
return ERR_INVALID_DATA;
Error err;
f=FileAccess::open(file,FileAccess::READ,&err);
if (err) {
ERR_FAIL_COND_V( err, err );
}
int _err = 0;
opus_file = op_open_callbacks(f,&_op_callbacks,NULL,0,&_err);
switch (_err) {
case OP_EREAD: { // - Can't read the file.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_FILE_CANT_READ );
} break;
case OP_EVERSION: // - Unrecognized version number.
case OP_ENOTFORMAT: // - Stream is not Opus data.
case OP_EIMPL : { // - Stream used non-implemented feature.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_FILE_UNRECOGNIZED );
} break;
case OP_EBADLINK: // - Failed to find old data after seeking.
case OP_EBADTIMESTAMP: // - Timestamp failed the validity checks.
case OP_EBADHEADER: { // - Invalid or mising Opus bitstream header.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_FILE_CORRUPT );
} break;
case OP_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_BUG );
} break;
}
repeats=0;
stream_loaded=true;
return OK;
}
AudioStreamPlaybackOpus::AudioStreamPlaybackOpus() {
loops=false;
playing=false;
f = NULL;
stream_loaded=false;
stream_valid=false;
repeats=0;
paused=true;
stream_channels=0;
current_section=0;
length=0;
loop_restart_time=0;
pre_skip=0;
_op_callbacks.read = _op_read_func;
_op_callbacks.seek = _op_seek_func;
_op_callbacks.tell = _op_tell_func;
_op_callbacks.close = _op_close_func;
}
Error AudioStreamPlaybackOpus::set_file(const String &p_file) {
file=p_file;
stream_valid=false;
Error err;
f=FileAccess::open(file,FileAccess::READ,&err);
if (err) {
ERR_FAIL_COND_V( err, err );
}
int _err;
opus_file = op_open_callbacks(f,&_op_callbacks,NULL,0,&_err);
switch (_err) {
case OP_EREAD: { // - Can't read the file.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_FILE_CANT_READ );
} break;
case OP_EVERSION: // - Unrecognized version number.
case OP_ENOTFORMAT: // - Stream is not Opus data.
case OP_EIMPL : { // - Stream used non-implemented feature.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_FILE_UNRECOGNIZED );
} break;
case OP_EBADLINK: // - Failed to find old data after seeking.
case OP_EBADTIMESTAMP: // - Timestamp failed the validity checks.
case OP_EBADHEADER: { // - Invalid or mising Opus bitstream header.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_FILE_CORRUPT );
} break;
case OP_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption.
memdelete(f); f=NULL;
ERR_FAIL_V( ERR_BUG );
} break;
}
const OpusHead *oinfo = op_head(opus_file,-1);
stream_channels=oinfo->channel_count;
pre_skip=oinfo->pre_skip;
frames_mixed=pre_skip;
ogg_int64_t len = op_pcm_total(opus_file,-1);
if(len < 0) {
length = 0;
} else {
length=(len/osrate);
}
op_free(opus_file);
memdelete(f);
f=NULL;
stream_valid=true;
return OK;
}
void AudioStreamPlaybackOpus::play(float p_from) {
if (playing)
stop();
if (_load_stream()!=OK)
return;
frames_mixed=pre_skip;
playing=true;
if (p_from>0) {
seek_pos(p_from);
}
}
void AudioStreamPlaybackOpus::stop() {
_clear_stream();
playing=false;
}
void AudioStreamPlaybackOpus::seek_pos(float p_time) {
if(!playing) return;
ogg_int64_t pcm_offset = (ogg_int64_t)(p_time * osrate);
bool ok = op_pcm_seek(opus_file,pcm_offset)==0;
if(!ok) {
ERR_PRINT("Seek time over stream size.");
return;
}
frames_mixed=osrate*p_time;
}
int AudioStreamPlaybackOpus::mix(int16_t* p_bufer,int p_frames) {
if (!playing)
return 0;
int total=p_frames;
while (true) {
int todo = p_frames;
if (todo==0 || todo<MIN_MIX) {
break;
}
int ret=op_read(opus_file,(opus_int16*)p_bufer,todo*stream_channels,&current_section);
if (ret<0) {
playing = false;
ERR_EXPLAIN("Error reading Opus File: "+file);
ERR_BREAK(ret<0);
} else if (ret==0) { // end of song, reload?
op_free(opus_file);
_close_file();
f=FileAccess::open(file,FileAccess::READ);
int errv = 0;
opus_file = op_open_callbacks(f,&_op_callbacks,NULL,0,&errv);
if (errv!=0) {
playing=false;
break; // :(
}
if (!has_loop()) {
playing=false;
repeats=1;
break;
}
if (loop_restart_time) {
bool ok = op_pcm_seek(opus_file, (loop_restart_time*osrate)+pre_skip)==0;
if (!ok) {
playing=false;
ERR_PRINT("loop restart time rejected")
}
frames_mixed=(loop_restart_time*osrate)+pre_skip;
} else {
frames_mixed=pre_skip;
}
repeats++;
continue;
}
stream_channels=op_head(opus_file,current_section)->channel_count;
frames_mixed+=ret;
p_bufer+=ret*stream_channels;
p_frames-=ret;
}
return total-p_frames;
}
float AudioStreamPlaybackOpus::get_length() const {
if(!stream_loaded) {
if(const_cast<AudioStreamPlaybackOpus*>(this)->_load_stream() != OK)
return 0;
}
return length;
}
float AudioStreamPlaybackOpus::get_pos() const {
int32_t frames = int32_t(frames_mixed);
if (frames < 0)
frames=0;
return double(frames) / osrate;
}
int AudioStreamPlaybackOpus::get_minimum_buffer_size() const {
return MIN_MIX;
}
AudioStreamPlaybackOpus::~AudioStreamPlaybackOpus() {
_clear_stream();
}
RES ResourceFormatLoaderAudioStreamOpus::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error)
*r_error=OK;
AudioStreamOpus *opus_stream = memnew(AudioStreamOpus);
opus_stream->set_file(p_path);
return Ref<AudioStreamOpus>(opus_stream);
}
void ResourceFormatLoaderAudioStreamOpus::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("opus");
}
String ResourceFormatLoaderAudioStreamOpus::get_resource_type(const String &p_path) const {
if (p_path.extension().to_lower()=="opus")
return "AudioStreamOpus";
return "";
}
bool ResourceFormatLoaderAudioStreamOpus::handles_type(const String& p_type) const {
return (p_type=="AudioStream" || p_type=="AudioStreamOpus");
}

View file

@ -0,0 +1,141 @@
/*************************************************************************/
/* audio_stream_opus.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Author: George Marques <george@gmarqu.es> */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef AUDIO_STREAM_OPUS_H
#define AUDIO_STREAM_OPUS_H
#include "scene/resources/audio_stream.h"
#include "opus/opusfile.h"
#include "opus/internal.h"
#include "os/file_access.h"
#include "io/resource_loader.h"
class AudioStreamPlaybackOpus : public AudioStreamPlayback {
OBJ_TYPE(AudioStreamPlaybackOpus,AudioStreamPlayback)
enum {
MIN_MIX=1024
};
FileAccess *f;
OpusFileCallbacks _op_callbacks;
float length;
static int _op_read_func(void *_stream, unsigned char *_ptr, int _nbytes);
static int _op_seek_func(void *_stream, opus_int64 _offset, int _whence);
static int _op_close_func(void *_stream);
static opus_int64 _op_tell_func(void *_stream);
static const float osrate;
String file;
int64_t frames_mixed;
bool stream_loaded;
volatile bool playing;
OggOpusFile *opus_file;
int stream_channels;
int current_section;
int pre_skip;
bool paused;
bool loops;
int repeats;
Error _load_stream();
void _clear_stream();
void _close_file();
bool stream_valid;
float loop_restart_time;
public:
Error set_file(const String& p_file);
virtual void play(float p_from=0);
virtual void stop();
virtual bool is_playing() const { return playing; }
virtual void set_loop_restart_time(float p_time) { loop_restart_time=p_time; }
virtual void set_paused(bool p_paused) { paused=p_paused; }
virtual bool is_paused() const { return paused; }
virtual void set_loop(bool p_enable) { loops=p_enable; }
virtual bool has_loop() const {return loops; }
virtual float get_length() const;
virtual String get_stream_name() const { return ""; }
virtual int get_loop_count() const { return repeats; }
virtual float get_pos() const;
virtual void seek_pos(float p_time);
virtual int get_channels() const { return stream_channels; }
virtual int get_mix_rate() const { return osrate; }
virtual int get_minimum_buffer_size() const;
virtual int mix(int16_t* p_bufer,int p_frames);
AudioStreamPlaybackOpus();
~AudioStreamPlaybackOpus();
};
class AudioStreamOpus: public AudioStream {
OBJ_TYPE(AudioStreamOpus,AudioStream)
String file;
public:
Ref<AudioStreamPlayback> instance_playback() {
Ref<AudioStreamPlaybackOpus> pb = memnew( AudioStreamPlaybackOpus );
pb->set_file(file);
return pb;
}
void set_file(const String& p_file) { file=p_file; }
};
class ResourceFormatLoaderAudioStreamOpus: public ResourceFormatLoader {
public:
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
#endif // AUDIO_STREAM_OPUS_H

View file

@ -0,0 +1,183 @@
/*Copyright (c) 2003-2004, Mark Borgerding
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
#ifndef KISS_FFT_GUTS_H
#define KISS_FFT_GUTS_H
#define MIN(a,b) ((a)<(b) ? (a):(b))
#define MAX(a,b) ((a)>(b) ? (a):(b))
/* kiss_fft.h
defines kiss_fft_scalar as either short or a float type
and defines
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
#include "kiss_fft.h"
/*
Explanation of macros dealing with complex math:
C_MUL(m,a,b) : m = a*b
C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
C_SUB( res, a,b) : res = a - b
C_SUBFROM( res , a) : res -= a
C_ADDTO( res , a) : res += a
* */
#ifdef OPUS_FIXED_POINT
#include "arch.h"
#define SAMP_MAX 2147483647
#define TWID_MAX 32767
#define TRIG_UPSCALE 1
#define SAMP_MIN -SAMP_MAX
# define S_MUL(a,b) MULT16_32_Q15(b, a)
# define C_MUL(m,a,b) \
do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
(m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
# define C_MULC(m,a,b) \
do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
(m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
# define C_MUL4(m,a,b) \
do{ (m).r = SHR32(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \
(m).i = SHR32(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0)
# define C_MULBYSCALAR( c, s ) \
do{ (c).r = S_MUL( (c).r , s ) ;\
(c).i = S_MUL( (c).i , s ) ; }while(0)
# define DIVSCALAR(x,k) \
(x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 )
# define C_FIXDIV(c,div) \
do { DIVSCALAR( (c).r , div); \
DIVSCALAR( (c).i , div); }while (0)
#define C_ADD( res, a,b)\
do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \
}while(0)
#define C_SUB( res, a,b)\
do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \
}while(0)
#define C_ADDTO( res , a)\
do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\
}while(0)
#define C_SUBFROM( res , a)\
do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
}while(0)
#if defined(OPUS_ARM_INLINE_ASM)
#include "arm/kiss_fft_armv4.h"
#endif
#if defined(OPUS_ARM_INLINE_EDSP)
#include "arm/kiss_fft_armv5e.h"
#endif
#else /* not OPUS_FIXED_POINT*/
# define S_MUL(a,b) ( (a)*(b) )
#define C_MUL(m,a,b) \
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
#define C_MULC(m,a,b) \
do{ (m).r = (a).r*(b).r + (a).i*(b).i;\
(m).i = (a).i*(b).r - (a).r*(b).i; }while(0)
#define C_MUL4(m,a,b) C_MUL(m,a,b)
# define C_FIXDIV(c,div) /* NOOP */
# define C_MULBYSCALAR( c, s ) \
do{ (c).r *= (s);\
(c).i *= (s); }while(0)
#endif
#ifndef CHECK_OVERFLOW_OP
# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
#endif
#ifndef C_ADD
#define C_ADD( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,+,(b).r)\
CHECK_OVERFLOW_OP((a).i,+,(b).i)\
(res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
}while(0)
#define C_SUB( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,-,(b).r)\
CHECK_OVERFLOW_OP((a).i,-,(b).i)\
(res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
}while(0)
#define C_ADDTO( res , a)\
do { \
CHECK_OVERFLOW_OP((res).r,+,(a).r)\
CHECK_OVERFLOW_OP((res).i,+,(a).i)\
(res).r += (a).r; (res).i += (a).i;\
}while(0)
#define C_SUBFROM( res , a)\
do {\
CHECK_OVERFLOW_OP((res).r,-,(a).r)\
CHECK_OVERFLOW_OP((res).i,-,(a).i)\
(res).r -= (a).r; (res).i -= (a).i; \
}while(0)
#endif /* C_ADD defined */
#ifdef OPUS_FIXED_POINT
# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))
# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase))
# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase))
# define HALF_OF(x) ((x)>>1)
#elif defined(USE_SIMD)
# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
# define HALF_OF(x) ((x)*_mm_set1_ps(.5f))
#else
# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
# define HALF_OF(x) ((x)*.5f)
#endif
#define kf_cexp(x,phase) \
do{ \
(x)->r = KISS_FFT_COS(phase);\
(x)->i = KISS_FFT_SIN(phase);\
}while(0)
#define kf_cexp2(x,phase) \
do{ \
(x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\
(x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\
}while(0)
#endif /* KISS_FFT_GUTS_H */

214
drivers/opus/celt/arch.h Normal file
View file

@ -0,0 +1,214 @@
/* Copyright (c) 2003-2008 Jean-Marc Valin
Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file arch.h
@brief Various architecture definitions for CELT
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCH_H
#define ARCH_H
#include "opus_types.h"
#include "opus_defines.h"
# if !defined(__GNUC_PREREQ)
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
# define __GNUC_PREREQ(_maj,_min) \
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
# else
# define __GNUC_PREREQ(_maj,_min) 0
# endif
# endif
#define CELT_SIG_SCALE 32768.f
#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
#ifdef ENABLE_ASSERTIONS
#include <stdio.h>
#include <stdlib.h>
#ifdef __GNUC__
__attribute__((noreturn))
#endif
static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
{
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
abort();
}
#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}}
#else
#define celt_assert(cond)
#define celt_assert2(cond, message)
#endif
#define IMUL32(a,b) ((a)*(b))
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */
#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
#define UADD32(a,b) ((a)+(b))
#define USUB32(a,b) ((a)-(b))
#define PRINT_MIPS(file)
#ifdef OPUS_FIXED_POINT
typedef opus_int16 opus_val16;
typedef opus_int32 opus_val32;
typedef opus_val32 celt_sig;
typedef opus_val16 celt_norm;
typedef opus_val32 celt_ener;
#define Q15ONE 32767
#define SIG_SHIFT 12
#define NORM_SCALING 16384
#define DB_SHIFT 10
#define EPSILON 1
#define VERY_SMALL 0
#define VERY_LARGE16 ((opus_val16)32767)
#define Q15_ONE ((opus_val16)32767)
#define SCALEIN(a) (a)
#define SCALEOUT(a) (a)
#ifdef FIXED_DEBUG
#include "fixed_debug.h"
#else
#include "fixed_generic.h"
#ifdef OPUS_ARM_INLINE_EDSP
#include "arm/fixed_armv5e.h"
#elif defined (OPUS_ARM_INLINE_ASM)
#include "arm/fixed_armv4.h"
#elif defined (BFIN_ASM)
#include "fixed_bfin.h"
#elif defined (TI_C5X_ASM)
#include "fixed_c5x.h"
#elif defined (TI_C6X_ASM)
#include "fixed_c6x.h"
#endif
#endif
#else /* OPUS_FIXED_POINT */
typedef float opus_val16;
typedef float opus_val32;
typedef float celt_sig;
typedef float celt_norm;
typedef float celt_ener;
#define Q15ONE 1.0f
#define NORM_SCALING 1.f
#define EPSILON 1e-15f
#define VERY_SMALL 1e-30f
#define VERY_LARGE16 1e15f
#define Q15_ONE ((opus_val16)1.f)
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define EXTRACT16(x) (x)
#define EXTEND32(x) (x)
#define SHR16(a,shift) (a)
#define SHL16(a,shift) (a)
#define SHR32(a,shift) (a)
#define SHL32(a,shift) (a)
#define PSHR32(a,shift) (a)
#define VSHR32(a,shift) (a)
#define PSHR(a,shift) (a)
#define SHR(a,shift) (a)
#define SHL(a,shift) (a)
#define SATURATE(x,a) (x)
#define SATURATE16(x) (x)
#define ROUND16(a,shift) (a)
#define HALF16(x) (.5f*(x))
#define HALF32(x) (.5f*(x))
#define ADD16(a,b) ((a)+(b))
#define SUB16(a,b) ((a)-(b))
#define ADD32(a,b) ((a)+(b))
#define SUB32(a,b) ((a)-(b))
#define MULT16_16_16(a,b) ((a)*(b))
#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
#define MULT16_32_Q15(a,b) ((a)*(b))
#define MULT16_32_Q16(a,b) ((a)*(b))
#define MULT32_32_Q31(a,b) ((a)*(b))
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
#define MULT16_16_Q11_32(a,b) ((a)*(b))
#define MULT16_16_Q11(a,b) ((a)*(b))
#define MULT16_16_Q13(a,b) ((a)*(b))
#define MULT16_16_Q14(a,b) ((a)*(b))
#define MULT16_16_Q15(a,b) ((a)*(b))
#define MULT16_16_P15(a,b) ((a)*(b))
#define MULT16_16_P13(a,b) ((a)*(b))
#define MULT16_16_P14(a,b) ((a)*(b))
#define MULT16_32_P16(a,b) ((a)*(b))
#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b))
#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b))
#define SCALEIN(a) ((a)*CELT_SIG_SCALE)
#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE))
#endif /* !OPUS_FIXED_POINT */
#ifndef GLOBAL_STACK_SIZE
#ifdef OPUS_FIXED_POINT
#define GLOBAL_STACK_SIZE 100000
#else
#define GLOBAL_STACK_SIZE 100000
#endif
#endif
#endif /* ARCH_H */

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