diff options
Diffstat (limited to 'core')
54 files changed, 1559 insertions, 955 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index b4bf1ed4bd..94557d149d 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -732,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() { @@ -859,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 ); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index ed3db29259..24ea810767 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -256,6 +256,9 @@ public: 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; diff --git a/core/error_list.h b/core/error_list.h index 124027172e..92c417154c 100644 --- a/core/error_list.h +++ b/core/error_list.h @@ -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, diff --git a/core/error_macros.h b/core/error_macros.h index 18b08d8e0e..76da88287b 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -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;\ } \ diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 0e43112de8..66962710bd 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -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))); diff --git a/core/global_constants.cpp b/core/global_constants.cpp index b8d113f67c..9fb45c672a 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -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 ), diff --git a/core/globals.cpp b/core/globals.cpp index 731c5b7dff..ffd4cf5d5e 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -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; } diff --git a/core/image.cpp b/core/image.cpp index c31fa47847..06b7a78488 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -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; diff --git a/core/image.h b/core/image.h index 8ce4f22dc1..a155823af7 100644 --- a/core/image.h +++ b/core/image.h @@ -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(); diff --git a/core/io/aes256.cpp b/core/io/aes256.cpp index 69a5091f1d..e7f465dcc6 100644 --- a/core/io/aes256.cpp +++ b/core/io/aes256.cpp @@ -1,359 +1,359 @@ -/*
-* Byte-oriented AES-256 implementation.
-* All lookup tables replaced with 'on the fly' calculations.
-*
-* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
-* Other contributors: Hal Finney
-*
-* Permission to use, copy, modify, and distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-#include "aes256.h"
-
-#define F(x) (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b))
-#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
-
-// #define BACK_TO_TABLES
-#ifdef BACK_TO_TABLES
-
-const uint8_t sbox[256] = {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
- 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
- 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
- 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
- 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
- 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
- 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
- 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
- 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
- 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
- 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
- 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
- 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
- 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
- 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
- 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
- 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-const uint8_t sboxinv[256] = {
- 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
- 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
- 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
- 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
- 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
- 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
- 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
- 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
- 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
- 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
- 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
- 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
- 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
- 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
- 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
- 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
- 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
- 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
- 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
- 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
- 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
- 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
- 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
- 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-};
-
-#define rj_sbox(x) sbox[(x)]
-#define rj_sbox_inv(x) sboxinv[(x)]
-
-#else /* tableless subroutines */
-
-/* -------------------------------------------------------------------------- */
-uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
-{
- uint8_t atb = 1, z;
-
- while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;}
-
- return atb;
-} /* gf_alog */
-
-/* -------------------------------------------------------------------------- */
-uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
-{
- uint8_t atb = 1, i = 0, z;
-
- do {
- if (atb == x) break;
- z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;
- } while (++i > 0);
-
- return i;
-} /* gf_log */
-
-
-/* -------------------------------------------------------------------------- */
-uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
-{
- return (x) ? gf_alog(255 - gf_log(x)) : 0;
-} /* gf_mulinv */
-
-/* -------------------------------------------------------------------------- */
-uint8_t rj_sbox(uint8_t x)
-{
- uint8_t y, sb;
-
- sb = y = gf_mulinv(x);
- y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;
- y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;
-
- return (sb ^ 0x63);
-} /* rj_sbox */
-
-/* -------------------------------------------------------------------------- */
-uint8_t rj_sbox_inv(uint8_t x)
-{
- uint8_t y, sb;
-
- y = x ^ 0x63;
- sb = y = (y<<1)|(y>>7);
- y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y;
-
- return gf_mulinv(sb);
-} /* rj_sbox_inv */
-
-#endif
-
-/* -------------------------------------------------------------------------- */
-uint8_t rj_xtime(uint8_t x)
-{
- return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);
-} /* rj_xtime */
-
-/* -------------------------------------------------------------------------- */
-void aes_subBytes(uint8_t *buf)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] = rj_sbox(buf[i]);
-} /* aes_subBytes */
-
-/* -------------------------------------------------------------------------- */
-void aes_subBytes_inv(uint8_t *buf)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] = rj_sbox_inv(buf[i]);
-} /* aes_subBytes_inv */
-
-/* -------------------------------------------------------------------------- */
-void aes_addRoundKey(uint8_t *buf, uint8_t *key)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] ^= key[i];
-} /* aes_addRoundKey */
-
-/* -------------------------------------------------------------------------- */
-void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i];
-} /* aes_addRoundKey_cpy */
-
-
-/* -------------------------------------------------------------------------- */
-void aes_shiftRows(uint8_t *buf)
-{
- register uint8_t i, j; /* to make it potentially parallelable :) */
-
- i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i;
- i = buf[10]; buf[10] = buf[2]; buf[2] = i;
- j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j;
- j = buf[14]; buf[14] = buf[6]; buf[6] = j;
-
-} /* aes_shiftRows */
-
-/* -------------------------------------------------------------------------- */
-void aes_shiftRows_inv(uint8_t *buf)
-{
- register uint8_t i, j; /* same as above :) */
-
- i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i;
- i = buf[2]; buf[2] = buf[10]; buf[10] = i;
- j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j;
- j = buf[6]; buf[6] = buf[14]; buf[14] = j;
-
-} /* aes_shiftRows_inv */
-
-/* -------------------------------------------------------------------------- */
-void aes_mixColumns(uint8_t *buf)
-{
- register uint8_t i, a, b, c, d, e;
-
- for (i = 0; i < 16; i += 4)
- {
- a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];
- e = a ^ b ^ c ^ d;
- buf[i] ^= e ^ rj_xtime(a^b); buf[i+1] ^= e ^ rj_xtime(b^c);
- buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a);
- }
-} /* aes_mixColumns */
-
-/* -------------------------------------------------------------------------- */
-void aes_mixColumns_inv(uint8_t *buf)
-{
- register uint8_t i, a, b, c, d, e, x, y, z;
-
- for (i = 0; i < 16; i += 4)
- {
- a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];
- e = a ^ b ^ c ^ d;
- z = rj_xtime(e);
- x = e ^ rj_xtime(rj_xtime(z^a^c)); y = e ^ rj_xtime(rj_xtime(z^b^d));
- buf[i] ^= x ^ rj_xtime(a^b); buf[i+1] ^= y ^ rj_xtime(b^c);
- buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a);
- }
-} /* aes_mixColumns_inv */
-
-/* -------------------------------------------------------------------------- */
-void aes_expandEncKey(uint8_t *k, uint8_t *rc)
-{
- register uint8_t i;
-
- k[0] ^= rj_sbox(k[29]) ^ (*rc);
- k[1] ^= rj_sbox(k[30]);
- k[2] ^= rj_sbox(k[31]);
- k[3] ^= rj_sbox(k[28]);
- *rc = F( *rc);
-
- for(i = 4; i < 16; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
- k[16] ^= rj_sbox(k[12]);
- k[17] ^= rj_sbox(k[13]);
- k[18] ^= rj_sbox(k[14]);
- k[19] ^= rj_sbox(k[15]);
-
- for(i = 20; i < 32; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
-
-} /* aes_expandEncKey */
-
-/* -------------------------------------------------------------------------- */
-void aes_expandDecKey(uint8_t *k, uint8_t *rc)
-{
- uint8_t i;
-
- for(i = 28; i > 16; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
-
- k[16] ^= rj_sbox(k[12]);
- k[17] ^= rj_sbox(k[13]);
- k[18] ^= rj_sbox(k[14]);
- k[19] ^= rj_sbox(k[15]);
-
- for(i = 12; i > 0; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
-
- *rc = FD(*rc);
- k[0] ^= rj_sbox(k[29]) ^ (*rc);
- k[1] ^= rj_sbox(k[30]);
- k[2] ^= rj_sbox(k[31]);
- k[3] ^= rj_sbox(k[28]);
-} /* aes_expandDecKey */
-
-
-/* -------------------------------------------------------------------------- */
-void aes256_init(aes256_context *ctx, uint8_t *k)
-{
- uint8_t rcon = 1;
- register uint8_t i;
-
- for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
- for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon);
-} /* aes256_init */
-
-/* -------------------------------------------------------------------------- */
-void aes256_done(aes256_context *ctx)
-{
- register uint8_t i;
-
- for (i = 0; i < sizeof(ctx->key); i++)
- ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
-} /* aes256_done */
-
-/* -------------------------------------------------------------------------- */
-void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
-{
- uint8_t i, rcon;
-
- aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
- for(i = 1, rcon = 1; i < 14; ++i)
- {
- aes_subBytes(buf);
- aes_shiftRows(buf);
- aes_mixColumns(buf);
- if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);
- else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
- }
- aes_subBytes(buf);
- aes_shiftRows(buf);
- aes_expandEncKey(ctx->key, &rcon);
- aes_addRoundKey(buf, ctx->key);
-} /* aes256_encrypt */
-
-/* -------------------------------------------------------------------------- */
-void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
-{
- uint8_t i, rcon;
-
- aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
- aes_shiftRows_inv(buf);
- aes_subBytes_inv(buf);
-
- for (i = 14, rcon = 0x80; --i;)
- {
- if( ( i & 1 ) )
- {
- aes_expandDecKey(ctx->key, &rcon);
- aes_addRoundKey(buf, &ctx->key[16]);
- }
- else aes_addRoundKey(buf, ctx->key);
- aes_mixColumns_inv(buf);
- aes_shiftRows_inv(buf);
- aes_subBytes_inv(buf);
- }
- aes_addRoundKey( buf, ctx->key);
-} /* aes256_decrypt */
+/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com +* Other contributors: Hal Finney +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#include "aes256.h" + +#define F(x) (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b)) +#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0)) + +// #define BACK_TO_TABLES +#ifdef BACK_TO_TABLES + +const uint8_t sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; +const uint8_t sboxinv[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; + +#define rj_sbox(x) sbox[(x)] +#define rj_sbox_inv(x) sboxinv[(x)] + +#else /* tableless subroutines */ + +/* -------------------------------------------------------------------------- */ +uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3 +{ + uint8_t atb = 1, z; + + while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;} + + return atb; +} /* gf_alog */ + +/* -------------------------------------------------------------------------- */ +uint8_t gf_log(uint8_t x) // calculate logarithm gen 3 +{ + uint8_t atb = 1, i = 0, z; + + do { + if (atb == x) break; + z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z; + } while (++i > 0); + + return i; +} /* gf_log */ + + +/* -------------------------------------------------------------------------- */ +uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse +{ + return (x) ? gf_alog(255 - gf_log(x)) : 0; +} /* gf_mulinv */ + +/* -------------------------------------------------------------------------- */ +uint8_t rj_sbox(uint8_t x) +{ + uint8_t y, sb; + + sb = y = gf_mulinv(x); + y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y; + y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y; + + return (sb ^ 0x63); +} /* rj_sbox */ + +/* -------------------------------------------------------------------------- */ +uint8_t rj_sbox_inv(uint8_t x) +{ + uint8_t y, sb; + + y = x ^ 0x63; + sb = y = (y<<1)|(y>>7); + y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y; + + return gf_mulinv(sb); +} /* rj_sbox_inv */ + +#endif + +/* -------------------------------------------------------------------------- */ +uint8_t rj_xtime(uint8_t x) +{ + return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1); +} /* rj_xtime */ + +/* -------------------------------------------------------------------------- */ +void aes_subBytes(uint8_t *buf) +{ + register uint8_t i = 16; + + while (i--) buf[i] = rj_sbox(buf[i]); +} /* aes_subBytes */ + +/* -------------------------------------------------------------------------- */ +void aes_subBytes_inv(uint8_t *buf) +{ + register uint8_t i = 16; + + while (i--) buf[i] = rj_sbox_inv(buf[i]); +} /* aes_subBytes_inv */ + +/* -------------------------------------------------------------------------- */ +void aes_addRoundKey(uint8_t *buf, uint8_t *key) +{ + register uint8_t i = 16; + + while (i--) buf[i] ^= key[i]; +} /* aes_addRoundKey */ + +/* -------------------------------------------------------------------------- */ +void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk) +{ + register uint8_t i = 16; + + while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i]; +} /* aes_addRoundKey_cpy */ + + +/* -------------------------------------------------------------------------- */ +void aes_shiftRows(uint8_t *buf) +{ + register uint8_t i, j; /* to make it potentially parallelable :) */ + + i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i; + i = buf[10]; buf[10] = buf[2]; buf[2] = i; + j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j; + j = buf[14]; buf[14] = buf[6]; buf[6] = j; + +} /* aes_shiftRows */ + +/* -------------------------------------------------------------------------- */ +void aes_shiftRows_inv(uint8_t *buf) +{ + register uint8_t i, j; /* same as above :) */ + + i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i; + i = buf[2]; buf[2] = buf[10]; buf[10] = i; + j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j; + j = buf[6]; buf[6] = buf[14]; buf[14] = j; + +} /* aes_shiftRows_inv */ + +/* -------------------------------------------------------------------------- */ +void aes_mixColumns(uint8_t *buf) +{ + register uint8_t i, a, b, c, d, e; + + for (i = 0; i < 16; i += 4) + { + a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3]; + e = a ^ b ^ c ^ d; + buf[i] ^= e ^ rj_xtime(a^b); buf[i+1] ^= e ^ rj_xtime(b^c); + buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a); + } +} /* aes_mixColumns */ + +/* -------------------------------------------------------------------------- */ +void aes_mixColumns_inv(uint8_t *buf) +{ + register uint8_t i, a, b, c, d, e, x, y, z; + + for (i = 0; i < 16; i += 4) + { + a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3]; + e = a ^ b ^ c ^ d; + z = rj_xtime(e); + x = e ^ rj_xtime(rj_xtime(z^a^c)); y = e ^ rj_xtime(rj_xtime(z^b^d)); + buf[i] ^= x ^ rj_xtime(a^b); buf[i+1] ^= y ^ rj_xtime(b^c); + buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a); + } +} /* aes_mixColumns_inv */ + +/* -------------------------------------------------------------------------- */ +void aes_expandEncKey(uint8_t *k, uint8_t *rc) +{ + register uint8_t i; + + k[0] ^= rj_sbox(k[29]) ^ (*rc); + k[1] ^= rj_sbox(k[30]); + k[2] ^= rj_sbox(k[31]); + k[3] ^= rj_sbox(k[28]); + *rc = F( *rc); + + for(i = 4; i < 16; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + k[16] ^= rj_sbox(k[12]); + k[17] ^= rj_sbox(k[13]); + k[18] ^= rj_sbox(k[14]); + k[19] ^= rj_sbox(k[15]); + + for(i = 20; i < 32; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + +} /* aes_expandEncKey */ + +/* -------------------------------------------------------------------------- */ +void aes_expandDecKey(uint8_t *k, uint8_t *rc) +{ + uint8_t i; + + for(i = 28; i > 16; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + + k[16] ^= rj_sbox(k[12]); + k[17] ^= rj_sbox(k[13]); + k[18] ^= rj_sbox(k[14]); + k[19] ^= rj_sbox(k[15]); + + for(i = 12; i > 0; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3], + k[i+2] ^= k[i-2], k[i+3] ^= k[i-1]; + + *rc = FD(*rc); + k[0] ^= rj_sbox(k[29]) ^ (*rc); + k[1] ^= rj_sbox(k[30]); + k[2] ^= rj_sbox(k[31]); + k[3] ^= rj_sbox(k[28]); +} /* aes_expandDecKey */ + + +/* -------------------------------------------------------------------------- */ +void aes256_init(aes256_context *ctx, uint8_t *k) +{ + uint8_t rcon = 1; + register uint8_t i; + + for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i]; + for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon); +} /* aes256_init */ + +/* -------------------------------------------------------------------------- */ +void aes256_done(aes256_context *ctx) +{ + register uint8_t i; + + for (i = 0; i < sizeof(ctx->key); i++) + ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0; +} /* aes256_done */ + +/* -------------------------------------------------------------------------- */ +void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf) +{ + uint8_t i, rcon; + + aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key); + for(i = 1, rcon = 1; i < 14; ++i) + { + aes_subBytes(buf); + aes_shiftRows(buf); + aes_mixColumns(buf); + if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]); + else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key); + } + aes_subBytes(buf); + aes_shiftRows(buf); + aes_expandEncKey(ctx->key, &rcon); + aes_addRoundKey(buf, ctx->key); +} /* aes256_encrypt */ + +/* -------------------------------------------------------------------------- */ +void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf) +{ + uint8_t i, rcon; + + aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key); + aes_shiftRows_inv(buf); + aes_subBytes_inv(buf); + + for (i = 14, rcon = 0x80; --i;) + { + if( ( i & 1 ) ) + { + aes_expandDecKey(ctx->key, &rcon); + aes_addRoundKey(buf, &ctx->key[16]); + } + else aes_addRoundKey(buf, ctx->key); + aes_mixColumns_inv(buf); + aes_shiftRows_inv(buf); + aes_subBytes_inv(buf); + } + aes_addRoundKey( buf, ctx->key); +} /* aes256_decrypt */ diff --git a/core/io/aes256.h b/core/io/aes256.h index 180352e970..fabbcf1968 100644 --- a/core/io/aes256.h +++ b/core/io/aes256.h @@ -1,46 +1,46 @@ -/*
-* Byte-oriented AES-256 implementation.
-* All lookup tables replaced with 'on the fly' calculations.
-*
-* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
-* Other contributors: Hal Finney
-*
-* Permission to use, copy, modify, and distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#ifndef AES_256_H
-#define AES_256_H
-
-#include "typedefs.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- typedef struct {
- uint8_t key[32];
- uint8_t enckey[32];
- uint8_t deckey[32];
- } aes256_context;
-
-
- void aes256_init(aes256_context *, uint8_t * /* key */);
- void aes256_done(aes256_context *);
- void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */);
- void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com +* Other contributors: Hal Finney +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef AES_256_H +#define AES_256_H + +#include "typedefs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + uint8_t key[32]; + uint8_t enckey[32]; + uint8_t deckey[32]; + } aes256_context; + + + void aes256_init(aes256_context *, uint8_t * /* key */); + void aes256_done(aes256_context *); + void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */); + void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 0bc006b41e..729b7bec52 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -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) { diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index d3390ae199..2db6e00f0a 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -50,8 +50,10 @@ 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,15 +64,20 @@ 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); diff --git a/core/io/ioapi.h b/core/io/ioapi.h index a13d7ba621..24bf612617 100644 --- a/core/io/ioapi.h +++ b/core/io/ioapi.h @@ -40,7 +40,6 @@ #endif #include <stdio.h> -#include <stdlib.h> #include "zlib.h" #if defined(USE_FILE32API) diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index b0d24abfe3..62ccd81489 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -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; - ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + 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; diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 875cace368..f6d526b512 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -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; @@ -202,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size) uint8_t lbuf[4]; ring_buffer.copy(lbuf,0,4); remaining-=4; - uint32_t len = decode_uint32(lbuf); + uint32_t len = decode_uint32(lbuf); ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE); ring_buffer.read(lbuf,4); //get rid of first 4 bytes diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index c6cf631de6..1a0552e8d1 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -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 }; @@ -375,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index=f->get_32(); - String path = res_path+"::"+itos(index); + String path = res_path+"::"+itos(index); RES res = ResourceLoader::load(path); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); @@ -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,6 +398,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { } + if (remaps.find(path)) { + path=remaps[path]; + } + RES res=ResourceLoader::load(path,type); if (res.is_null()) { @@ -402,6 +410,34 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { 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: { ERR_FAIL_V(ERR_FILE_CORRUPT); @@ -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()); + + for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) { + save_order[E->get()]=E->key(); + } - save_unicode_string(E->get()->get_save_type()); - String path = E->get()->get_path(); + 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; +} diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index da415d97a5..8bf20bc574 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -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(); }; diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index b744cbf967..66ae014dbc 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -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,10 +485,31 @@ 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(); if (err) { ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error closing <resource> 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("&","&"); - p_str=p_str.replace("<",">"); - p_str=p_str.replace(">","<"); + p_str=p_str.replace("<","<"); + p_str=p_str.replace(">",">"); p_str=p_str.replace("'","'"); p_str=p_str.replace("\"","""); for (char i=1;i<32;i++) { @@ -2024,20 +2228,26 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V return; // don't save it } - params="resource_type=\""+res->get_save_type()+"\""; + if (external_resources.has(res)) { - 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(); - escape(path); - params+=" path=\""+path+"\""; + params="external=\""+itos(external_resources[res])+"\""; } else { + params="resource_type=\""+res->get_save_type()+"\""; - //internal resource - ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); - ERR_FAIL_COND(!resource_set.has(res)); - params+=" path=\"local://"+itos(res->get_subindex())+"\""; + 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(); + escape(path); + params+=" path=\""+path+"\""; + } else { + + //internal resource + ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); + ERR_FAIL_COND(!resource_set.has(res)); + + params+=" path=\"local://"+itos(res->get_subindex())+"\""; + } } } 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; +} diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h index d5ba9eb800..77987c6a5b 100644 --- a/core/io/resource_format_xml.h +++ b/core/io/resource_format_xml.h @@ -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(); }; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 22d89840ae..3862790b02 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -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,32 @@ 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; + 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; + + 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; @@ -372,11 +406,15 @@ 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); + 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; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index d25727f19f..00a05dcb43 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -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; } }; diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 05cbe7f98e..8382b65290 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -46,7 +46,7 @@ public: virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0; virtual bool recognize(const RES& p_resource) const=0; virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0; - + virtual ~ResourceFormatSaver() {} }; diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index c32b25c407..020d168208 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -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; diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 9d8ad97a29..e07ae15e28 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -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; diff --git a/core/io/unzip.c b/core/io/unzip.c index 0cd975211e..b438021ad7 100644 --- a/core/io/unzip.c +++ b/core/io/unzip.c @@ -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; diff --git a/core/io/zip.c b/core/io/zip.c index 8f6aeb922f..c4ab93ab81 100644 --- a/core/io/zip.c +++ b/core/io/zip.c @@ -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; diff --git a/core/io/zip.h b/core/io/zip.h index cca06c2ee8..85f93568c9 100644 --- a/core/io/zip.h +++ b/core/io/zip.h @@ -39,6 +39,8 @@ #ifndef _zip12_H #define _zip12_H +#include <stdlib.h> + #ifdef __cplusplus extern "C" { #endif diff --git a/core/io/zip_io.h b/core/io/zip_io.h index c4b4d6b34d..dd3c371a4a 100644 --- a/core/io/zip_io.h +++ b/core/io/zip_io.h @@ -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; diff --git a/core/list.h b/core/list.h index 6deb150ef6..018abca940 100644 --- a/core/list.h +++ b/core/list.h @@ -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) { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 33175ed2fc..ec089ebc8b 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -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); diff --git a/core/math/quat.h b/core/math/quat.h index de4aedaeec..f161e35074 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -73,7 +73,7 @@ public: -x * v.x - y * v.y - z * v.z); } - _FORCE_INLINE_ Vector3 xform(const Vector3& v) { + _FORCE_INLINE_ Vector3 xform(const Vector3& v) const { Quat q = *this * v; q *= this->inverse(); diff --git a/core/math/vector3.h b/core/math/vector3.h index d27b611379..8a3cca8f33 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -40,11 +40,11 @@ struct Vector3 { enum Axis { AXIS_X, AXIS_Y, - AXIS_Z, + AXIS_Z, }; union { - + #ifdef USE_QUAD_VECTORS struct { @@ -52,7 +52,7 @@ struct Vector3 { real_t y; real_t z; real_t _unused; - }; + }; real_t coord[4]; #else @@ -61,18 +61,18 @@ struct Vector3 { real_t y; real_t z; }; - + real_t coord[3]; #endif }; _FORCE_INLINE_ const real_t& operator[](int p_axis) const { - + return coord[p_axis]; } _FORCE_INLINE_ real_t& operator[](int p_axis) { - + return coord[p_axis]; } @@ -84,7 +84,7 @@ struct Vector3 { _FORCE_INLINE_ real_t length() const; _FORCE_INLINE_ real_t length_squared() const; - + _FORCE_INLINE_ void normalize(); _FORCE_INLINE_ Vector3 normalized() const; _FORCE_INLINE_ Vector3 inverse() const; @@ -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; @@ -172,7 +174,17 @@ real_t Vector3::dot(const Vector3& p_b) const { 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 { @@ -301,7 +313,7 @@ bool Vector3::operator<(const Vector3& p_v) const { return y<p_v.y; } else return x<p_v.x; - + } bool Vector3::operator<=(const Vector3& p_v) const { diff --git a/core/object.h b/core/object.h index eb0e78a8c3..981a83958c 100644 --- a/core/object.h +++ b/core/object.h @@ -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) @@ -58,12 +58,12 @@ enum PropertyHint { PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_ALL_FLAGS, - PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," + PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," PROPERTY_HINT_DIR, ///< a directort path must be passed PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type - PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines + PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color PROPERTY_HINT_IMAGE_COMPRESS_LOSSY, PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS, @@ -71,7 +71,7 @@ enum PropertyHint { }; enum PropertyUsageFlags { - + PROPERTY_USAGE_STORAGE=1, PROPERTY_USAGE_EDITOR=2, PROPERTY_USAGE_NETWORK=4, @@ -102,15 +102,15 @@ enum PropertyUsageFlags { #define ADD_PROPERTYINO( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), m_setter, m_getter, m_index ) struct PropertyInfo { - - Variant::Type type; + + Variant::Type type; String name; PropertyHint hint; - String hint_string; + String hint_string; uint32_t usage; _FORCE_INLINE_ PropertyInfo added_usage(int p_fl) const { PropertyInfo pi=*this; pi.usage|=p_fl; return pi; } - + PropertyInfo() { type=Variant::NIL; hint=PROPERTY_HINT_NONE; usage = PROPERTY_USAGE_DEFAULT; } PropertyInfo( Variant::Type p_type, const String p_name, PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_string="",uint32_t p_usage=PROPERTY_USAGE_DEFAULT) { type=p_type; name=p_name; hint=p_hint; hint_string=p_hint_string; usage=p_usage; @@ -125,23 +125,23 @@ struct PropertyInfo { Array convert_property_list(const List<PropertyInfo> * p_list); struct MethodInfo { - + String name; List<PropertyInfo> arguments; Vector<Variant> default_arguments; PropertyInfo return_val; uint32_t flags; int id; - + inline bool operator<(const MethodInfo& p_method) const { return id==p_method.id?(name < p_method.name):(id<p_method.id); } - + MethodInfo(); MethodInfo(const String& p_name); MethodInfo(const String& p_name, const PropertyInfo& p_param1); MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2); MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3); MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3,const PropertyInfo& p_param4); - MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3,const PropertyInfo& p_param4,const PropertyInfo& p_param5); + MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3,const PropertyInfo& p_param4,const PropertyInfo& p_param5); MethodInfo(Variant::Type ret); MethodInfo(Variant::Type ret,const String& p_name); MethodInfo(Variant::Type ret,const String& p_name, const PropertyInfo& p_param1); @@ -158,7 +158,7 @@ struct MethodInfo { //return NULL; /* - the following is an uncomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. + the following is an uncomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. */ #define REVERSE_GET_PROPERTY_LIST \ @@ -314,7 +314,7 @@ private: class ScriptInstance; typedef uint32_t ObjectID; -class Object { +class Object { public: enum ConnectFlags { @@ -404,7 +404,7 @@ friend void postinitialize_handler(Object*); void property_list_changed_notify(); -protected: +protected: virtual bool _use_builtin_script() const { return false; } virtual void _initialize_typev() { initialize_type(); } @@ -412,14 +412,14 @@ protected: virtual bool _getv(const StringName& p_name,Variant &r_property) const { return false; }; virtual void _get_property_listv(List<PropertyInfo> *p_list,bool p_reversed) const {}; virtual void _notificationv(int p_notification,bool p_reversed) {}; - + static String _get_category() { return ""; } static void _bind_methods(); bool _set(const StringName& p_name,const Variant &p_property) { return false; }; bool _get(const StringName& p_name,Variant &r_property) const { return false; }; void _get_property_list(List<PropertyInfo> *p_list) const {}; void _notification(int p_notification) {}; - + _FORCE_INLINE_ static void (*_get_bind_methods())() { return &Object::_bind_methods; } @@ -431,13 +431,13 @@ protected: } _FORCE_INLINE_ void (Object::* (_get_get_property_list() const))(List<PropertyInfo> *p_list) const{ return &Object::_get_property_list; - } + } _FORCE_INLINE_ void (Object::* (_get_notification() const))(int){ return &Object::_notification; - } + } static void get_valid_parents_static(List<String> *p_parents); static void _get_valid_parents_static(List<String> *p_parents); - + void cancel_delete(); @@ -485,7 +485,7 @@ public: void add_change_receptor( Object *p_receptor ); void remove_change_receptor( Object *p_receptor ); - + template<class T> T *cast_to() { @@ -500,7 +500,7 @@ public: return NULL; #endif } - + template<class T> const T *cast_to() const { @@ -517,11 +517,11 @@ public: } enum { - + NOTIFICATION_POSTINITIALIZE=0, NOTIFICATION_PREDELETE=1 }; - + /* TYPE API */ static void get_inheritance_list_static(List<String>* p_inheritance_list) { p_inheritance_list->push_back("Object"); } @@ -545,7 +545,7 @@ public: return *_type_ptr; } } - + /* IAPI */ // void set(const String& p_name, const Variant& p_value); // Variant get(const String& p_name) const; @@ -554,7 +554,7 @@ public: Variant get(const StringName& p_name, bool *r_valid=NULL) const; void get_property_list(List<PropertyInfo> *p_list,bool p_reversed=false) const; - + bool has_method(const StringName& p_method) const; void get_method_list(List<MethodInfo> *p_list) const; Variant callv(const StringName& p_method,const Array& p_args); @@ -564,14 +564,14 @@ public: Variant call(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper void call_multilevel(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper - void notification(int p_notification,bool p_reversed=false); + void notification(int p_notification,bool p_reversed=false); //used mainly by script, get and set all INCLUDING string virtual Variant getvar(const Variant& p_key, bool *r_valid=NULL) const; virtual void setvar(const Variant& p_key, const Variant& p_value,bool *r_valid=NULL); /* SCRIPT */ - + void set_script(const RefPtr& p_script); RefPtr get_script() const; @@ -614,14 +614,14 @@ public: StringName tr(const StringName& p_message) const; //translate message (alternative) bool _is_queued_for_deletion; // set to true by SceneTree::queue_delete() - bool is_queued_for_deletion() const; + bool is_queued_for_deletion() const; _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate=p_enable; } _FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; } void clear_internal_resource_paths(); - Object(); + Object(); virtual ~Object(); }; @@ -649,13 +649,13 @@ class ObjectDB { static HashMap<Object*,ObjectID,ObjectPtrHash> instance_checks; static uint32_t instance_counter; -friend class Object; +friend class Object; friend void unregister_core_types(); static void cleanup(); static uint32_t add_instance(Object *p_object); static void remove_instance(Object *p_object); -public: +public: typedef void (*DebugFunc)(Object *p_obj); diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index c291714573..a64b3d2715 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -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; diff --git a/core/object_type_db.h b/core/object_type_db.h index caa5baddd5..bfa0f921e5 100644 --- a/core/object_type_db.h +++ b/core/object_type_db.h @@ -475,7 +475,9 @@ public: static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false); 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); diff --git a/core/os/input.cpp b/core/os/input.cpp index 2b939ede46..15872d02fd 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -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; -} diff --git a/core/os/input.h b/core/os/input.h index ce14c2166e..8aa0e6b18a 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -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 diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index b4c02ddbce..c37c281fb9 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -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); diff --git a/core/os/main_loop.h b/core/os/main_loop.h index bf9fe83a43..c5d58120c5 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -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, diff --git a/core/os/os.cpp b/core/os/os.cpp index efcd492230..8caf95e4d1 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -31,7 +31,7 @@ #include <stdarg.h> #include "dir_access.h" #include "globals.h" - +#include "input.h" OS* OS::singleton=NULL; @@ -61,9 +61,16 @@ void OS::debug_break() { void OS::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) { + const char* err_type; + switch(p_type) { + case ERR_ERROR: err_type="**ERROR**"; break; + case ERR_WARNING: err_type="**WARNING**"; break; + case ERR_SCRIPT: err_type="**SCRIPT ERROR**"; break; + } + if (p_rationale && *p_rationale) - print("**ERROR**: %s\n ",p_rationale); - print("**ERROR**: At: %s:%i:%s() - %s\n",p_file,p_line,p_function,p_code); + print("%s: %s\n ",err_type,p_rationale); + print("%s: At: %s:%i:%s() - %s\n",err_type,p_file,p_line,p_function,p_code); } void OS::print(const char* p_format, ...) { @@ -363,7 +370,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 { @@ -516,6 +523,7 @@ OS::OS() { _target_fps=0; _render_thread_mode=RENDER_THREAD_SAFE; _time_scale=1.0; + _pixel_snap=false; Math::seed(1234567); } diff --git a/core/os/os.h b/core/os/os.h index e8ecfa1054..e5338b4a02 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -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) {} @@ -393,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(); diff --git a/core/path_db.cpp b/core/path_db.cpp index d3dc3aceb8..c6ea25d966 100644 --- a/core/path_db.cpp +++ b/core/path_db.cpp @@ -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; diff --git a/core/path_db.h b/core/path_db.h index b4f13d50be..de84216006 100644 --- a/core/path_db.h +++ b/core/path_db.h @@ -84,7 +84,10 @@ public: bool operator==(const NodePath& p_path) const; 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); diff --git a/core/resource.h b/core/resource.h index 9d9c445e1d..3596abe673 100644 --- a/core/resource.h +++ b/core/resource.h @@ -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); diff --git a/core/ring_buffer.h b/core/ring_buffer.h index de33de0c76..3cf9cf9064 100644 --- a/core/ring_buffer.h +++ b/core/ring_buffer.h @@ -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() { diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index d42f879441..d72c9f7532 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -31,6 +31,28 @@ #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) { @@ -248,6 +270,9 @@ 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]; @@ -531,6 +556,9 @@ 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]; @@ -652,6 +680,8 @@ 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(); diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index c2642782a9..973fa23212 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -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; @@ -90,6 +93,7 @@ class ScriptDebuggerRemote : public ScriptDebugger { RequestSceneTreeMessageFunc request_scene_tree; void *request_scene_tree_ud; + void _send_video_memory(); LiveEditFuncs *live_edit_funcs; ErrorHandlerList eh; @@ -98,6 +102,20 @@ class ScriptDebuggerRemote : public ScriptDebugger { 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(); diff --git a/core/typedefs.h b/core/typedefs.h index ae1eb1f5e7..6ca31fd137 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -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_ diff --git a/core/ustring.cpp b/core/ustring.cpp index 3cfc1e4a3c..7582376fe0 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -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("&","&"); - str=str.replace("<",">"); - str=str.replace(">","<"); + str=str.replace("<","<"); + str=str.replace(">",">"); if (p_escape_quotes) { str=str.replace("'","'"); str=str.replace("\"","""); @@ -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]==';') { diff --git a/core/ustring.h b/core/ustring.h index 1000c1cc8a..fa25a07eb0 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -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; diff --git a/core/variant.cpp b/core/variant.cpp index e0bceb4dd8..c6a55b10e6 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -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; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 4cca3420a1..7bbb18225d 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -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); @@ -407,6 +409,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM0R(Quat,normalized); VCALL_LOCALMEM0R(Quat,inverse); VCALL_LOCALMEM1R(Quat,dot); + VCALL_LOCALMEM1R(Quat,xform); VCALL_LOCALMEM2R(Quat,slerp); VCALL_LOCALMEM2R(Quat,slerpni); VCALL_LOCALMEM4R(Quat,cubic_slerp); @@ -753,7 +756,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var } static void Matrix32_init2(Variant& r_ret,const Variant** p_args) { - + Matrix32 m(*p_args[0], *p_args[1]); r_ret=m; } @@ -1133,7 +1136,7 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { if (fd.returns) ret.name="ret"; mi.return_val=ret; -#endif +#endif p_list->push_back(mi); } @@ -1336,6 +1339,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()); @@ -1357,6 +1362,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC0(QUAT,QUAT,Quat,normalized,varray()); ADDFUNC0(QUAT,QUAT,Quat,inverse,varray()); ADDFUNC1(QUAT,REAL,Quat,dot,QUAT,"b",varray()); + ADDFUNC1(QUAT,VECTOR3,Quat,xform,VECTOR3,"v",varray()); ADDFUNC2(QUAT,QUAT,Quat,slerp,QUAT,"b",REAL,"t",varray()); ADDFUNC2(QUAT,QUAT,Quat,slerpni,QUAT,"b",REAL,"t",varray()); ADDFUNC4(QUAT,QUAT,Quat,cubic_slerp,QUAT,"b",QUAT,"pre_a",QUAT,"post_b",REAL,"t",varray()); @@ -1535,10 +1541,10 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(TRANSFORM,NIL,Transform,xform,NIL,"v",varray()); ADDFUNC1(TRANSFORM,NIL,Transform,xform_inv,NIL,"v",varray()); -#ifdef DEBUG_ENABLED +#ifdef DEBUG_ENABLED _VariantCall::type_funcs[Variant::TRANSFORM].functions["xform"].returns=true; _VariantCall::type_funcs[Variant::TRANSFORM].functions["xform_inv"].returns=true; -#endif +#endif ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_pressed,varray()); ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action,STRING,"action",varray()); @@ -1635,9 +1641,3 @@ void unregister_variant_methods() { } - - - - - - diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 1cdf6d7319..eabd647837 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -586,7 +586,21 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& } break; DEFAULT_OP_LOCALMEM_NUM(*,VECTOR3,Vector3); DEFAULT_OP_FAIL(PLANE); - DEFAULT_OP_FAIL(QUAT); + case QUAT: { + + switch(p_b.type) { + case VECTOR3: { + + _RETURN( reinterpret_cast<const Quat*>(p_a._data._mem)->xform( *(const Vector3*)p_b._data._mem) ); + } break; + case QUAT: { + + _RETURN( *reinterpret_cast<const Quat*>(p_a._data._mem) * *reinterpret_cast<const Quat*>(p_b._data._mem) ); + } break; + }; + r_valid=false; + return; + } break; DEFAULT_OP_FAIL(_AABB); case MATRIX3: { @@ -2573,7 +2587,7 @@ bool Variant::in(const Variant& p_index, bool *r_valid) const { String idx=p_index; const String *str=reinterpret_cast<const String*>(_data._mem); - return str->find("idx")!=-1; + return str->find(idx)!=-1; } } break; |