diff options
Diffstat (limited to 'core')
58 files changed, 3929 insertions, 61 deletions
diff --git a/core/array.cpp b/core/array.cpp index fef0fcbb40..1d283a14aa 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -155,6 +155,37 @@ int Array::find(const Variant& p_value) const { return _p->array.find(p_value); } +int Array::find_last(const Variant& p_value) const { + + if(_p->array.size() == 0) + return -1; + + for (int i=_p->array.size()-1; i>=0; i--) { + + if(_p->array[i] == p_value){ + return i; + }; + }; + + return -1; +} + +int Array::count(const Variant& p_value) const { + + if(_p->array.size() == 0) + return 0; + + int amount=0; + for (int i=0; i<_p->array.size(); i++) { + + if(_p->array[i] == p_value){ + amount++; + }; + }; + + return amount; +} + void Array::remove(int p_pos) { _p->array.remove(p_pos); diff --git a/core/array.h b/core/array.h index ecb91b69dc..9472a6dd21 100644 --- a/core/array.h +++ b/core/array.h @@ -72,6 +72,8 @@ public: void invert(); int find(const Variant& p_value) const; + int find_last(const Variant& p_value) const; + int count(const Variant& p_value) const; void erase(const Variant& p_value); diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 45d089599b..31c0c0e208 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -226,6 +226,11 @@ Size2 _OS::get_screen_size(int p_screen) const { return OS::get_singleton()->get_screen_size(p_screen); } +int _OS::get_screen_dpi(int p_screen) const { + + return OS::get_singleton()->get_screen_dpi(p_screen); +} + Point2 _OS::get_window_position() const { return OS::get_singleton()->get_window_position(); } @@ -431,6 +436,15 @@ Error _OS::set_thread_name(const String& p_name) { return Thread::set_name(p_name); }; +void _OS::set_use_vsync(bool p_enable) { + OS::get_singleton()->set_use_vsync(p_enable); +} + +bool _OS::is_vsnc_enabled() const { + + return OS::get_singleton()->is_vsnc_enabled(); +} + /* enum Weekday { @@ -500,9 +514,9 @@ void _OS::set_icon(const Image& p_icon) { } /** - * Get current datetime with consideration for utc and + * Get current datetime with consideration for utc and * dst - */ + */ Dictionary _OS::get_datetime(bool utc) const { Dictionary dated = get_date(utc); @@ -564,17 +578,17 @@ uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { // Get all time values from the dictionary, set to zero if it doesn't exist. // Risk incorrect calculation over throwing errors - unsigned int second = ((datetime.has(SECOND_KEY))? + unsigned int second = ((datetime.has(SECOND_KEY))? static_cast<unsigned int>(datetime[SECOND_KEY]): 0); - unsigned int minute = ((datetime.has(MINUTE_KEY))? + unsigned int minute = ((datetime.has(MINUTE_KEY))? static_cast<unsigned int>(datetime[MINUTE_KEY]): 0); - unsigned int hour = ((datetime.has(HOUR_KEY))? + unsigned int hour = ((datetime.has(HOUR_KEY))? static_cast<unsigned int>(datetime[HOUR_KEY]): 0); - unsigned int day = ((datetime.has(DAY_KEY))? + unsigned int day = ((datetime.has(DAY_KEY))? static_cast<unsigned int>(datetime[DAY_KEY]): 0); - unsigned int month = ((datetime.has(MONTH_KEY))? + unsigned int month = ((datetime.has(MONTH_KEY))? static_cast<unsigned int>(datetime[MONTH_KEY]) -1: 0); - unsigned int year = ((datetime.has(YEAR_KEY))? + unsigned int year = ((datetime.has(YEAR_KEY))? static_cast<unsigned int>(datetime[YEAR_KEY]):0); /// How many days come before each month (0-12) @@ -604,7 +618,7 @@ uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { ERR_FAIL_COND_V( day > MONTH_DAYS_TABLE[LEAPYEAR(year)][month], 0); // Calculate all the seconds from months past in this year - uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = + uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month] * SECONDS_PER_DAY; uint64_t SECONDS_FROM_YEARS_PAST = 0; @@ -614,13 +628,13 @@ uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { SECONDS_PER_DAY; } - uint64_t epoch = - second + - minute * SECONDS_PER_MINUTE + + uint64_t epoch = + second + + minute * SECONDS_PER_MINUTE + hour * SECONDS_PER_HOUR + // Subtract 1 from day, since the current day isn't over yet // and we cannot count all 24 hours. - (day-1) * SECONDS_PER_DAY + + (day-1) * SECONDS_PER_DAY + SECONDS_FROM_MONTHS_PAST_THIS_YEAR + SECONDS_FROM_YEARS_PAST; return epoch; @@ -631,7 +645,7 @@ uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { * Get a dictionary of time values when given epoch time * * Dictionary Time values will be a union if values from #get_time - * and #get_date dictionaries (with the exception of dst = + * and #get_date dictionaries (with the exception of dst = * day light standard time, as it cannot be determined from epoch) * * @param unix_time_val epoch time to convert @@ -660,14 +674,14 @@ Dictionary _OS::get_datetime_from_unix_time( uint64_t unix_time_val) const { time.hour = dayclock / 3600; /* day 0 was a thursday */ - date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7); + date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7); while (dayno >= YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } - date.year = year; + date.year = year; size_t imonth = 0; @@ -984,6 +998,7 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_current_screen","screen"),&_OS::set_current_screen); ObjectTypeDB::bind_method(_MD("get_screen_position","screen"),&_OS::get_screen_position,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_screen_size","screen"),&_OS::get_screen_size,DEFVAL(0)); + ObjectTypeDB::bind_method(_MD("get_screen_dpi","screen"),&_OS::get_screen_dpi,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_window_position"),&_OS::get_window_position); ObjectTypeDB::bind_method(_MD("set_window_position","position"),&_OS::set_window_position); ObjectTypeDB::bind_method(_MD("get_window_size"),&_OS::get_window_size); @@ -1104,6 +1119,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_thread_name","name"),&_OS::set_thread_name); + ObjectTypeDB::bind_method(_MD("set_use_vsync","enable"),&_OS::set_use_vsync); + ObjectTypeDB::bind_method(_MD("is_vsnc_enabled"),&_OS::is_vsnc_enabled); BIND_CONSTANT( DAY_SUNDAY ); BIND_CONSTANT( DAY_MONDAY ); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 0c768651ff..441927940d 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -117,6 +117,7 @@ public: virtual void set_current_screen(int p_screen); virtual Point2 get_screen_position(int p_screen=0) const; virtual Size2 get_screen_size(int p_screen=0) const; + virtual int get_screen_dpi(int p_screen=0) const; virtual Point2 get_window_position() const; virtual void set_window_position(const Point2& p_position); virtual Size2 get_window_size() const; @@ -281,6 +282,9 @@ public: Error set_thread_name(const String& p_name); + void set_use_vsync(bool p_enable); + bool is_vsnc_enabled() const; + static _OS *get_singleton() { return singleton; } _OS(); diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index b1e0066c35..409543bf25 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -152,6 +152,23 @@ class CommandQueueMT { virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); } }; + template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class P8> + struct Command8 : public CommandBase { + + T*instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + + virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7,p8); } + }; + /* comands that return */ template<class T,class M,class R> @@ -270,6 +287,25 @@ class CommandQueueMT { virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; } }; + template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class P8,class R> + struct CommandRet8 : public CommandBase { + + T*instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + R* ret; + SyncSemaphore *sync; + + virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7,p8); sync->sem->post(); sync->in_use=false; ; } + }; + /** commands that don't return but sync */ /* comands that return */ @@ -390,6 +426,25 @@ class CommandQueueMT { virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; } }; + template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class P8> + struct CommandSync8 : public CommandBase { + + T*instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + + SyncSemaphore *sync; + + virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7,p8); sync->sem->post(); sync->in_use=false; ; } + }; + /***** BASE *******/ enum { @@ -639,6 +694,27 @@ public: if (sync) sync->post(); } + + template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7,class P8> + void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8 ) { + + Command8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> * cmd = allocate_and_lock< Command8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> >(); + + cmd->instance=p_instance; + cmd->method=p_method; + cmd->p1=p1; + cmd->p2=p2; + cmd->p3=p3; + cmd->p4=p4; + cmd->p5=p5; + cmd->p6=p6; + cmd->p7=p7; + cmd->p8=p8; + + unlock(); + + if (sync) sync->post(); + } /*** PUSH AND RET COMMANDS ***/ @@ -806,6 +882,31 @@ public: ss->sem->wait(); } + template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class P8,class R> + void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7,P8 p8, R* r_ret ) { + + CommandRet8<T,M,P1,P2,P3,P4,P5,P6,P7,P8,R> * cmd = allocate_and_lock< CommandRet8<T,M,P1,P2,P3,P4,P5,P6,P7,P8,R> >(); + + cmd->instance=p_instance; + cmd->method=p_method; + cmd->p1=p1; + cmd->p2=p2; + cmd->p3=p3; + cmd->p4=p4; + cmd->p5=p5; + cmd->p6=p6; + cmd->p7=p7; + cmd->p8=p8; + cmd->ret=r_ret; + SyncSemaphore *ss=_alloc_sync_sem(); + cmd->sync=ss; + + unlock(); + + if (sync) sync->post(); + ss->sem->wait(); + } + template<class T, class M> void push_and_sync( T * p_instance, M p_method) { @@ -971,6 +1072,31 @@ public: ss->sem->wait(); } + template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class P8> + void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7,P8 p8) { + + CommandSync8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> * cmd = allocate_and_lock< CommandSync8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> >(); + + cmd->instance=p_instance; + cmd->method=p_method; + cmd->p1=p1; + cmd->p2=p2; + cmd->p3=p3; + cmd->p4=p4; + cmd->p5=p5; + cmd->p6=p6; + cmd->p7=p7; + cmd->p8=p8; + + SyncSemaphore *ss=_alloc_sync_sem(); + cmd->sync=ss; + + unlock(); + + if (sync) sync->post(); + ss->sem->wait(); + } + void wait_and_flush_one() { ERR_FAIL_COND(!sync); sync->wait(); diff --git a/core/dictionary.cpp b/core/dictionary.cpp index 75c8531251..6204a87054 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -199,6 +199,18 @@ Array Dictionary::keys() const { } +Array Dictionary::values() const { + + Array varr; + varr.resize(size()); + const Variant *key=NULL; + int i=0; + while((key=next(key))){ + varr[i++] = _p->variant_map[*key]; + } + return varr; +} + const Variant* Dictionary::next(const Variant* p_key) const { return _p->variant_map.next(p_key); @@ -250,5 +262,3 @@ Dictionary::~Dictionary() { _unref(); } - - diff --git a/core/dictionary.h b/core/dictionary.h index c854e95ee6..ae79fab9c3 100644 --- a/core/dictionary.h +++ b/core/dictionary.h @@ -81,6 +81,7 @@ public: const Variant* next(const Variant* p_key=NULL) const; Array keys() const; + Array values() const; Dictionary(const Dictionary& p_from); Dictionary(bool p_shared=false); diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 3cf4ff8f83..63764383ff 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -478,7 +478,21 @@ static _GlobalConstant _global_constants[]={ BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ), + + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR_HELPER ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CHECKABLE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CHECKED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_INTERNATIONALIZED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_BUNDLE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CATEGORY ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONZERO ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONONE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NO_INSTANCE_STATE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_RESTART_IF_CHANGED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT_INTL ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NOEDITOR ), BIND_GLOBAL_CONSTANT( METHOD_FLAG_NORMAL ), BIND_GLOBAL_CONSTANT( METHOD_FLAG_EDITOR ), diff --git a/core/globals.cpp b/core/globals.cpp index 020e05fb8f..9e7b357d73 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -1528,6 +1528,7 @@ Globals::Globals() { 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("debug/profiler_max_functions",16384); using_datapack=false; } diff --git a/core/hq2x.cpp b/core/hq2x.cpp new file mode 100644 index 0000000000..6495c77b2a --- /dev/null +++ b/core/hq2x.cpp @@ -0,0 +1,2636 @@ +/* + * Copyright 2016 Bruno Ribeiro + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "hq2x.h" +#include "math_funcs.h" + + +static const uint32_t AMASK = 0xFF000000; +static const uint32_t YMASK = 0x00FF0000; +static const uint32_t UMASK = 0x0000FF00; +static const uint32_t VMASK = 0x000000FF; + +_FORCE_INLINE_ static uint32_t ARGBtoAYUV( + uint32_t value ) +{ + uint32_t A, R, G, B, Y, U, V; +//todo big endian check + A = value >> 24; + R = (value >> 16) & 0xFF; + G = (value >> 8) & 0xFF; + B = value & 0xFF; + + Y = Math::fast_ftoi( 0.299 * R + 0.587 * G + 0.114 * B); + U = Math::fast_ftoi(-0.169 * R - 0.331 * G + 0.5 * B) + 128; + V = Math::fast_ftoi( 0.5 * R - 0.419 * G - 0.081 * B) + 128; + return (A << 24) + (Y << 16) + (U << 8) + V; +} + + +/* + * Use this function for sharper images (good for cartoon style, used by DOSBOX) + */ + +_FORCE_INLINE_ static bool isDifferent( + uint32_t color1, + uint32_t color2, + uint32_t trY, + uint32_t trU, + uint32_t trV, + uint32_t trA ) +{ + color1 = ARGBtoAYUV(color1); + color2 = ARGBtoAYUV(color2); + + uint32_t value; + + value = ((color1 & YMASK) - (color2 & YMASK)); + value = (value ^ (value >> 31)) - (value >> 31); + if (value > trY) return true; + + value = ((color1 & UMASK) - (color2 & UMASK)); + value = (value ^ (value >> 31)) - (value >> 31); + if (value > trU) return true; + + value = ((color1 & VMASK) - (color2 & VMASK)); + value = (value ^ (value >> 31)) - (value >> 31); + if (value > trV) return true; + + value = ((color1 & AMASK) - (color2 & AMASK)); + value = (value ^ (value >> 31)) - (value >> 31); + if (value > trA) return true; + + return false; + +} + + + +#define MASK_RB 0x00FF00FF +#define MASK_G 0x0000FF00 +#define MASK_A 0xFF000000 + + +/** + * @brief Mixes two colors using the given weights. + */ +#define HQX_MIX_2(C0,C1,W0,W1) \ + ((((C0 & MASK_RB) * W0 + (C1 & MASK_RB) * W1) / (W0 + W1)) & MASK_RB) | \ + ((((C0 & MASK_G) * W0 + (C1 & MASK_G) * W1) / (W0 + W1)) & MASK_G) | \ + (((((C0 & MASK_A) >> 8) * W0 + ((C1 & MASK_A) >> 8) * W1) / (W0 + W1)) << 8) & MASK_A + +/** + * @brief Mixes three colors using the given weights. + */ +#define HQX_MIX_3(C0,C1,C2,W0,W1,W2) \ + ((((C0 & MASK_RB) * W0 + (C1 & MASK_RB) * W1 + (C2 & MASK_RB) * W2) / (W0 + W1 + W2)) & MASK_RB) | \ + ((((C0 & MASK_G) * W0 + (C1 & MASK_G) * W1 + (C2 & MASK_G) * W2) / (W0 + W1 + W2)) & MASK_G) | \ + (((((C0 & MASK_A) >> 8) * W0 + ((C1 & MASK_A) >> 8) * W1 + ((C2 & MASK_A) >> 8) * W2) / (W0 + W1 + W2)) << 8) & MASK_A + + +#define MIX_00_4 *output = w[4]; +#define MIX_00_MIX_00_4_0_3_1 *output = HQX_MIX_2(w[4],w[0],3U,1U); +#define MIX_00_4_3_3_1 *output = HQX_MIX_2(w[4],w[3],3U,1U); +#define MIX_00_4_1_3_1 *output = HQX_MIX_2(w[4],w[1],3U,1U); +#define MIX_00_3_1_1_1 *output = HQX_MIX_2(w[3],w[1],1U,1U); +#define MIX_00_4_3_1_2_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],2U,1U,1U); +#define MIX_00_4_3_1_2_7_7 *output = HQX_MIX_3(w[4],w[3],w[1],2U,7U,7U); +#define MIX_00_4_0_1_2_1_1 *output = HQX_MIX_3(w[4],w[0],w[1],2U,1U,1U); +#define MIX_00_4_0_3_2_1_1 *output = HQX_MIX_3(w[4],w[0],w[3],2U,1U,1U); +#define MIX_00_4_1_3_5_2_1 *output = HQX_MIX_3(w[4],w[1],w[3],5U,2U,1U); +#define MIX_00_4_3_1_5_2_1 *output = HQX_MIX_3(w[4],w[3],w[1],5U,2U,1U); +#define MIX_00_4_3_1_6_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],6U,1U,1U); +#define MIX_00_4_3_1_2_3_3 *output = HQX_MIX_3(w[4],w[3],w[1],2U,3U,3U); +#define MIX_00_MIX_00_4_0_3_10 *output = HQX_MIX_3(w[4],w[3],w[1],14U,1U,1U); + +#define MIX_01_4 *(output + 1) = w[4]; +#define MIX_01_4_2_3_1 *(output + 1) = HQX_MIX_2(w[4],w[2],3U,1U); +#define MIX_01_4_1_3_1 *(output + 1) = HQX_MIX_2(w[4],w[1],3U,1U); +#define MIX_01_1_4_3_1 *(output + 1) = HQX_MIX_2(w[1],w[4],3U,1U); +#define MIX_01_4_5_3_1 *(output + 1) = HQX_MIX_2(w[4],w[5],3U,1U); +#define MIX_01_4_1_7_1 *(output + 1) = HQX_MIX_2(w[4],w[1],7U,1U); +#define MIX_01_4_1_5_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],2U,1U,1U); +#define MIX_01_4_2_5_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[2],w[5],2U,1U,1U); +#define MIX_01_4_2_1_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[2],w[1],2U,1U,1U); +#define MIX_01_4_5_1_5_2_1 *(output + 1) = HQX_MIX_3(w[4],w[5],w[1],5U,2U,1U); +#define MIX_01_4_1_5_5_2_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],5U,2U,1U); +#define MIX_01_4_1_5_6_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],6U,1U,1U); +#define MIX_01_4_1_5_2_3_3 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],2U,3U,3U); +#define MIX_01_4_2_3_10 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],14U,1U,1U); + +#define MIX_02_4 *(output + 2) = w[4]; +#define MIX_02_4_2_3_1 *(output + 2) = HQX_MIX_2(w[4],w[2],3U,1U); +#define MIX_02_4_1_3_1 *(output + 2) = HQX_MIX_2(w[4],w[1],3U,1U); +#define MIX_02_4_5_3_1 *(output + 2) = HQX_MIX_2(w[4],w[5],3U,1U); +#define MIX_02_4_1_5_2_1_1 *(output + 2) = HQX_MIX_3(w[4],w[1],w[5],2U,1U,1U); +#define MIX_02_4_1_5_2_7_7 *(output + 2) = HQX_MIX_3(w[4],w[1],w[5],2U,7U,7U); +#define MIX_02_1_5_1_1 *(output + 2) = HQX_MIX_2(w[1],w[5],1U,1U); + +#define MIX_10_4 *(output + lineSize) = w[4]; +#define MIX_10_4_6_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[6],3U,1U); +#define MIX_10_4_7_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[7],3U,1U); +#define MIX_10_4_3_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[3],3U,1U); +#define MIX_10_4_7_3_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,1U,1U); +#define MIX_10_4_6_3_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[6],w[3],2U,1U,1U); +#define MIX_10_4_6_7_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[6],w[7],2U,1U,1U); +#define MIX_10_4_3_7_5_2_1 *(output + lineSize) = HQX_MIX_3(w[4],w[3],w[7],5U,2U,1U); +#define MIX_10_4_7_3_5_2_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],5U,2U,1U); +#define MIX_10_4_7_3_6_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],6U,1U,1U); +#define MIX_10_4_7_3_2_3_3 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,3U,3U); +#define MIX_10_4_6_3_10 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],14U,1U,1U); +#define MIX_10_4_3_7_1 *(output + lineSize) = HQX_MIX_2(w[4],w[3],7U,1U); +#define MIX_10_3_4_3_1 *(output + lineSize) = HQX_MIX_2(w[3],w[4],3U,1U); + +#define MIX_11_4 *(output + lineSize + 1) = w[4]; +#define MIX_11_4_8_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[8],3U,1U); +#define MIX_11_4_5_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[5],3U,1U); +#define MIX_11_4_7_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[7],3U,1U); +#define MIX_11_4_5_7_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],2U,1U,1U); +#define MIX_11_4_8_7_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[8],w[7],2U,1U,1U); +#define MIX_11_4_8_5_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[8],w[5],2U,1U,1U); +#define MIX_11_4_7_5_5_2_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[7],w[5],5U,2U,1U); +#define MIX_11_4_5_7_5_2_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],5U,2U,1U); +#define MIX_11_4_5_7_6_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],6U,1U,1U); +#define MIX_11_4_5_7_2_3_3 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],2U,3U,3U); +#define MIX_11_4_8_3_10 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],14U,1U,1U); + +#define MIX_12_4 *(output + lineSize + 2) = w[4]; +#define MIX_12_4_5_3_1 *(output + lineSize + 2) = HQX_MIX_2(w[4],w[5],3U,1U); +#define MIX_12_4_5_7_1 *(output + lineSize + 2) = HQX_MIX_2(w[4],w[5],7U,1U); +#define MIX_12_5_4_3_1 *(output + lineSize + 2) = HQX_MIX_2(w[5],w[4],3U,1U); + +#define MIX_20_4 *(output + lineSize + lineSize) = w[4]; +#define MIX_20_4_6_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[6],3U,1U); +#define MIX_20_4_7_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[7],3U,1U); +#define MIX_20_4_3_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[3],3U,1U); +#define MIX_20_4_7_3_2_1_1 *(output + lineSize + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,1U,1U); +#define MIX_20_4_7_3_2_7_7 *(output + lineSize + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,7U,7U); +#define MIX_20_7_3_1_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[7],w[3],1U,1U); + +#define MIX_21_4 *(output + lineSize + lineSize + 1) = w[4]; +#define MIX_21_4_7_3_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[4],w[7],3U,1U); +#define MIX_21_4_7_7_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[4],w[7],7U,1U); +#define MIX_21_7_4_3_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[7],w[4],3U,1U); + +#define MIX_22_4 *(output + lineSize + lineSize + 2) = w[4]; +#define MIX_22_4_8_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[8],3U,1U); +#define MIX_22_4_7_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[7],3U,1U); +#define MIX_22_4_5_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[5],3U,1U); +#define MIX_22_4_5_7_2_1_1 *(output + lineSize + lineSize + 2) = HQX_MIX_3(w[4],w[5],w[7],2U,1U,1U); +#define MIX_22_4_5_7_2_7_7 *(output + lineSize + lineSize + 2) = HQX_MIX_3(w[4],w[5],w[7],2U,7U,7U); +#define MIX_22_5_7_1_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[5],w[7],1U,1U); + + + +uint32_t *hq2x_resize( + const uint32_t *image, + uint32_t width, + uint32_t height, + uint32_t *output, + uint32_t trY, + uint32_t trU, + uint32_t trV, + uint32_t trA, + bool wrapX, + bool wrapY ) +{ + int lineSize = width * 2; + + int previous, next; + uint32_t w[9]; + + trY <<= 16; + trU <<= 8; + trA <<= 24; + + // iterates between the lines + for (uint32_t row = 0; row < height; row++) + { + /* + * Note: this function uses a 3x3 sliding window over the original image. + * + * +----+----+----+ + * | | | | + * | w0 | w1 | w2 | + * +----+----+----+ + * | | | | + * | w3 | w4 | w5 | + * +----+----+----+ + * | | | | + * | w6 | w7 | w8 | + * +----+----+----+ + */ + + // adjusts the previous and next line pointers + if (row > 0) + previous = -width; + else + { + if (wrapY) + previous = width * (height - 1); + else + previous = 0; + } + if (row < height - 1) + next = width; + else + { + if (wrapY) + next = -(width * (height - 1)); + else + next = 0; + } + + // iterates between the columns + for (uint32_t col = 0; col < width; col++) + { + w[1] = *(image + previous); + w[4] = *image; + w[7] = *(image + next); + + if (col > 0) + { + w[0] = *(image + previous - 1); + w[3] = *(image - 1); + w[6] = *(image + next - 1); + } + else + { + if (wrapX) + { + w[0] = *(image + previous + width - 1); + w[3] = *(image + width - 1); + w[6] = *(image + next + width - 1); + } + else + { + w[0] = w[1]; + w[3] = w[4]; + w[6] = w[7]; + } + } + + if (col < width - 1) + { + w[2] = *(image + previous + 1); + w[5] = *(image + 1); + w[8] = *(image + next + 1); + } + else + { + if (wrapX) + { + w[2] = *(image + previous - width + 1); + w[5] = *(image - width + 1); + w[8] = *(image + next - width + 1); + } + else + { + w[2] = w[1]; + w[5] = w[4]; + w[8] = w[7]; + } + } + + int pattern = 0; + + // computes the pattern to be used considering the neighbor pixels + for (int k = 0, flag = 1; k < 9; k++) + { + // ignores the central pixel + if (k == 4) continue; + + if (w[k] != w[4]) + if (isDifferent(w[4], w[k], trY, trU, trV, trA)) pattern |= flag; + flag <<= 1; + } + + switch (pattern) + { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 2: + case 34: + case 130: + case 162: + MIX_00_4_0_3_2_1_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 16: + case 17: + case 48: + case 49: + MIX_00_4_3_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 64: + case 65: + case 68: + case 69: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 8: + case 12: + case 136: + case 140: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 3: + case 35: + case 131: + case 163: + MIX_00_4_3_3_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 6: + case 38: + case 134: + case 166: + MIX_00_4_0_3_2_1_1 + MIX_01_4_5_3_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 20: + case 21: + case 52: + case 53: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 144: + case 145: + case 176: + case 177: + MIX_00_4_3_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_7_3_1 + break; + case 192: + case 193: + case 196: + case 197: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_5_3_1 + break; + case 96: + case 97: + case 100: + case 101: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_8_5_2_1_1 + break; + case 40: + case 44: + case 168: + case 172: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_5_7_2_1_1 + break; + case 9: + case 13: + case 137: + case 141: + MIX_00_4_1_3_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 18: + case 50: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_7_3_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 80: + case 81: + MIX_00_4_3_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 72: + case 76: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 10: + case 138: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 66: + MIX_00_4_0_3_2_1_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 24: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 7: + case 39: + case 135: + MIX_00_4_3_3_1 + MIX_01_4_5_3_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 148: + case 149: + case 180: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_7_3_1 + break; + case 224: + case 228: + case 225: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_5_3_1 + break; + case 41: + case 169: + case 45: + MIX_00_4_1_3_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_5_7_2_1_1 + break; + case 22: + case 54: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_7_3_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 208: + case 209: + MIX_00_4_3_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 104: + case 108: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 11: + case 139: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 19: + case 51: + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_00_4_3_3_1 + MIX_01_4_2_3_1 + } + else + { + MIX_00_4_1_3_5_2_1 + MIX_01_4_1_5_2_3_3 + } + MIX_10_4_7_3_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 146: + case 178: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + MIX_11_4_7_3_1 + } + else + { + MIX_01_4_1_5_2_3_3 + MIX_11_4_5_7_5_2_1 + } + MIX_10_4_7_3_2_1_1 + break; + case 84: + case 85: + MIX_00_4_3_1_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_01_4_1_3_1 + MIX_11_4_8_3_1 + } + else + { + MIX_01_4_5_1_5_2_1 + MIX_11_4_5_7_2_3_3 + } + MIX_10_4_6_3_2_1_1 + break; + case 112: + case 113: + MIX_00_4_3_1_2_1_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_10_4_3_3_1 + MIX_11_4_8_3_1 + } + else + { + MIX_10_4_7_3_5_2_1 + MIX_11_4_5_7_2_3_3 + } + break; + case 200: + case 204: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + MIX_11_4_5_3_1 + } + else + { + MIX_10_4_7_3_2_3_3 + MIX_11_4_7_5_5_2_1 + } + break; + case 73: + case 77: + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_00_4_1_3_1 + MIX_10_4_6_3_1 + } + else + { + MIX_00_4_3_1_5_2_1 + MIX_10_4_7_3_2_3_3 + } + MIX_01_4_1_5_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 42: + case 170: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + MIX_10_4_7_3_1 + } + else + { + MIX_00_4_3_1_2_3_3 + MIX_10_4_3_7_5_2_1 + } + MIX_01_4_2_5_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 14: + case 142: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + MIX_01_4_5_3_1 + } + else + { + MIX_00_4_3_1_2_3_3 + MIX_01_4_1_5_5_2_1 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 67: + MIX_00_4_3_3_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 70: + MIX_00_4_0_3_2_1_1 + MIX_01_4_5_3_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 28: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 152: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 194: + MIX_00_4_0_3_2_1_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_5_3_1 + break; + case 98: + MIX_00_4_0_3_2_1_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_8_5_2_1_1 + break; + case 56: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 25: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 26: + case 31: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 82: + case 214: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 88: + case 248: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 74: + case 107: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 27: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_3_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 86: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_3_2_1_1 + MIX_11_4_8_3_1 + break; + case 216: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 106: + MIX_00_MIX_00_4_0_3_1 + MIX_01_4_2_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 30: + MIX_00_MIX_00_4_0_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 210: + MIX_00_4_0_3_2_1_1 + MIX_01_4_2_3_1 + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 120: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_3_1 + break; + case 75: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_3_1 + MIX_11_4_8_5_2_1_1 + break; + case 29: + MIX_00_4_1_3_1 + MIX_01_4_1_3_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 198: + MIX_00_4_0_3_2_1_1 + MIX_01_4_5_3_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_5_3_1 + break; + case 184: + MIX_00_4_0_1_2_1_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_7_3_1 + break; + case 99: + MIX_00_4_3_3_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_8_5_2_1_1 + break; + case 57: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 71: + MIX_00_4_3_3_1 + MIX_01_4_5_3_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 156: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 226: + MIX_00_4_0_3_2_1_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_5_3_1 + break; + case 60: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 195: + MIX_00_4_3_3_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_5_3_1 + break; + case 102: + MIX_00_4_0_3_2_1_1 + MIX_01_4_5_3_1 + MIX_10_4_3_3_1 + MIX_11_4_8_5_2_1_1 + break; + case 153: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 58: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 83: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 92: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 202: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + MIX_01_4_2_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + MIX_11_4_5_3_1 + break; + case 78: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 154: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 114: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 89: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 90: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 55: + case 23: + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_00_4_3_3_1 + MIX_01_4 + } + else + { + MIX_00_4_1_3_5_2_1 + MIX_01_4_1_5_2_3_3 + } + MIX_10_4_7_3_2_1_1 + MIX_11_4_8_7_2_1_1 + break; + case 182: + case 150: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + MIX_11_4_7_3_1 + } + else + { + MIX_01_4_1_5_2_3_3 + MIX_11_4_5_7_5_2_1 + } + MIX_10_4_7_3_2_1_1 + break; + case 213: + case 212: + MIX_00_4_3_1_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_01_4_1_3_1 + MIX_11_4 + } + else + { + MIX_01_4_5_1_5_2_1 + MIX_11_4_5_7_2_3_3 + } + MIX_10_4_6_3_2_1_1 + break; + case 241: + case 240: + MIX_00_4_3_1_2_1_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_10_4_3_3_1 + MIX_11_4 + } + else + { + MIX_10_4_7_3_5_2_1 + MIX_11_4_5_7_2_3_3 + } + break; + case 236: + case 232: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + MIX_11_4_5_3_1 + } + else + { + MIX_10_4_7_3_2_3_3 + MIX_11_4_7_5_5_2_1 + } + break; + case 109: + case 105: + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_00_4_1_3_1 + MIX_10_4 + } + else + { + MIX_00_4_3_1_5_2_1 + MIX_10_4_7_3_2_3_3 + } + MIX_01_4_1_5_2_1_1 + MIX_11_4_8_5_2_1_1 + break; + case 171: + case 43: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + MIX_10_4_7_3_1 + } + else + { + MIX_00_4_3_1_2_3_3 + MIX_10_4_3_7_5_2_1 + } + MIX_01_4_2_5_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 143: + case 15: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + MIX_01_4_5_3_1 + } + else + { + MIX_00_4_3_1_2_3_3 + MIX_01_4_1_5_5_2_1 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 124: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_3_1 + break; + case 203: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_5_2_1_1 + MIX_10_4_6_3_1 + MIX_11_4_5_3_1 + break; + case 62: + MIX_00_MIX_00_4_0_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 211: + MIX_00_4_3_3_1 + MIX_01_4_2_3_1 + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 118: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_3_3_1 + MIX_11_4_8_3_1 + break; + case 217: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_6_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 110: + MIX_00_MIX_00_4_0_3_1 + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 155: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_3_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 188: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_1 + MIX_11_4_7_3_1 + break; + case 185: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_7_3_1 + break; + case 61: + MIX_00_4_1_3_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 157: + MIX_00_4_1_3_1 + MIX_01_4_1_3_1 + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 103: + MIX_00_4_3_3_1 + MIX_01_4_5_3_1 + MIX_10_4_3_3_1 + MIX_11_4_8_5_2_1_1 + break; + case 227: + MIX_00_4_3_3_1 + MIX_01_4_2_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_5_3_1 + break; + case 230: + MIX_00_4_0_3_2_1_1 + MIX_01_4_5_3_1 + MIX_10_4_3_3_1 + MIX_11_4_5_3_1 + break; + case 199: + MIX_00_4_3_3_1 + MIX_01_4_5_3_1 + MIX_10_4_6_3_2_1_1 + MIX_11_4_5_3_1 + break; + case 220: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 158: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 234: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + MIX_01_4_2_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_5_3_1 + break; + case 242: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 59: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 121: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 87: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 79: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 122: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 94: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 218: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 91: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 229: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_3_3_1 + MIX_11_4_5_3_1 + break; + case 167: + MIX_00_4_3_3_1 + MIX_01_4_5_3_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_5_7_2_1_1 + break; + case 173: + MIX_00_4_1_3_1 + MIX_01_4_1_5_2_1_1 + MIX_10_4_7_3_1 + MIX_11_4_5_7_2_1_1 + break; + case 181: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_2_1_1 + MIX_11_4_7_3_1 + break; + case 186: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_7_3_1 + MIX_11_4_7_3_1 + break; + case 115: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 93: + MIX_00_4_1_3_1 + MIX_01_4_1_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 206: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + MIX_11_4_5_3_1 + break; + case 205: + case 201: + MIX_00_4_1_3_1 + MIX_01_4_1_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4_6_3_1 + } + else + { + MIX_10_4_7_3_6_1_1 + } + MIX_11_4_5_3_1 + break; + case 174: + case 46: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_MIX_00_4_0_3_1 + } + else + { + MIX_00_4_3_1_6_1_1 + } + MIX_01_4_5_3_1 + MIX_10_4_7_3_1 + MIX_11_4_5_7_2_1_1 + break; + case 179: + case 147: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4_2_3_1 + } + else + { + MIX_01_4_1_5_6_1_1 + } + MIX_10_4_7_3_2_1_1 + MIX_11_4_7_3_1 + break; + case 117: + case 116: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4_8_3_1 + } + else + { + MIX_11_4_5_7_6_1_1 + } + break; + case 189: + MIX_00_4_1_3_1 + MIX_01_4_1_3_1 + MIX_10_4_7_3_1 + MIX_11_4_7_3_1 + break; + case 231: + MIX_00_4_3_3_1 + MIX_01_4_5_3_1 + MIX_10_4_3_3_1 + MIX_11_4_5_3_1 + break; + case 126: + MIX_00_MIX_00_4_0_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_3_1 + break; + case 219: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_3_1 + MIX_10_4_6_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 125: + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_00_4_1_3_1 + MIX_10_4 + } + else + { + MIX_00_4_3_1_5_2_1 + MIX_10_4_7_3_2_3_3 + } + MIX_01_4_1_3_1 + MIX_11_4_8_3_1 + break; + case 221: + MIX_00_4_1_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_01_4_1_3_1 + MIX_11_4 + } + else + { + MIX_01_4_5_1_5_2_1 + MIX_11_4_5_7_2_3_3 + } + MIX_10_4_6_3_1 + break; + case 207: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + MIX_01_4_5_3_1 + } + else + { + MIX_00_4_3_1_2_3_3 + MIX_01_4_1_5_5_2_1 + } + MIX_10_4_6_3_1 + MIX_11_4_5_3_1 + break; + case 238: + MIX_00_MIX_00_4_0_3_1 + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + MIX_11_4_5_3_1 + } + else + { + MIX_10_4_7_3_2_3_3 + MIX_11_4_7_5_5_2_1 + } + break; + case 190: + MIX_00_MIX_00_4_0_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + MIX_11_4_7_3_1 + } + else + { + MIX_01_4_1_5_2_3_3 + MIX_11_4_5_7_5_2_1 + } + MIX_10_4_7_3_1 + break; + case 187: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + MIX_10_4_7_3_1 + } + else + { + MIX_00_4_3_1_2_3_3 + MIX_10_4_3_7_5_2_1 + } + MIX_01_4_2_3_1 + MIX_11_4_7_3_1 + break; + case 243: + MIX_00_4_3_3_1 + MIX_01_4_2_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_10_4_3_3_1 + MIX_11_4 + } + else + { + MIX_10_4_7_3_5_2_1 + MIX_11_4_5_7_2_3_3 + } + break; + case 119: + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_00_4_3_3_1 + MIX_01_4 + } + else + { + MIX_00_4_1_3_5_2_1 + MIX_01_4_1_5_2_3_3 + } + MIX_10_4_3_3_1 + MIX_11_4_8_3_1 + break; + case 237: + case 233: + MIX_00_4_1_3_1 + MIX_01_4_1_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_6_3_10 + } + MIX_11_4_5_3_1 + break; + case 175: + case 47: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_MIX_00_4_0_3_10 + } + MIX_01_4_5_3_1 + MIX_10_4_7_3_1 + MIX_11_4_5_7_2_1_1 + break; + case 183: + case 151: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_2_3_10 + } + MIX_10_4_7_3_2_1_1 + MIX_11_4_7_3_1 + break; + case 245: + case 244: + MIX_00_4_3_1_2_1_1 + MIX_01_4_1_3_1 + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_8_3_10 + } + break; + case 250: + MIX_00_MIX_00_4_0_3_1 + MIX_01_4_2_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 123: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_3_1 + break; + case 95: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_3_1 + MIX_11_4_8_3_1 + break; + case 222: + MIX_00_MIX_00_4_0_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_6_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 252: + MIX_00_4_0_1_2_1_1 + MIX_01_4_1_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_8_3_10 + } + break; + case 249: + MIX_00_4_1_3_1 + MIX_01_4_2_1_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_6_3_10 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 235: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_5_2_1_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_6_3_10 + } + MIX_11_4_5_3_1 + break; + case 111: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_MIX_00_4_0_3_10 + } + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_5_2_1_1 + break; + case 63: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_MIX_00_4_0_3_10 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_7_3_1 + MIX_11_4_8_7_2_1_1 + break; + case 159: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_2_3_10 + } + MIX_10_4_6_7_2_1_1 + MIX_11_4_7_3_1 + break; + case 215: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_2_3_10 + } + MIX_10_4_6_3_2_1_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 246: + MIX_00_4_0_3_2_1_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_8_3_10 + } + break; + case 254: + MIX_00_MIX_00_4_0_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_8_3_10 + } + break; + case 253: + MIX_00_4_1_3_1 + MIX_01_4_1_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_6_3_10 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_8_3_10 + } + break; + case 251: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + MIX_01_4_2_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_6_3_10 + } + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 239: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_MIX_00_4_0_3_10 + } + MIX_01_4_5_3_1 + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_6_3_10 + } + MIX_11_4_5_3_1 + break; + case 127: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_MIX_00_4_0_3_10 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_1_5_2_1_1 + } + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + { + MIX_10_4 + } + else + { + MIX_10_4_7_3_2_1_1 + } + MIX_11_4_8_3_1 + break; + case 191: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_MIX_00_4_0_3_10 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_2_3_10 + } + MIX_10_4_7_3_1 + MIX_11_4_7_3_1 + break; + case 223: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + { + MIX_00_4 + } + else + { + MIX_00_4_3_1_2_1_1 + } + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_2_3_10 + } + MIX_10_4_6_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_5_7_2_1_1 + } + break; + case 247: + MIX_00_4_3_3_1 + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + { + MIX_01_4 + } + else + { + MIX_01_4_2_3_10 + } + MIX_10_4_3_3_1 + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + { + MIX_11_4 + } + else + { + MIX_11_4_8_3_10 + } + break; + case 255: + if (isDifferent(w[3], w[1], trY, trU, trV, trA)) + MIX_00_4 + else + MIX_00_MIX_00_4_0_3_10 + + if (isDifferent(w[1], w[5], trY, trU, trV, trA)) + MIX_01_4 + else + MIX_01_4_2_3_10 + + if (isDifferent(w[7], w[3], trY, trU, trV, trA)) + MIX_10_4 + else + MIX_10_4_6_3_10 + + if (isDifferent(w[5], w[7], trY, trU, trV, trA)) + MIX_11_4 + else + MIX_11_4_8_3_10 + break; + } + image++; + output += 2; + } + output += lineSize; + } + + return output; +} diff --git a/core/hq2x.h b/core/hq2x.h new file mode 100644 index 0000000000..8f119d2a01 --- /dev/null +++ b/core/hq2x.h @@ -0,0 +1,19 @@ +#ifndef HQ2X_H +#define HQ2X_H + +#include "typedefs.h" + + +uint32_t *hq2x_resize( + const uint32_t *image, + uint32_t width, + uint32_t height, + uint32_t *output, + uint32_t trY = 0x30, + uint32_t trU = 0x07, + uint32_t trV = 0x06, + uint32_t trA = 0x50, + bool wrapX = false, + bool wrapY = false ); + +#endif // HQ2X_H diff --git a/core/image.cpp b/core/image.cpp index 8635aa1b29..57496683ef 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -30,7 +30,7 @@ #include "hash_map.h" #include "core/io/image_loader.h" #include "core/os/copymem.h" - +#include "hq2x.h" #include "print_string.h" #include <stdio.h> @@ -901,6 +901,44 @@ static void _generate_po2_mipmap(const uint8_t* p_src, uint8_t* p_dst, uint32_t } +void Image::expand_x2_hq2x() { + + ERR_FAIL_COND(format>=FORMAT_INDEXED); + + Format current = format; + bool mipmaps=get_mipmaps(); + if (mipmaps) { + clear_mipmaps(); + } + + if (current!=FORMAT_RGBA) + convert(FORMAT_RGBA); + + DVector<uint8_t> dest; + dest.resize(width*2*height*2*4); + + { + DVector<uint8_t>::Read r = data.read(); + DVector<uint8_t>::Write w = dest.write(); + + hq2x_resize((const uint32_t*)r.ptr(),width,height,(uint32_t*)w.ptr()); + + } + + width*=2; + height*=2; + data=dest; + + + if (current!=FORMAT_RGBA) + convert(current); + + if (mipmaps) { + generate_mipmaps(); + } + +} + void Image::shrink_x2() { ERR_FAIL_COND(format==FORMAT_INDEXED || format==FORMAT_INDEXED_ALPHA); diff --git a/core/image.h b/core/image.h index 35bbd1a684..0f0b345eb9 100644 --- a/core/image.h +++ b/core/image.h @@ -250,6 +250,7 @@ public: void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR ); Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR ); void shrink_x2(); + void expand_x2_hq2x(); /** * Crop the image to a specific size, if larger, then the image is filled by black */ diff --git a/core/input_map.cpp b/core/input_map.cpp index 17e98902a1..08ee8138a3 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -28,6 +28,7 @@ /*************************************************************************/ #include "input_map.h" #include "globals.h" +#include "os/keyboard.h" InputMap *InputMap::singleton=NULL; @@ -36,6 +37,7 @@ void InputMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action); ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id); ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id); + ObjectTypeDB::bind_method(_MD("get_actions"),&InputMap::_get_actions); ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action); ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action); @@ -75,6 +77,35 @@ StringName InputMap::get_action_from_id(int p_id) const { return input_id_map[p_id]; } +Array InputMap::_get_actions() { + + Array ret; + List<StringName> actions = get_actions(); + if(actions.empty()) + return ret; + + for(const List<StringName>::Element *E=actions.front();E;E=E->next()) { + + ret.push_back(E->get()); + } + + return ret; +} + +List<StringName> InputMap::get_actions() const { + + List<StringName> actions = List<StringName>(); + if(input_map.empty()){ + return actions; + } + + for (Map<StringName, Action>::Element *E=input_map.front();E;E=E->next()) { + actions.push_back(E->key()); + } + + return actions; +} + List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const { for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) { @@ -291,6 +322,67 @@ void InputMap::load_from_globals() { } +void InputMap::load_default() { + + InputEvent key; + key.type=InputEvent::KEY; + + add_action("ui_accept"); + key.key.scancode=KEY_RETURN; + action_add_event("ui_accept",key); + key.key.scancode=KEY_ENTER; + action_add_event("ui_accept",key); + key.key.scancode=KEY_SPACE; + action_add_event("ui_accept",key); + + add_action("ui_select"); + key.key.scancode=KEY_SPACE; + action_add_event("ui_select",key); + + add_action("ui_cancel"); + key.key.scancode=KEY_ESCAPE; + action_add_event("ui_cancel",key); + + add_action("ui_focus_next"); + key.key.scancode=KEY_TAB; + action_add_event("ui_focus_next",key); + + add_action("ui_focus_prev"); + key.key.scancode=KEY_TAB; + key.key.mod.shift=true; + action_add_event("ui_focus_prev",key); + key.key.mod.shift=false; + + add_action("ui_left"); + key.key.scancode=KEY_LEFT; + action_add_event("ui_left",key); + + add_action("ui_right"); + key.key.scancode=KEY_RIGHT; + action_add_event("ui_right",key); + + add_action("ui_up"); + key.key.scancode=KEY_UP; + action_add_event("ui_up",key); + + add_action("ui_down"); + key.key.scancode=KEY_DOWN; + action_add_event("ui_down",key); + + + add_action("ui_page_up"); + key.key.scancode=KEY_PAGEUP; + action_add_event("ui_page_up",key); + + add_action("ui_page_down"); + key.key.scancode=KEY_PAGEDOWN; + action_add_event("ui_page_down",key); + +// set("display/orientation", "landscape"); + + +} + InputMap::InputMap() { ERR_FAIL_COND(singleton); diff --git a/core/input_map.h b/core/input_map.h index 5cd1e41922..dc5a911963 100644 --- a/core/input_map.h +++ b/core/input_map.h @@ -47,6 +47,7 @@ class InputMap : public Object { List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const; Array _get_action_list(const StringName& p_action); + Array _get_actions(); protected: @@ -59,6 +60,7 @@ public: bool has_action(const StringName& p_action) const; int get_action_id(const StringName& p_action) const; StringName get_action_from_id(int p_id) const; + List<StringName> get_actions() const; void add_action(const StringName& p_action); void erase_action(const StringName& p_action); @@ -72,6 +74,7 @@ public: void load_from_globals(); + void load_default(); InputMap(); }; diff --git a/core/io/LICENSE-InfoZip.txt b/core/io/LICENSE-InfoZip.txt new file mode 100644 index 0000000000..bcfe47e978 --- /dev/null +++ b/core/io/LICENSE-InfoZip.txt @@ -0,0 +1,60 @@ +This is version 2007-Mar-4 of the Info-ZIP license. +The definitive version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and +a copy at http://www.info-zip.org/pub/infozip/license.html. + + +Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined as +the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, + Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth, + Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, + David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, + Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, + Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, + Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, + Rich Wales, Mike White. + +This software is provided "as is," without warranty of any kind, express +or implied. In no event shall Info-ZIP or its contributors be held liable +for any direct, indirect, incidental, special or consequential damages +arising out of the use of or inability to use this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the above disclaimer and the following restrictions: + + 1. Redistributions of source code (in whole or in part) must retain + the above copyright notice, definition, disclaimer, and this list + of conditions. + + 2. Redistributions in binary form (compiled executables and libraries) + must reproduce the above copyright notice, definition, disclaimer, + and this list of conditions in documentation and/or other materials + provided with the distribution. The sole exception to this condition + is redistribution of a standard UnZipSFX binary (including SFXWiz) as + part of a self-extracting archive; that is permitted without inclusion + of this license, as long as the normal SFX banner has not been removed + from the binary or disabled. + + 3. Altered versions--including, but not limited to, ports to new operating + systems, existing ports with new graphical interfaces, versions with + modified or added functionality, and dynamic, shared, or static library + versions not from Info-ZIP--must be plainly marked as such and must not + be misrepresented as being the original source or, if binaries, + compiled from the original source. Such altered versions also must not + be misrepresented as being Info-ZIP releases--including, but not + limited to, labeling of the altered versions with the names "Info-ZIP" + (or any variation thereof, including, but not limited to, different + capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without the + explicit permission of Info-ZIP. Such altered versions are further + prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP + e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP + will provide support for the altered versions. + + 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," + "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its + own source and binary releases. diff --git a/core/io/LICENSE-MiniZip.txt b/core/io/LICENSE-MiniZip.txt new file mode 100644 index 0000000000..0e8950f86f --- /dev/null +++ b/core/io/LICENSE-MiniZip.txt @@ -0,0 +1,32 @@ +Credits + + Gilles Vollant - Original MiniZip author + Even Rouault - ZIP64 unzip Support + Daniel Borca - BZip Compression method support in unzip + Mathias Svensson - ZIP64 zip support + Mathias Svensson - BZip Compression method support in zip + + This version has been modified for Godot Engine + + +License +---------------------------------------------------------------------------- + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +---------------------------------------------------------------------------- diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 2cc52a9e2d..7db3499505 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -135,7 +135,7 @@ size_t FileAccessMemory::get_len() const { bool FileAccessMemory::eof_reached() const { - return pos >= length; + return pos > length; } uint8_t FileAccessMemory::get_8() const { diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 680e0ef7f9..3520680118 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -116,7 +116,7 @@ Error HTTPClient::request_raw( Method p_method, const String& p_url, const Vecto } request+="\r\n"; CharString cs=request.utf8(); - + DVector<uint8_t> data; //Maybe this goes faster somehow? @@ -639,7 +639,7 @@ void HTTPClient::_bind_methods() { ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true)); ObjectTypeDB::bind_method(_MD("set_connection","connection:StreamPeer"),&HTTPClient::set_connection); ObjectTypeDB::bind_method(_MD("get_connection:StreamPeer"),&HTTPClient::get_connection); - ObjectTypeDB::bind_method(_MD("request_raw","method","url","headers","body"),&HTTPClient::request_raw,DEFVAL(String())); + ObjectTypeDB::bind_method(_MD("request_raw","method","url","headers","body"),&HTTPClient::request_raw); ObjectTypeDB::bind_method(_MD("request","method","url","headers","body"),&HTTPClient::request,DEFVAL(String())); ObjectTypeDB::bind_method(_MD("send_body_text","body"),&HTTPClient::send_body_text); ObjectTypeDB::bind_method(_MD("send_body_data","body"),&HTTPClient::send_body_data); diff --git a/core/io/http_client.h b/core/io/http_client.h index a9cfb1ed73..ceb0273a7d 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -40,7 +40,7 @@ class HTTPClient : public Reference { OBJ_TYPE(HTTPClient,Reference); public: - enum RespondeCode { + enum ResponseCode { // 1xx informational RESPONSE_CONTINUE = 100, diff --git a/core/io/ioapi.c b/core/io/ioapi.c index 8818199f0b..d6063a5fe6 100644 --- a/core/io/ioapi.c +++ b/core/io/ioapi.c @@ -6,7 +6,7 @@ Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read LICENSE-MiniZip.txt */ diff --git a/core/io/ioapi.h b/core/io/ioapi.h index 24bf612617..cb6cb7e766 100644 --- a/core/io/ioapi.h +++ b/core/io/ioapi.h @@ -5,7 +5,7 @@ Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read LICENSE-MiniZip.txt Changes diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index abb1082256..1bb80e74eb 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -243,6 +243,7 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p break; } + return ret; } @@ -318,7 +319,11 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ if (OS::get_singleton()->is_stdout_verbose()) print_line("load resource: "+local_path+" (cached)"); - return RES( ResourceCache::get(local_path ) ); + Ref<Resource> res_cached = ResourceCache::get(local_path); + Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); + + ril->resource = res_cached; + return ril; } if (OS::get_singleton()->is_stdout_verbose()) diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index fe101a8676..4ddb276a27 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -30,13 +30,8 @@ #include "os/file_access.h" #include "translation.h" -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()); +RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const String &p_path) { String l = f->get_line(); @@ -52,6 +47,8 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat String msg_id; String msg_str; String config; + int msg_line=0; + if (r_error) *r_error=ERR_FILE_CORRUPT; @@ -87,7 +84,7 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat if (status==STATUS_READING_ID) { memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+" nexpected 'msgid', was expecting 'msgstr' while parsing: "); + ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected 'msgid', was expecting 'msgstr' while parsing: "); ERR_FAIL_V(RES()); } @@ -100,6 +97,7 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat status=STATUS_READING_ID; msg_id=""; msg_str=""; + msg_line=line; } if (l.begins_with("msgstr")) { @@ -113,6 +111,7 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat l=l.substr(6,l.length()).strip_edges(); status=STATUS_READING_STRING; + msg_line=line; } if (l=="" || l.begins_with("#")) { @@ -183,6 +182,18 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat *r_error=OK; return translation; +} + +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()); + + + return load_translation(f,r_error); } diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index a569674d80..b0c4e42682 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -30,10 +30,12 @@ #define TRANSLATION_LOADER_PO_H #include "io/resource_loader.h" - +#include "translation.h" +#include "os/file_access.h" class TranslationLoaderPO : public ResourceFormatLoader { public: + static RES load_translation(FileAccess *f, Error *r_error,const String& p_path=String()); 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; diff --git a/core/io/unzip.c b/core/io/unzip.c index b438021ad7..78672677f9 100644 --- a/core/io/unzip.c +++ b/core/io/unzip.c @@ -10,7 +10,7 @@ Modifications for Zip64 support on both zip and unzip Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read LICENSE-MiniZip.txt ------------------------------------------------------------------------------------ diff --git a/core/io/unzip.h b/core/io/unzip.h index cb3d239eac..f67c3b2fa8 100644 --- a/core/io/unzip.h +++ b/core/io/unzip.h @@ -10,7 +10,7 @@ Modifications for Zip64 support on both zip and unzip Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read LICENSE-MiniZip.txt --------------------------------------------------------------------------------- diff --git a/core/io/zip.c b/core/io/zip.c index c4ab93ab81..44c79195d9 100644 --- a/core/io/zip.c +++ b/core/io/zip.c @@ -7,7 +7,7 @@ Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read LICENSE-MiniZip.txt Changes Oct-2009 - Mathias Svensson - Remove old C style function prototypes diff --git a/core/io/zip.h b/core/io/zip.h index 85f93568c9..37478b34c0 100644 --- a/core/io/zip.h +++ b/core/io/zip.h @@ -6,7 +6,7 @@ Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read LICENSE-MiniZip.txt --------------------------------------------------------------------------- diff --git a/core/math/math_defs.h b/core/math/math_defs.h index eb85039ca3..e6a56c5e45 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -34,6 +34,7 @@ #define CMP_NORMALIZE_TOLERANCE 0.000001 #define CMP_POINT_IN_PLANE_EPSILON 0.00001 +#define USEC_TO_SEC(m_usec) ((m_usec)/1000000.0) /** * "Real" is a type that will be translated to either floats or fixed depending * on the compilation setting diff --git a/core/object.cpp b/core/object.cpp index ee4b5e288c..cbe24a49f3 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1249,6 +1249,7 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) { argc++; } + emit_signal(p_name,argptr,argc); } @@ -1382,6 +1383,31 @@ void Object::get_signal_connection_list(const StringName& p_signal,List<Connecti } +bool Object::has_persistent_signal_connections() const { + + const StringName *S=NULL; + + while((S=signal_map.next(S))) { + + const Signal *s=&signal_map[*S]; + + for(int i=0;i<s->slot_map.size();i++) { + + if (s->slot_map.getv(i).conn.flags&CONNECT_PERSIST) + return true; + } + } + + return false; +} + +void Object::get_signals_connected_to_this(List<Connection> *p_connections) const { + + for (const List<Connection>::Element *E=connections.front();E;E=E->next()) { + p_connections->push_back(E->get()); + } +} + Error Object::connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds,uint32_t p_flags) { @@ -1395,7 +1421,7 @@ Error Object::connect(const StringName& p_signal, Object *p_to_object, const Str signal_is_valid=true; if (!signal_is_valid) { - ERR_EXPLAIN("Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_method+"'"); + ERR_EXPLAIN("In Object of type '"+String(get_type())+"': Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_object->get_type()+"."+p_to_method+"'"); ERR_FAIL_COND_V(!signal_is_valid,ERR_INVALID_PARAMETER); } signal_map[p_signal]=Signal(); @@ -1755,6 +1781,7 @@ bool Object::is_queued_for_deletion() const { void Object::set_edited(bool p_edited) { _edited=p_edited; + _edited_version++; } bool Object::is_edited() const { @@ -1762,6 +1789,11 @@ bool Object::is_edited() const { return _edited; } + +uint32_t Object::get_edited_version() const { + + return _edited_version; +} #endif Object::Object() { @@ -1777,6 +1809,7 @@ Object::Object() { #ifdef TOOLS_ENABLED _edited=false; + _edited_version=0; #endif #ifdef DEBUG_ENABLED diff --git a/core/object.h b/core/object.h index c34440100f..ce545a58e8 100644 --- a/core/object.h +++ b/core/object.h @@ -67,6 +67,7 @@ enum PropertyHint { PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color PROPERTY_HINT_IMAGE_COMPRESS_LOSSY, PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS, + PROPERTY_HINT_OBJECT_ID, PROPERTY_HINT_MAX, }; @@ -84,6 +85,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_STORE_IF_NONZERO=512, //only store if nonzero PROPERTY_USAGE_STORE_IF_NONONE=1024, //only store if false PROPERTY_USAGE_NO_INSTANCE_STATE=2048, + PROPERTY_USAGE_RESTART_IF_CHANGED=4096, PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED, @@ -387,6 +389,7 @@ friend void postinitialize_handler(Object*); bool _can_translate; #ifdef TOOLS_ENABLED bool _edited; + uint32_t _edited_version; #endif ScriptInstance *script_instance; RefPtr script; @@ -588,6 +591,7 @@ public: #ifdef TOOLS_ENABLED void set_edited(bool p_edited); bool is_edited() const; + uint32_t get_edited_version() const; //this function is used to check when something changed beyond a point, it's used mainly for generating previews #endif void set_script_instance(ScriptInstance *p_instance); @@ -600,6 +604,8 @@ public: void get_signal_list(List<MethodInfo> *p_signals ) const; void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const; void get_all_signal_connections(List<Connection> *p_connections) const; + bool has_persistent_signal_connections() const; + void get_signals_connected_to_this(List<Connection> *p_connections) const; Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds=Vector<Variant>(),uint32_t p_flags=0); void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method); diff --git a/core/os/input.cpp b/core/os/input.cpp index 6e1e618d9a..a766ef87fc 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -60,6 +60,7 @@ void Input::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_joy_name","device"),&Input::get_joy_name); ObjectTypeDB::bind_method(_MD("get_joy_guid","device"),&Input::get_joy_guid); ObjectTypeDB::bind_method(_MD("get_accelerometer"),&Input::get_accelerometer); + ObjectTypeDB::bind_method(_MD("get_magnetometer"),&Input::get_magnetometer); //ObjectTypeDB::bind_method(_MD("get_mouse_pos"),&Input::get_mouse_pos); - this is not the function you want ObjectTypeDB::bind_method(_MD("get_mouse_speed"),&Input::get_mouse_speed); ObjectTypeDB::bind_method(_MD("get_mouse_button_mask"),&Input::get_mouse_button_mask); diff --git a/core/os/input.h b/core/os/input.h index 535776f39c..46edb30aa1 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -75,6 +75,7 @@ public: virtual void warp_mouse_pos(const Vector2& p_to)=0; virtual Vector3 get_accelerometer()=0; + virtual Vector3 get_magnetometer()=0; virtual void action_press(const StringName& p_action)=0; virtual void action_release(const StringName& p_action)=0; diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index 310bbaa3b8..e5feebfbfc 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -43,6 +43,7 @@ void MainLoop::_bind_methods() { BIND_VMETHOD( MethodInfo("_initialize") ); BIND_VMETHOD( MethodInfo("_iteration",PropertyInfo(Variant::REAL,"delta")) ); BIND_VMETHOD( MethodInfo("_idle",PropertyInfo(Variant::REAL,"delta")) ); + BIND_VMETHOD( MethodInfo("_drop_files",PropertyInfo(Variant::STRING_ARRAY,"files"),PropertyInfo(Variant::INT,"screen")) ); BIND_VMETHOD( MethodInfo("_finalize") ); BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER); @@ -108,6 +109,15 @@ bool MainLoop::idle(float p_time) { return false; } + +void MainLoop::drop_files(const Vector<String>& p_files,int p_from_screen) { + + + if (get_script_instance()) + get_script_instance()->call("_drop_files",p_files,p_from_screen); + +} + void MainLoop::finish() { if (get_script_instance()) { diff --git a/core/os/main_loop.h b/core/os/main_loop.h index a34014983e..57185d9d3d 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -64,6 +64,8 @@ public: virtual bool idle(float p_time); virtual void finish(); + virtual void drop_files(const Vector<String>& p_files,int p_from_screen=0); + void set_init_script(const Ref<Script>& p_init_script); MainLoop(); diff --git a/core/os/memory.h b/core/os/memory.h index 8257e66851..5f4c6f929c 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -211,7 +211,7 @@ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_de #ifdef DEBUG_MEMORY_ENABLED -#define memalloc(m_size) Memory::alloc_static(m_size, __FILE__":"__STR(__LINE__)", memalloc.") +#define memalloc(m_size) Memory::alloc_static(m_size, __FILE__ ":" __STR(__LINE__) ", memalloc.") #define memrealloc(m_mem,m_size) Memory::realloc_static(m_mem,m_size) #define memfree(m_size) Memory::free_static(m_size) @@ -224,8 +224,7 @@ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_de #endif #ifdef DEBUG_MEMORY_ENABLED - -#define dynalloc(m_size) Memory::alloc_dynamic(m_size, __FILE__":"__STR(__LINE__)", type: DYNAMIC") +#define dynalloc(m_size) Memory::alloc_dynamic(m_size, __FILE__ ":" __STR(__LINE__) ", type: DYNAMIC") #define dynrealloc(m_mem,m_size) m_mem.resize(m_size) #else @@ -248,7 +247,7 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) { #ifdef DEBUG_MEMORY_ENABLED -#define memnew(m_class) _post_initialize(new(__FILE__":"__STR(__LINE__)", memnew type: "__STR(m_class)) m_class) +#define memnew(m_class) _post_initialize(new(__FILE__ ":" __STR(__LINE__) ", memnew type: " __STR(m_class)) m_class) #else @@ -291,7 +290,7 @@ void memdelete_allocator(T *p_class) { #define memdelete_notnull(m_v) { if (m_v) memdelete(m_v); } #ifdef DEBUG_MEMORY_ENABLED -#define memnew_arr( m_class, m_count ) memnew_arr_template<m_class>(m_count,__FILE__":"__STR(__LINE__)", memnew_arr type: "_STR(m_class)) +#define memnew_arr( m_class, m_count ) memnew_arr_template<m_class>(m_count,__FILE__ ":" __STR(__LINE__) ", memnew_arr type: " _STR(m_class)) #else diff --git a/core/os/os.cpp b/core/os/os.cpp index 1aee6d9aa2..e501bc2eb5 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -306,6 +306,15 @@ String OS::get_system_dir(SystemDir p_dir) const { return "."; } +String OS::get_safe_application_name() const { + String an = Globals::get_singleton()->get("application/name"); + Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" "); + for (int i=0;i<invalid_char.size();i++) { + an = an.replace(invalid_char[i],"-"); + } + return an; +} + String OS::get_data_dir() const { return "."; @@ -530,6 +539,14 @@ String OS::get_joy_guid(int p_device) const { void OS::set_context(int p_context) { } +void OS::set_use_vsync(bool p_enable) { + +} + +bool OS::is_vsnc_enabled() const{ + + return true; +} OS::OS() { last_error=NULL; @@ -548,6 +565,7 @@ OS::OS() { _render_thread_mode=RENDER_THREAD_SAFE; _time_scale=1.0; _pixel_snap=false; + _allow_hidpi=true; Math::seed(1234567); } diff --git a/core/os/os.h b/core/os/os.h index 160c0495bb..c291d09250 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -60,6 +60,7 @@ class OS { int _target_fps; float _time_scale; bool _pixel_snap; + bool _allow_hidpi; char *last_error; @@ -160,6 +161,7 @@ public: virtual void set_current_screen(int p_screen) { } 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 int get_screen_dpi(int p_screen=0) const { return 72; } virtual Point2 get_window_position() const { return Vector2(); } virtual void set_window_position(const Point2& p_position) {} virtual Size2 get_window_size() const=0; @@ -324,6 +326,7 @@ public: virtual String get_locale() const; + String get_safe_application_name() const; virtual String get_data_dir() const; virtual String get_resource_dir() const; @@ -417,6 +420,10 @@ public: virtual void set_context(int p_context); + virtual void set_use_vsync(bool p_enable); + virtual bool is_vsnc_enabled() const; + + bool is_hidpi_allowed() const { return _allow_hidpi; } OS(); virtual ~OS(); diff --git a/core/print_string.cpp b/core/print_string.cpp index e364388b7b..6e57822e94 100644 --- a/core/print_string.cpp +++ b/core/print_string.cpp @@ -66,7 +66,7 @@ void remove_print_handler(PrintHandlerList *p_handler) { l=l->next; } - OS::get_singleton()->print("print handler list is %p\n",print_handler_list); + //OS::get_singleton()->print("print handler list is %p\n",print_handler_list); ERR_FAIL_COND(l==NULL); _global_unlock(); diff --git a/core/profile_clock.cpp b/core/profile_clock.cpp new file mode 100644 index 0000000000..0806275463 --- /dev/null +++ b/core/profile_clock.cpp @@ -0,0 +1,3 @@ +#include "profile_clock.h" + + diff --git a/core/profile_clock.h b/core/profile_clock.h new file mode 100644 index 0000000000..e254580249 --- /dev/null +++ b/core/profile_clock.h @@ -0,0 +1,7 @@ +#ifndef PROFILE_CLOCK_H +#define PROFILE_CLOCK_H + + + + +#endif // PROFILE_CLOCK_H diff --git a/core/resource.cpp b/core/resource.cpp index 672e64b1bb..97dee3e1d7 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -133,6 +133,7 @@ void ResourceImportMetadata::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_source","path","md5"),&ResourceImportMetadata::add_source, ""); ObjectTypeDB::bind_method(_MD("get_source_path","idx"),&ResourceImportMetadata::get_source_path); ObjectTypeDB::bind_method(_MD("get_source_md5","idx"),&ResourceImportMetadata::get_source_md5); + ObjectTypeDB::bind_method(_MD("set_source_md5","idx", "md5"),&ResourceImportMetadata::set_source_md5); ObjectTypeDB::bind_method(_MD("remove_source","idx"),&ResourceImportMetadata::remove_source); ObjectTypeDB::bind_method(_MD("get_source_count"),&ResourceImportMetadata::get_source_count); ObjectTypeDB::bind_method(_MD("set_option","key","value"),&ResourceImportMetadata::set_option); @@ -330,6 +331,31 @@ Ref<ResourceImportMetadata> Resource::get_import_metadata() const { } +#ifdef TOOLS_ENABLED + +uint32_t Resource::hash_edited_version() const { + + uint32_t hash = hash_djb2_one_32(get_edited_version()); + + List<PropertyInfo> plist; + get_property_list(&plist); + + for (List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { + + if (E->get().type==Variant::OBJECT && E->get().hint==PROPERTY_HINT_RESOURCE_TYPE) { + RES res = get(E->get().name); + if (res.is_valid()) { + hash = hash_djb2_one_32(res->hash_edited_version(),hash); + } + } + } + + return hash; + +} + +#endif + Resource::Resource() { @@ -341,6 +367,8 @@ Resource::Resource() { } + + Resource::~Resource() { if (path_cache!="") diff --git a/core/resource.h b/core/resource.h index 8bcdd6b4b7..958414f62b 100644 --- a/core/resource.h +++ b/core/resource.h @@ -142,8 +142,12 @@ public: Ref<ResourceImportMetadata> get_import_metadata() const; + + #ifdef TOOLS_ENABLED + uint32_t hash_edited_version() const; + virtual void set_last_modified_time(uint64_t p_time) { last_modified_time=p_time; } uint64_t get_last_modified_time() const { return last_modified_time; } diff --git a/core/script_debugger_local.cpp b/core/script_debugger_local.cpp index 3e442f7f59..dfff54378a 100644 --- a/core/script_debugger_local.cpp +++ b/core/script_debugger_local.cpp @@ -179,6 +179,125 @@ void ScriptDebuggerLocal::debug(ScriptLanguage *p_script,bool p_can_continue) { } } +struct _ScriptDebuggerLocalProfileInfoSort { + + bool operator()(const ScriptLanguage::ProfilingInfo &A,const ScriptLanguage::ProfilingInfo &B) const { + return A.total_time > B.total_time; + } +}; + +void ScriptDebuggerLocal::profiling_set_frame_times(float p_frame_time,float p_idle_time,float p_fixed_time,float p_fixed_frame_time) { + + + frame_time=p_frame_time; + idle_time=p_idle_time; + fixed_time=p_fixed_time; + fixed_frame_time=p_fixed_frame_time; + + +} + +void ScriptDebuggerLocal::idle_poll() { + + if (!profiling) + return; + + uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum; + + if (diff<1000000) //show every one second + return; + + idle_accum = OS::get_singleton()->get_ticks_usec(); + + int ofs=0; + for(int i=0;i<ScriptServer::get_language_count();i++) { + ofs+=ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo[ofs],pinfo.size()-ofs); + } + + SortArray<ScriptLanguage::ProfilingInfo,_ScriptDebuggerLocalProfileInfoSort> sort; + sort.sort(pinfo.ptr(),ofs); + + //falta el frame time + + uint64_t script_time_us=0; + + for(int i=0;i<ofs;i++) { + + script_time_us+=pinfo[i].self_time; + } + + + float script_time=USEC_TO_SEC(script_time_us); + + float total_time=frame_time; + + //print script total + + print_line("FRAME: total: "+rtos(frame_time)+" script: "+rtos(script_time)+"/"+itos(script_time*100/total_time)+" %"); + + for(int i=0;i<ofs;i++) { + + print_line(itos(i)+":"+pinfo[i].signature); + float tt=USEC_TO_SEC(pinfo[i].total_time); + float st=USEC_TO_SEC(pinfo[i].self_time); + print_line("\ttotal: "+rtos(tt)+"/"+itos(tt*100/total_time)+" % \tself: "+rtos(st)+"/"+itos(st*100/total_time)+" % tcalls: "+itos(pinfo[i].call_count)); + } + + + +} + +void ScriptDebuggerLocal::profiling_start() { + + for(int i=0;i<ScriptServer::get_language_count();i++) { + ScriptServer::get_language(i)->profiling_start(); + } + + + print_line("BEGIN PROFILING"); + profiling=true; + pinfo.resize(32768); + frame_time=0; + fixed_time=0; + idle_time=0; + fixed_frame_time=0; + +} + + +void ScriptDebuggerLocal::profiling_end() { + + int ofs=0; + + for(int i=0;i<ScriptServer::get_language_count();i++) { + ofs+=ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo[ofs],pinfo.size()-ofs); + } + + SortArray<ScriptLanguage::ProfilingInfo,_ScriptDebuggerLocalProfileInfoSort> sort; + sort.sort(pinfo.ptr(),ofs); + + uint64_t total_us=0; + for(int i=0;i<ofs;i++) { + total_us+=pinfo[i].self_time; + } + + float total_time=total_us/1000000.0; + + for(int i=0;i<ofs;i++) { + + print_line(itos(i)+":"+pinfo[i].signature); + float tt=USEC_TO_SEC(pinfo[i].total_time);; + float st=USEC_TO_SEC(pinfo[i].self_time); + print_line("\ttotal_ms: "+rtos(tt)+"\tself_ms: "+rtos(st)+"total%: "+itos(tt*100/total_time)+"\tself%: "+itos(st*100/total_time)+"\tcalls: "+itos(pinfo[i].call_count)); + } + + for(int i=0;i<ScriptServer::get_language_count();i++) { + ScriptServer::get_language(i)->profiling_stop(); + } + + profiling=false; +} + void ScriptDebuggerLocal::send_message(const String& p_message, const Array &p_args) { print_line("MESSAGE: '"+p_message+"' - "+String(Variant(p_args))); @@ -186,4 +305,6 @@ void ScriptDebuggerLocal::send_message(const String& p_message, const Array &p_a ScriptDebuggerLocal::ScriptDebuggerLocal() { + profiling=false; + idle_accum=OS::get_singleton()->get_ticks_usec(); } diff --git a/core/script_debugger_local.h b/core/script_debugger_local.h index 4abacfc519..ffe8dce445 100644 --- a/core/script_debugger_local.h +++ b/core/script_debugger_local.h @@ -32,10 +32,29 @@ #include "script_language.h" class ScriptDebuggerLocal : public ScriptDebugger { + + bool profiling; + float frame_time,idle_time,fixed_time,fixed_frame_time; + uint64_t idle_accum; + + Vector<ScriptLanguage::ProfilingInfo> pinfo; + + public: void debug(ScriptLanguage *p_script,bool p_can_continue); virtual void send_message(const String& p_message, const Array& p_args); + + virtual bool is_profiling() const { return profiling; } + virtual void add_profiling_frame_data(const StringName& p_name,const Array& p_data) {} + + virtual void idle_poll(); + + virtual void profiling_start(); + virtual void profiling_end(); + virtual void profiling_set_frame_times(float p_frame_time,float p_idle_time,float p_fixed_time,float p_fixed_frame_time); + + ScriptDebuggerLocal(); }; diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index b56ff4c0e1..99d1e22c07 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -125,6 +125,10 @@ static ObjectID safe_get_instance_id(const Variant& p_v) { void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { + //this function is called when there is a debugger break (bug on script) + //or when execution is paused from editor + + if (!tcp_client->is_connected()) { ERR_EXPLAIN("Script Debugger failed to connect, but being used anyway."); ERR_FAIL(); @@ -135,6 +139,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { packet_peer_stream->put_var(p_can_continue); packet_peer_stream->put_var(p_script->debug_get_error()); + skip_profile_frame=true; // to avoid super long frame time for the frame + Input::MouseMode mouse_mode=Input::get_singleton()->get_mouse_mode(); if (mouse_mode!=Input::MOUSE_MODE_VISIBLE) Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); @@ -277,6 +283,16 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { } else if (command=="request_video_mem") { _send_video_memory(); + } else if (command=="inspect_object") { + + ObjectID id = cmd[1]; + _send_object_id(id); + } else if (command=="set_object_property") { + + _set_object_property(cmd[1],cmd[2],cmd[3]); + + } else if (command=="reload_scripts") { + reload_all_scripts=true; } else if (command=="breakpoint") { bool set = cmd[3]; @@ -372,7 +388,7 @@ void ScriptDebuggerRemote::line_poll() { //the purpose of this is just processing events every now and then when the script might get too busy //otherwise bugs like infinite loops cant be catched - if (poll_every%512==0) + if (poll_every%2048==0) _poll_events(); poll_every++; @@ -533,8 +549,94 @@ bool ScriptDebuggerRemote::_parse_live_edit(const Array& cmd) { return true; } + +void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) { + + Object* obj = ObjectDB::get_instance(p_id); + if (!obj) + return; + + List<PropertyInfo> pinfo; + obj->get_property_list(&pinfo,true); + + int props_to_send=0; + for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { + + if (E->get().usage&(PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_CATEGORY)) { + props_to_send++; + } + } + + packet_peer_stream->put_var("message:inspect_object"); + packet_peer_stream->put_var(props_to_send*5+4); + packet_peer_stream->put_var(p_id); + packet_peer_stream->put_var(obj->get_type()); + if (obj->is_type("Resource") || obj->is_type("Node")) + packet_peer_stream->put_var(obj->call("get_path")); + else + packet_peer_stream->put_var(""); + + packet_peer_stream->put_var(props_to_send); + + for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { + + if (E->get().usage&(PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_CATEGORY)) { + + if (E->get().usage&PROPERTY_USAGE_CATEGORY) { + packet_peer_stream->put_var("*"+E->get().name); + } else { + packet_peer_stream->put_var(E->get().name); + } + + Variant var = obj->get(E->get().name); + + if (E->get().type==Variant::OBJECT || var.get_type()==Variant::OBJECT) { + + ObjectID id2; + Object *obj=var; + if (obj) { + id2=obj->get_instance_ID(); + } else { + id2=0; + } + + packet_peer_stream->put_var(Variant::INT); //hint string + packet_peer_stream->put_var(PROPERTY_HINT_OBJECT_ID); //hint + packet_peer_stream->put_var(E->get().hint_string); //hint string + packet_peer_stream->put_var(id2); //value + } else { + packet_peer_stream->put_var(E->get().type); + packet_peer_stream->put_var(E->get().hint); + packet_peer_stream->put_var(E->get().hint_string); + //only send information that can be sent.. + if (var.get_type()==Variant::IMAGE) { + var=Image(); + } + if (var.get_type()>=Variant::DICTIONARY) { + var=Array(); //send none for now, may be to big + } + packet_peer_stream->put_var(var); + } + + } + } + +} + +void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String& p_property, const Variant& p_value) { + + Object* obj = ObjectDB::get_instance(p_id); + if (!obj) + return; + + obj->set(p_property,p_value); +} + void ScriptDebuggerRemote::_poll_events() { + //this si called from ::idle_poll, happens only when running the game, + //does not get called while on debug break + while(packet_peer_stream->get_available_packet_count()>0) { _get_output(); @@ -566,6 +668,40 @@ void ScriptDebuggerRemote::_poll_events() { } else if (command=="request_video_mem") { _send_video_memory(); + } else if (command=="inspect_object") { + + ObjectID id = cmd[1]; + _send_object_id(id); + } else if (command=="set_object_property") { + + _set_object_property(cmd[1],cmd[2],cmd[3]); + + } else if (command=="start_profiling") { + + for(int i=0;i<ScriptServer::get_language_count();i++) { + ScriptServer::get_language(i)->profiling_start(); + } + + max_frame_functions=cmd[1]; + profiler_function_signature_map.clear(); + profiling=true; + frame_time=0; + idle_time=0; + fixed_time=0; + fixed_frame_time=0; + + print_line("PROFILING ALRIGHT!"); + + } else if (command=="stop_profiling") { + + for(int i=0;i<ScriptServer::get_language_count();i++) { + ScriptServer::get_language(i)->profiling_stop(); + } + profiling=false; + _send_profiling_data(false); + print_line("PROFILING END!"); + } else if (command=="reload_scripts") { + reload_all_scripts=true; } else if (command=="breakpoint") { bool set = cmd[3]; @@ -582,8 +718,113 @@ void ScriptDebuggerRemote::_poll_events() { } +void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) { + + + + + int ofs=0; + + for(int i=0;i<ScriptServer::get_language_count();i++) { + if (p_for_frame) + ofs+=ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info[ofs],profile_info.size()-ofs); + else + ofs+=ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info[ofs],profile_info.size()-ofs); + } + + for(int i=0;i<ofs;i++) { + profile_info_ptrs[i]=&profile_info[i]; + } + + SortArray<ScriptLanguage::ProfilingInfo*,ProfileInfoSort> sa; + sa.sort(profile_info_ptrs.ptr(),ofs); + + int to_send=MIN(ofs,max_frame_functions); + + //check signatures first + uint64_t total_script_time=0; + + for(int i=0;i<to_send;i++) { + + if (!profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) { + + int idx = profiler_function_signature_map.size(); + packet_peer_stream->put_var("profile_sig"); + packet_peer_stream->put_var(2); + packet_peer_stream->put_var(profile_info_ptrs[i]->signature); + packet_peer_stream->put_var(idx); + + profiler_function_signature_map[profile_info_ptrs[i]->signature]=idx; + + + } + + total_script_time+=profile_info_ptrs[i]->self_time; + } + + //send frames then + + if (p_for_frame) { + packet_peer_stream->put_var("profile_frame"); + packet_peer_stream->put_var(8+profile_frame_data.size()*2+to_send*4); + } else { + packet_peer_stream->put_var("profile_total"); + packet_peer_stream->put_var(8+to_send*4); + } + + + packet_peer_stream->put_var(OS::get_singleton()->get_frames_drawn()); //total frame time + packet_peer_stream->put_var(frame_time); //total frame time + packet_peer_stream->put_var(idle_time); //idle frame time + packet_peer_stream->put_var(fixed_time); //fixed frame time + packet_peer_stream->put_var(fixed_frame_time); //fixed frame time + + packet_peer_stream->put_var(USEC_TO_SEC(total_script_time)); //total script execution time + + if (p_for_frame) { + + packet_peer_stream->put_var(profile_frame_data.size()); //how many profile framedatas to send + packet_peer_stream->put_var(to_send); //how many script functions to send + for (int i=0;i<profile_frame_data.size();i++) { + + + packet_peer_stream->put_var(profile_frame_data[i].name); + packet_peer_stream->put_var(profile_frame_data[i].data); + } + } else { + packet_peer_stream->put_var(0); //how many script functions to send + packet_peer_stream->put_var(to_send); //how many script functions to send + } + + + + for(int i=0;i<to_send;i++) { + + int sig_id=-1; + + if (profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) { + sig_id=profiler_function_signature_map[profile_info_ptrs[i]->signature]; + } + + + + packet_peer_stream->put_var(sig_id); + packet_peer_stream->put_var(profile_info_ptrs[i]->call_count); + packet_peer_stream->put_var(profile_info_ptrs[i]->total_time/1000000.0); + packet_peer_stream->put_var(profile_info_ptrs[i]->self_time/1000000.0); + } + + if (p_for_frame) { + profile_frame_data.clear(); + } + +} + void ScriptDebuggerRemote::idle_poll() { + // this function is called every frame, except when there is a debugger break (::debug() in this class) + // execution stops and remains in the ::debug function + _get_output(); @@ -615,6 +856,24 @@ void ScriptDebuggerRemote::idle_poll() { } } + if (profiling) { + + if (skip_profile_frame) { + skip_profile_frame=false; + } else { + //send profiling info normally + _send_profiling_data(true); + } + } + + if (reload_all_scripts) { + + for(int i=0;i<ScriptServer::get_language_count();i++) { + ScriptServer::get_language(i)->reload_all_scripts(); + } + reload_all_scripts=false; + } + _poll_events(); } @@ -687,6 +946,50 @@ void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) { live_edit_funcs=p_funcs; } +bool ScriptDebuggerRemote::is_profiling() const { + + return profiling; +} +void ScriptDebuggerRemote::add_profiling_frame_data(const StringName& p_name,const Array& p_data){ + + int idx=-1; + for(int i=0;i<profile_frame_data.size();i++) { + if (profile_frame_data[i].name==p_name) { + idx=i; + break; + } + } + + FrameData fd; + fd.name=p_name; + fd.data=p_data; + + if (idx==-1) { + profile_frame_data.push_back(fd); + } else { + profile_frame_data[idx]=fd; + } +} + +void ScriptDebuggerRemote::profiling_start() { + //ignores this, uses it via connnection +} + +void ScriptDebuggerRemote::profiling_end() { + //ignores this, uses it via connnection +} + +void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_fixed_time, float p_fixed_frame_time) { + + frame_time=p_frame_time; + idle_time=p_idle_time; + fixed_time=p_fixed_time; + fixed_frame_time=p_fixed_frame_time; + + +} + + ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func=NULL; ScriptDebuggerRemote::ScriptDebuggerRemote() { @@ -710,11 +1013,18 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() { char_count=0; msec_count=0; last_msec=0; + skip_profile_frame=false; eh.errfunc=_err_handler; eh.userdata=this; add_error_handler(&eh); + profile_info.resize(CLAMP(int(Globals::get_singleton()->get("debug/profiler_max_functions")),128,65535)); + profile_info_ptrs.resize(profile_info.size()); + profiling=false; + max_frame_functions=16; + reload_all_scripts=false; + } ScriptDebuggerRemote::~ScriptDebuggerRemote() { @@ -723,4 +1033,5 @@ ScriptDebuggerRemote::~ScriptDebuggerRemote() { remove_error_handler(&eh); memdelete(mutex); + } diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index f18e212236..c6a00e189f 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -44,6 +44,24 @@ class ScriptDebuggerRemote : public ScriptDebugger { }; + struct ProfileInfoSort { + + bool operator()(ScriptLanguage::ProfilingInfo*A,ScriptLanguage::ProfilingInfo*B) const { + return A->total_time < B->total_time; + } + }; + + Vector<ScriptLanguage::ProfilingInfo> profile_info; + Vector<ScriptLanguage::ProfilingInfo*> profile_info_ptrs; + + Map<StringName,int> profiler_function_signature_map; + float frame_time,idle_time,fixed_time,fixed_frame_time; + + bool profiling; + int max_frame_functions; + bool skip_profile_frame; + bool reload_all_scripts; + Ref<StreamPeerTCP> tcp_client; Ref<PacketPeerStream> packet_peer_stream; @@ -88,17 +106,32 @@ class ScriptDebuggerRemote : public ScriptDebugger { uint32_t poll_every; + bool _parse_live_edit(const Array &p_command); RequestSceneTreeMessageFunc request_scene_tree; void *request_scene_tree_ud; + void _set_object_property(ObjectID p_id, const String& p_property, const Variant& p_value); + + void _send_object_id(ObjectID p_id); void _send_video_memory(); LiveEditFuncs *live_edit_funcs; ErrorHandlerList eh; static void _err_handler(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type); + void _send_profiling_data(bool p_for_frame); + + + struct FrameData { + + StringName name; + Array data; + }; + + Vector<FrameData> profile_frame_data; + public: @@ -129,6 +162,14 @@ public: virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata); virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs); + virtual bool is_profiling() const; + virtual void add_profiling_frame_data(const StringName& p_name,const Array& p_data); + + virtual void profiling_start(); + virtual void profiling_end(); + virtual void profiling_set_frame_times(float p_frame_time,float p_idle_time,float p_fixed_time,float p_fixed_frame_time); + + ScriptDebuggerRemote(); ~ScriptDebuggerRemote(); }; diff --git a/core/script_language.cpp b/core/script_language.cpp index 1503418269..b3116a0297 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -51,7 +51,7 @@ void Script::_bind_methods() { ObjectTypeDB::bind_method(_MD("has_source_code"),&Script::has_source_code); ObjectTypeDB::bind_method(_MD("get_source_code"),&Script::get_source_code); ObjectTypeDB::bind_method(_MD("set_source_code","source"),&Script::set_source_code); - ObjectTypeDB::bind_method(_MD("reload"),&Script::reload); + ObjectTypeDB::bind_method(_MD("reload","keep_state"),&Script::reload,DEFVAL(false)); } diff --git a/core/script_language.h b/core/script_language.h index 1be1aabdab..d8b4c61b6c 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -87,7 +87,7 @@ public: virtual bool has_source_code() const=0; virtual String get_source_code() const=0; virtual void set_source_code(const String& p_code)=0; - virtual Error reload()=0; + virtual Error reload(bool p_keep_state=false)=0; virtual bool is_tool() const=0; @@ -127,6 +127,8 @@ public: virtual Ref<Script> get_script() const=0; + virtual bool is_placeholder() const { return false; } + virtual ScriptLanguage *get_language()=0; virtual ~ScriptInstance(); }; @@ -189,12 +191,28 @@ public: virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); } + virtual void reload_all_scripts()=0; /* LOADER FUNCTIONS */ virtual void get_recognized_extensions(List<String> *p_extensions) const=0; virtual void get_public_functions(List<MethodInfo> *p_functions) const=0; virtual void get_public_constants(List<Pair<String,Variant> > *p_constants) const=0; + struct ProfilingInfo { + StringName signature; + uint64_t call_count; + uint64_t total_time; + uint64_t self_time; + + }; + + virtual void profiling_start()=0; + virtual void profiling_stop()=0; + + virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr,int p_info_max)=0; + virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr,int p_info_max)=0; + + virtual void frame(); virtual ~ScriptLanguage() {}; @@ -233,6 +251,8 @@ public: void update(const List<PropertyInfo> &p_properties,const Map<StringName,Variant>& p_values); //likely changed in editor + virtual bool is_placeholder() const { return true; } + PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script,Object *p_owner); ~PlaceHolderScriptInstance(); @@ -309,6 +329,13 @@ public: virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {} virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {} + virtual bool is_profiling() const=0; + virtual void add_profiling_frame_data(const StringName& p_name,const Array& p_data)=0; + virtual void profiling_start()=0; + virtual void profiling_end()=0; + virtual void profiling_set_frame_times(float p_frame_time,float p_idle_time,float p_fixed_time,float p_fixed_frame_time)=0; + + ScriptDebugger(); virtual ~ScriptDebugger() {singleton=NULL;} diff --git a/core/translation.cpp b/core/translation.cpp index 85e207e08d..ee0ef2ea09 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -672,9 +672,11 @@ void TranslationServer::set_tool_translation(const Ref<Translation>& p_translati StringName TranslationServer::tool_translate(const StringName& p_message) const { if (tool_translation.is_valid()) { - StringName r = tool_translation->tr(p_message); - if (r) + StringName r = tool_translation->get_message(p_message); + + if (r) { return r; + } } return p_message; diff --git a/core/ustring.cpp b/core/ustring.cpp index 1f0eadc03f..a039ba11cd 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3635,7 +3635,7 @@ String String::percent_decode() const { CharString cs = utf8(); for(int i=0;i<cs.length();i++) { - + uint8_t c = cs[i]; if (c=='%' && i<length()-2) { @@ -3963,11 +3963,31 @@ String String::sprintf(const Array& values, bool* error) const { #include "translation.h" +#ifdef TOOLS_ENABLED String TTR(const String& p_text) { if (TranslationServer::get_singleton()) { - return TranslationServer::get_singleton()->translate(p_text); + return TranslationServer::get_singleton()->tool_translate(p_text); } return p_text; } + +#endif + +String RTR(const String& p_text) { + + + + if (TranslationServer::get_singleton()) { + String rtr = TranslationServer::get_singleton()->tool_translate(p_text); + if (rtr==String() || rtr==p_text) { + return TranslationServer::get_singleton()->translate(p_text); + } else { + return rtr; + } + } + + return p_text; +} + diff --git a/core/ustring.h b/core/ustring.h index 78c041fb92..e03f74f506 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -257,6 +257,17 @@ struct NoCaseComparator { /* end of namespace */ //tool translate +#ifdef TOOLS_ENABLED + String TTR(const String&); +#else + +#define TTR(m_val) (String()) + +#endif + +//tool or regular translate +String RTR(const String&); + #endif diff --git a/core/variant.cpp b/core/variant.cpp index ea5a378ad0..38f5e69cc0 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -3048,3 +3048,47 @@ String Variant::get_call_error_text(Object* p_base, const StringName& p_method,c } return "'"+class_name+"::"+String(p_method)+"': "+err_text; } + + +String vformat(const String& p_text, const Variant& p1,const Variant& p2,const Variant& p3,const Variant& p4,const Variant& p5) { + + Array args; + if (p1.get_type()!=Variant::NIL) { + + args.push_back(p1); + + if (p2.get_type()!=Variant::NIL) { + + args.push_back(p2); + + if (p3.get_type()!=Variant::NIL) { + + args.push_back(p3); + + if (p4.get_type()!=Variant::NIL) { + + args.push_back(p4); + + if (p5.get_type()!=Variant::NIL) { + + args.push_back(p5); + + } + + } + + + } + + } + + } + + bool error=false; + String fmt = p_text.sprintf(args,&error); + + ERR_FAIL_COND_V(error,String()); + + return fmt; + +} diff --git a/core/variant.h b/core/variant.h index ed33de6660..b95223ecfb 100644 --- a/core/variant.h +++ b/core/variant.h @@ -469,4 +469,6 @@ const Variant::ObjData& Variant::_get_obj() const { return *reinterpret_cast<const ObjData*>(&_data._mem[0]); } + +String vformat(const String& p_text, const Variant& p1=Variant(),const Variant& p2=Variant(),const Variant& p3=Variant(),const Variant& p4=Variant(),const Variant& p5=Variant()); #endif diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 4be763a511..eb3ab65f40 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -262,7 +262,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM0R(String,basename); VCALL_LOCALMEM1R(String,plus_file); VCALL_LOCALMEM1R(String,ord_at); - //VCALL_LOCALMEM2R(String,erase); + VCALL_LOCALMEM2(String,erase); VCALL_LOCALMEM0R(String,hash); VCALL_LOCALMEM0R(String,md5_text); VCALL_LOCALMEM0R(String,md5_buffer); @@ -339,6 +339,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1R(Vector2,reflect); VCALL_LOCALMEM0R(Vector2,angle); // VCALL_LOCALMEM1R(Vector2,cross); + VCALL_LOCALMEM0R(Vector2,abs); VCALL_LOCALMEM0R(Rect2,get_area); VCALL_LOCALMEM1R(Rect2,intersects); @@ -445,6 +446,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1(Dictionary,erase); VCALL_LOCALMEM0R(Dictionary,hash); VCALL_LOCALMEM0R(Dictionary,keys); + VCALL_LOCALMEM0R(Dictionary,values); VCALL_LOCALMEM1R(Dictionary,parse_json); VCALL_LOCALMEM0R(Dictionary,to_json); @@ -463,6 +465,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM2(Array,insert); VCALL_LOCALMEM1(Array,remove); VCALL_LOCALMEM1R(Array,find); + VCALL_LOCALMEM1R(Array,find_last); + VCALL_LOCALMEM1R(Array,count); VCALL_LOCALMEM1(Array,erase); VCALL_LOCALMEM0(Array,sort); VCALL_LOCALMEM2(Array,sort_custom); @@ -1282,7 +1286,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC0(STRING,STRING,String,basename,varray()); ADDFUNC1(STRING,STRING,String,plus_file,STRING,"file",varray()); ADDFUNC1(STRING,STRING,String,ord_at,INT,"at",varray()); -// ADDFUNC2(STRING,String,erase,INT,INT,varray()); + ADDFUNC2(STRING,NIL,String,erase,INT,"pos",INT,"chars", varray()); ADDFUNC0(STRING,INT,String,hash,varray()); ADDFUNC0(STRING,STRING,String,md5_text,varray()); ADDFUNC0(STRING,RAW_ARRAY,String,md5_buffer,varray()); @@ -1333,6 +1337,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(VECTOR2,VECTOR2,Vector2,slide,VECTOR2,"vec",varray()); ADDFUNC1(VECTOR2,VECTOR2,Vector2,reflect,VECTOR2,"vec",varray()); //ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray()); + ADDFUNC0(VECTOR2,VECTOR2,Vector2,abs,varray()); ADDFUNC0(RECT2,REAL,Rect2,get_area,varray()); ADDFUNC1(RECT2,BOOL,Rect2,intersects,RECT2,"b",varray()); @@ -1432,6 +1437,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(DICTIONARY,NIL,Dictionary,erase,NIL,"value",varray()); ADDFUNC0(DICTIONARY,INT,Dictionary,hash,varray()); ADDFUNC0(DICTIONARY,ARRAY,Dictionary,keys,varray()); + ADDFUNC0(DICTIONARY,ARRAY,Dictionary,values,varray()); ADDFUNC1(DICTIONARY,INT,Dictionary,parse_json,STRING,"json",varray()); ADDFUNC0(DICTIONARY,STRING,Dictionary,to_json,varray()); @@ -1448,6 +1454,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(ARRAY,NIL,Array,remove,INT,"pos",varray()); ADDFUNC1(ARRAY,NIL,Array,erase,NIL,"value",varray()); ADDFUNC1(ARRAY,INT,Array,find,NIL,"value",varray()); + ADDFUNC1(ARRAY,INT,Array,find_last,NIL,"value",varray()); + ADDFUNC1(ARRAY,INT,Array,count,NIL,"value",varray()); ADDFUNC0(ARRAY,NIL,Array,pop_back,varray()); ADDFUNC0(ARRAY,NIL,Array,pop_front,varray()); ADDFUNC0(ARRAY,NIL,Array,sort,varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index f03ab43fce..6065094da7 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -1354,7 +1354,7 @@ void Variant::set(const Variant& p_index, const Variant& p_value, bool *r_valid) return; } else if (*str=="r8" ) { valid=true; - v->g=float(p_value)/255.0; + v->r=float(p_value)/255.0; return; } else if (*str=="g8" ) { valid=true; @@ -2213,16 +2213,16 @@ Variant Variant::get(const Variant& p_index, bool *r_valid) const { return v->get_v(); } else if (*str=="r8") { valid=true; - return v->r*255.0; + return (int)Math::round(v->r*255.0); } else if (*str=="g8" ) { valid=true; - return v->g*255.0; + return (int)Math::round(v->g*255.0); } else if (*str=="b8" ) { valid=true; - return v->b*255.0; + return (int)Math::round(v->b*255.0); } else if (*str=="a8" ) { valid=true; - return v->a*255.0; + return (int)Math::round(v->a*255.0); } } else if (p_index.get_type()==Variant::INT) { @@ -3513,7 +3513,7 @@ void Variant::interpolate(const Variant& a, const Variant& b, float c,Variant &r case INT:{ int va=a._data._int; int vb=b._data._int; - r_dst=int((1.0-c) * va + vb * c + 0.5); + r_dst=int((1.0-c) * va + vb * c); } return; case REAL:{ real_t va=a._data._real; diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 8bd1fddfad..e2786b8099 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -2011,7 +2011,44 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str } break; case Variant::INPUT_EVENT: { - p_store_string_func(p_store_string_ud,"InputEvent()"); //will be added later + String str="InputEvent("; + + InputEvent ev=p_variant; + switch(ev.type) { + case InputEvent::KEY: { + + str+="KEY,"+itos(ev.key.scancode); + String mod; + if (ev.key.mod.alt) + mod+="A"; + if (ev.key.mod.shift) + mod+="S"; + if (ev.key.mod.control) + mod+="C"; + if (ev.key.mod.meta) + mod+="M"; + + if (mod!=String()) + str+=","+mod; + } break; + case InputEvent::MOUSE_BUTTON: { + + str+="MBUTTON,"+itos(ev.mouse_button.button_index); + } break; + case InputEvent::JOYSTICK_BUTTON: { + str+="JBUTTON,"+itos(ev.joy_button.button_index); + + } break; + case InputEvent::JOYSTICK_MOTION: { + str+="JAXIS,"+itos(ev.joy_motion.axis)+","+itos(ev.joy_motion.axis_value); + } break; + default: {} + } + + str+=")"; + + p_store_string_func(p_store_string_ud,str); //will be added later + } break; case Variant::DICTIONARY: { |