diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/core_constants.cpp | 1 | ||||
-rw-r--r-- | core/extension/gdnative_interface.h | 1 | ||||
-rw-r--r-- | core/io/image.cpp | 4 | ||||
-rw-r--r-- | core/io/zip_io.cpp | 58 | ||||
-rw-r--r-- | core/io/zip_io.h | 6 | ||||
-rw-r--r-- | core/math/expression.cpp | 40 | ||||
-rw-r--r-- | core/math/expression.h | 1 | ||||
-rw-r--r-- | core/variant/variant.h | 1 | ||||
-rw-r--r-- | core/variant/variant_op.cpp | 6 | ||||
-rw-r--r-- | core/variant/variant_op.h | 18 |
10 files changed, 95 insertions, 41 deletions
diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 2a514b68d8..a53929a3af 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -703,6 +703,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NEGATE", Variant::OP_NEGATE); BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_POSITIVE", Variant::OP_POSITIVE); BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MODULE", Variant::OP_MODULE); + BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_POWER", Variant::OP_POWER); //bitwise BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SHIFT_LEFT", Variant::OP_SHIFT_LEFT); BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SHIFT_RIGHT", Variant::OP_SHIFT_RIGHT); diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 36d51ff2b9..98976b29f6 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -114,6 +114,7 @@ typedef enum { GDNATIVE_VARIANT_OP_NEGATE, GDNATIVE_VARIANT_OP_POSITIVE, GDNATIVE_VARIANT_OP_MODULE, + GDNATIVE_VARIANT_OP_POWER, /* bitwise */ GDNATIVE_VARIANT_OP_SHIFT_LEFT, GDNATIVE_VARIANT_OP_SHIFT_RIGHT, diff --git a/core/io/image.cpp b/core/io/image.cpp index 661a9f7177..671a000e2c 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -436,7 +436,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p const uint8_t *rofs = &p_src[((y * p_width) + x) * (read_bytes + (read_alpha ? 1 : 0))]; uint8_t *wofs = &p_dst[((y * p_width) + x) * (write_bytes + (write_alpha ? 1 : 0))]; - uint8_t rgba[4]; + uint8_t rgba[4] = { 0, 0, 0, 255 }; if (read_gray) { rgba[0] = rofs[0]; @@ -454,7 +454,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p if (write_gray) { //TODO: not correct grayscale, should use fixed point version of actual weights - wofs[0] = uint8_t((uint16_t(rofs[0]) + uint16_t(rofs[1]) + uint16_t(rofs[2])) / 3); + wofs[0] = uint8_t((uint16_t(rgba[0]) + uint16_t(rgba[1]) + uint16_t(rgba[2])) / 3); } else { for (uint32_t i = 0; i < write_bytes; i++) { wofs[i] = rgba[i]; diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index 2cc844b628..e573e8de19 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -31,18 +31,19 @@ #include "zip_io.h" void *zipio_open(voidpf opaque, const char *p_fname, int mode) { - ZipIOData *zd = (ZipIOData *)opaque; + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, nullptr); String fname; fname.parse_utf8(p_fname); if (mode & ZLIB_FILEFUNC_MODE_WRITE) { - zd->f = FileAccess::open(fname, FileAccess::WRITE); + (*fa) = FileAccess::open(fname, FileAccess::WRITE); } else { - zd->f = FileAccess::open(fname, FileAccess::READ); + (*fa) = FileAccess::open(fname, FileAccess::READ); } - if (zd->f.is_null()) { + if (fa->is_null()) { return nullptr; } @@ -50,49 +51,66 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) { } uLong zipio_read(voidpf opaque, voidpf stream, void *buf, uLong size) { - ZipIOData *zd = (ZipIOData *)opaque; - return zd->f->get_buffer((uint8_t *)buf, size); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + return (*fa)->get_buffer((uint8_t *)buf, size); } uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) { - ZipIOData *zd = (ZipIOData *)opaque; - zd->f->store_buffer((uint8_t *)buf, size); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + (*fa)->store_buffer((uint8_t *)buf, size); return size; } long zipio_tell(voidpf opaque, voidpf stream) { - ZipIOData *zd = (ZipIOData *)opaque; - return zd->f->get_position(); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + return (*fa)->get_position(); } long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { - ZipIOData *zd = (ZipIOData *)opaque; + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); uint64_t pos = offset; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: - pos = zd->f->get_position() + offset; + pos = (*fa)->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: - pos = zd->f->get_length() + offset; + pos = (*fa)->get_length() + offset; break; default: break; } - zd->f->seek(pos); + (*fa)->seek(pos); return 0; } int zipio_close(voidpf opaque, voidpf stream) { - ZipIOData *zd = (ZipIOData *)opaque; - memdelete(zd); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + fa->unref(); return 0; } int zipio_testerror(voidpf opaque, voidpf stream) { - ZipIOData *zd = (ZipIOData *)opaque; - return (zd->f.is_valid() && zd->f->get_error() != OK) ? 1 : 0; + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 1); + ERR_FAIL_COND_V(fa->is_null(), 0); + + return (fa->is_valid() && (*fa)->get_error() != OK) ? 1 : 0; } voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) { @@ -105,9 +123,9 @@ void zipio_free(voidpf opaque, voidpf address) { memfree(address); } -zlib_filefunc_def zipio_create_io() { +zlib_filefunc_def zipio_create_io(Ref<FileAccess> *p_data) { zlib_filefunc_def io; - io.opaque = (void *)memnew(ZipIOData); + io.opaque = (void *)p_data; io.zopen_file = zipio_open; io.zread_file = zipio_read; io.zwrite_file = zipio_write; diff --git a/core/io/zip_io.h b/core/io/zip_io.h index 3bcd1f830d..f137bd2bbf 100644 --- a/core/io/zip_io.h +++ b/core/io/zip_io.h @@ -39,10 +39,6 @@ #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" -struct ZipIOData { - Ref<FileAccess> f; -}; - void *zipio_open(voidpf opaque, const char *p_fname, int mode); uLong zipio_read(voidpf opaque, voidpf stream, void *buf, uLong size); uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size); @@ -57,6 +53,6 @@ int zipio_testerror(voidpf opaque, voidpf stream); voidpf zipio_alloc(voidpf opaque, uInt items, uInt size); void zipio_free(voidpf opaque, voidpf address); -zlib_filefunc_def zipio_create_io(); +zlib_filefunc_def zipio_create_io(Ref<FileAccess> *p_data); #endif // ZIP_IO_H diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 9dd1257474..97dc175d94 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -155,7 +155,12 @@ Error Expression::_get_token(Token &r_token) { return OK; } case '*': { - r_token.type = TK_OP_MUL; + if (expression[str_ofs] == '*') { + r_token.type = TK_OP_POW; + str_ofs++; + } else { + r_token.type = TK_OP_MUL; + } return OK; } case '%': { @@ -542,6 +547,7 @@ const char *Expression::token_name[TK_MAX] = { "OP MUL", "OP DIV", "OP MOD", + "OP POW", "OP SHIFT LEFT", "OP SHIFT RIGHT", "OP BIT AND", @@ -1013,6 +1019,9 @@ Expression::ENode *Expression::_parse_expression() { case TK_OP_MOD: op = Variant::OP_MODULE; break; + case TK_OP_POW: + op = Variant::OP_POWER; + break; case TK_OP_SHIFT_LEFT: op = Variant::OP_SHIFT_LEFT; break; @@ -1066,35 +1075,38 @@ Expression::ENode *Expression::_parse_expression() { bool unary = false; switch (expression[i].op) { - case Variant::OP_BIT_NEGATE: + case Variant::OP_POWER: priority = 0; + break; + case Variant::OP_BIT_NEGATE: + priority = 1; unary = true; break; case Variant::OP_NEGATE: - priority = 1; + priority = 2; unary = true; break; case Variant::OP_MULTIPLY: case Variant::OP_DIVIDE: case Variant::OP_MODULE: - priority = 2; + priority = 3; break; case Variant::OP_ADD: case Variant::OP_SUBTRACT: - priority = 3; + priority = 4; break; case Variant::OP_SHIFT_LEFT: case Variant::OP_SHIFT_RIGHT: - priority = 4; + priority = 5; break; case Variant::OP_BIT_AND: - priority = 5; + priority = 6; break; case Variant::OP_BIT_XOR: - priority = 6; + priority = 7; break; case Variant::OP_BIT_OR: - priority = 7; + priority = 8; break; case Variant::OP_LESS: case Variant::OP_LESS_EQUAL: @@ -1102,20 +1114,20 @@ Expression::ENode *Expression::_parse_expression() { case Variant::OP_GREATER_EQUAL: case Variant::OP_EQUAL: case Variant::OP_NOT_EQUAL: - priority = 8; + priority = 9; break; case Variant::OP_IN: - priority = 10; + priority = 11; break; case Variant::OP_NOT: - priority = 11; + priority = 12; unary = true; break; case Variant::OP_AND: - priority = 12; + priority = 13; break; case Variant::OP_OR: - priority = 13; + priority = 14; break; default: { _set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op)); diff --git a/core/math/expression.h b/core/math/expression.h index d43cc4091a..6ea3c1611f 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -85,6 +85,7 @@ private: TK_OP_MUL, TK_OP_DIV, TK_OP_MOD, + TK_OP_POW, TK_OP_SHIFT_LEFT, TK_OP_SHIFT_RIGHT, TK_OP_BIT_AND, diff --git a/core/variant/variant.h b/core/variant/variant.h index 475bf7158d..726ba120b5 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -473,6 +473,7 @@ public: OP_NEGATE, OP_POSITIVE, OP_MODULE, + OP_POWER, //bitwise OP_SHIFT_LEFT, OP_SHIFT_RIGHT, diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 35e0319aa3..adace2b534 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -361,6 +361,11 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorStringModT<PackedVector3Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_VECTOR3_ARRAY); register_op<OperatorEvaluatorStringModT<PackedColorArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_COLOR_ARRAY); + register_op<OperatorEvaluatorPow<int64_t, int64_t, int64_t>>(Variant::OP_POWER, Variant::INT, Variant::INT); + register_op<OperatorEvaluatorPow<double, int64_t, double>>(Variant::OP_POWER, Variant::INT, Variant::FLOAT); + register_op<OperatorEvaluatorPow<double, double, double>>(Variant::OP_POWER, Variant::FLOAT, Variant::FLOAT); + register_op<OperatorEvaluatorPow<double, double, int64_t>>(Variant::OP_POWER, Variant::FLOAT, Variant::INT); + register_op<OperatorEvaluatorNeg<int64_t, int64_t>>(Variant::OP_NEGATE, Variant::INT, Variant::NIL); register_op<OperatorEvaluatorNeg<double, double>>(Variant::OP_NEGATE, Variant::FLOAT, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector2, Vector2>>(Variant::OP_NEGATE, Variant::VECTOR2, Variant::NIL); @@ -929,6 +934,7 @@ static const char *_op_names[Variant::OP_MAX] = { "unary-", "unary+", "%", + "**", "<<", ">>", "&", diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h index f72a92d31a..3e9bae1078 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -92,6 +92,24 @@ public: }; template <class R, class A, class B> +class OperatorEvaluatorPow { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = R(Math::pow((double)a, (double)b)); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = R(Math::pow((double)*VariantGetInternalPtr<A>::get_ptr(left), (double)*VariantGetInternalPtr<B>::get_ptr(right))); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(R(Math::pow((double)PtrToArg<A>::convert(left), (double)PtrToArg<B>::convert(right))), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> class OperatorEvaluatorXForm { public: static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { |