diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/color.h | 34 | ||||
-rw-r--r-- | core/image.cpp | 50 | ||||
-rw-r--r-- | core/image.h | 8 | ||||
-rw-r--r-- | core/io/image_loader.cpp | 4 | ||||
-rw-r--r-- | core/io/image_loader.h | 4 | ||||
-rw-r--r-- | core/method_ptrcall.h | 1 | ||||
-rw-r--r-- | core/os/file_access.cpp | 21 | ||||
-rw-r--r-- | core/os/file_access.h | 1 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | core/ustring.cpp | 12 | ||||
-rw-r--r-- | core/variant_parser.cpp | 159 |
11 files changed, 229 insertions, 67 deletions
diff --git a/core/color.h b/core/color.h index 46386fac64..c83dcda4b4 100644 --- a/core/color.h +++ b/core/color.h @@ -83,6 +83,40 @@ struct Color { return res; } + _FORCE_INLINE_ uint32_t to_rgbe9995() const { + + const float pow2to9 = 512.0f; + const float B = 15.0f; + //const float Emax = 31.0f; + const float N = 9.0f; + + float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f); + + float cRed = MAX(0.0f, MIN(sharedexp, r)); + float cGreen = MAX(0.0f, MIN(sharedexp, g)); + float cBlue = MAX(0.0f, MIN(sharedexp, b)); + + float cMax = MAX(cRed, MAX(cGreen, cBlue)); + + // expp = MAX(-B - 1, log2(maxc)) + 1 + B + + float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B; + + float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f); + + float exps = expp + 1.0f; + + if (0.0 <= sMax && sMax < pow2to9) { + exps = expp; + } + + float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); + float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); + float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); + + return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27); + } + _FORCE_INLINE_ Color blend(const Color &p_over) const { Color res; diff --git a/core/image.cpp b/core/image.cpp index 2496fd136c..2640c6be2a 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -59,8 +59,6 @@ const char *Image::format_names[Image::FORMAT_MAX] = { "DXT1 RGB8", //s3tc "DXT3 RGBA8", "DXT5 RGBA8", - "LATC Lum8", - "LATC LumAlpha8", "RGTC Red8", "RGTC RedGreen8", "BPTC_RGBA", @@ -131,10 +129,8 @@ int Image::get_format_pixel_size(Format p_format) { return 1; //bc2 case FORMAT_DXT5: return 1; //bc3 - case FORMAT_LATC_L: case FORMAT_RGTC_R: return 1; //bc4 - case FORMAT_LATC_LA: case FORMAT_RGTC_RG: return 1; //bc5 case FORMAT_BPTC_RGBA: @@ -171,8 +167,6 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { case FORMAT_DXT1: //s3tc bc1 case FORMAT_DXT3: //bc2 case FORMAT_DXT5: //bc3 - case FORMAT_LATC_L: //bc4 - case FORMAT_LATC_LA: //bc4 case FORMAT_RGTC_R: //bc4 case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1: @@ -225,7 +219,7 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { int Image::get_format_pixel_rshift(Format p_format) { - if (p_format == FORMAT_DXT1 || p_format == FORMAT_LATC_L || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) + if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) return 1; else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A) return 2; @@ -239,8 +233,6 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_DXT1: //s3tc bc1 case FORMAT_DXT3: //bc2 case FORMAT_DXT5: //bc3 - case FORMAT_LATC_L: //bc4 - case FORMAT_LATC_LA: //bc4 case FORMAT_RGTC_R: //bc4 case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1: @@ -1500,14 +1492,14 @@ Error Image::decompress() { return OK; } -Error Image::compress(CompressMode p_mode) { +Error Image::compress(CompressMode p_mode, bool p_for_srgb) { switch (p_mode) { case COMPRESS_S3TC: { ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); - _image_compress_bc_func(this); + _image_compress_bc_func(this, p_for_srgb); } break; case COMPRESS_PVRTC2: { @@ -1657,7 +1649,7 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po Ref<Image> (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL; Ref<Image> (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL; -void (*Image::_image_compress_bc_func)(Image *) = NULL; +void (*Image::_image_compress_bc_func)(Image *, bool) = NULL; void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL; void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL; void (*Image::_image_compress_etc_func)(Image *) = NULL; @@ -1981,35 +1973,7 @@ void Image::put_pixel(int p_x, int p_y, const Color &p_color) { } break; case FORMAT_RGBE9995: { - const float pow2to9 = 512.0f; - const float B = 7.0f; - //const float Emax = 31.0f; - const float N = 9.0f; - - float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f); - - float cRed = MAX(0.0f, MIN(sharedexp, p_color.r)); - float cGreen = MAX(0.0f, MIN(sharedexp, p_color.g)); - float cBlue = MAX(0.0f, MIN(sharedexp, p_color.b)); - - float cMax = MAX(cRed, MAX(cGreen, cBlue)); - - // expp = MAX(-B - 1, log2(maxc)) + 1 + B - float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math::log(2.0))) + 1.0f + B; - - float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f); - - float exps = expp + 1.0f; - - if (0.0 <= sMax && sMax < pow2to9) { - exps = expp; - } - - float sRed = (cRed / pow(2.0f, exps - B - N)) + 0.5f; - float sGreen = (cGreen / pow(2.0f, exps - B - N)) + 0.5f; - float sBlue = (cBlue / pow(2.0f, exps - B - N)) + 0.5f; - - ((uint32_t *)ptr)[ofs] = ((uint32_t)(sRed)&0x1FF) | (((uint32_t)(sGreen)&0x1FF) << 9) | (((uint32_t)(sBlue)&0x1FF) << 18) | (((uint32_t)(exps)&0x1F) << 27); + ((uint32_t *)ptr)[ofs] = p_color.to_rgbe9995(); } break; default: { @@ -2144,8 +2108,6 @@ void Image::_bind_methods() { BIND_CONSTANT(FORMAT_DXT1); //s3tc bc1 BIND_CONSTANT(FORMAT_DXT3); //bc2 BIND_CONSTANT(FORMAT_DXT5); //bc3 - BIND_CONSTANT(FORMAT_LATC_L); - BIND_CONSTANT(FORMAT_LATC_LA); BIND_CONSTANT(FORMAT_RGTC_R); BIND_CONSTANT(FORMAT_RGTC_RG); BIND_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h @@ -2180,7 +2142,7 @@ void Image::_bind_methods() { BIND_CONSTANT(COMPRESS_ETC2); } -void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) { +void Image::set_compress_bc_func(void (*p_compress_func)(Image *, bool)) { _image_compress_bc_func = p_compress_func; } diff --git a/core/image.h b/core/image.h index 9ea01a94d4..2a78870f53 100644 --- a/core/image.h +++ b/core/image.h @@ -80,8 +80,6 @@ public: FORMAT_DXT1, //s3tc bc1 FORMAT_DXT3, //bc2 FORMAT_DXT5, //bc3 - FORMAT_LATC_L, - FORMAT_LATC_LA, FORMAT_RGTC_R, FORMAT_RGTC_RG, FORMAT_BPTC_RGBA, //btpc bc7 @@ -116,7 +114,7 @@ public: static Ref<Image> (*_png_mem_loader_func)(const uint8_t *p_png, int p_size); static Ref<Image> (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size); - static void (*_image_compress_bc_func)(Image *); + static void (*_image_compress_bc_func)(Image *, bool p_srgb); static void (*_image_compress_pvrtc2_func)(Image *); static void (*_image_compress_pvrtc4_func)(Image *); static void (*_image_compress_etc_func)(Image *); @@ -269,7 +267,7 @@ public: COMPRESS_ETC2, }; - Error compress(CompressMode p_mode = COMPRESS_S3TC); + Error compress(CompressMode p_mode = COMPRESS_S3TC, bool p_for_srgb = false); Error decompress(); bool is_compressed() const; @@ -283,7 +281,7 @@ public: Rect2 get_used_rect() const; Ref<Image> get_rect(const Rect2 &p_area) const; - static void set_compress_bc_func(void (*p_compress_func)(Image *)); + static void set_compress_bc_func(void (*p_compress_func)(Image *, bool)); static String get_format_name(Format p_format); Image(const uint8_t *p_mem_png_jpg, int p_len = -1); diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 6ed20ac015..23719940be 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -43,7 +43,7 @@ bool ImageFormatLoader::recognize(const String &p_extension) const { return false; } -Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom) { +Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear) { ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER); FileAccess *f = p_custom; @@ -62,7 +62,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c if (!loader[i]->recognize(extension)) continue; - Error err = loader[i]->load_image(p_image, f); + Error err = loader[i]->load_image(p_image, f, p_force_linear); if (err != ERR_FILE_UNRECOGNIZED) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 7114cbf8ad..e528d1423b 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -56,7 +56,7 @@ class ImageFormatLoader { friend class ImageLoader; protected: - virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess) = 0; + virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear) = 0; virtual void get_recognized_extensions(List<String> *p_extensions) const = 0; bool recognize(const String &p_extension) const; @@ -75,7 +75,7 @@ class ImageLoader { protected: public: - static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL); + static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false); static void get_recognized_extensions(List<String> *p_extensions); static bool recognize(const String &p_extension); diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index bcbf2e4531..c6dbfc2a7a 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -115,7 +115,6 @@ MAKE_PTRARG(PoolVector2Array); MAKE_PTRARG(PoolVector3Array); MAKE_PTRARG(PoolColorArray); MAKE_PTRARG(Variant); -MAKE_PTRARG(PowerState); //this is for Object diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index 375121c0cc..805b66b983 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -252,6 +252,27 @@ double FileAccess::get_double() const { return m.d; }; +String FileAccess::get_token() const { + + CharString token; + + CharType c = get_8(); + + while (!eof_reached()) { + + if (c <= ' ') { + if (!token.empty()) + break; + } else { + token.push_back(c); + } + c = get_8(); + } + + token.push_back(0); + return String::utf8(token.get_data()); +} + String FileAccess::get_line() const { CharString line; diff --git a/core/os/file_access.h b/core/os/file_access.h index da15ddc544..6d3e491167 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -106,6 +106,7 @@ public: virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes virtual String get_line() const; + virtual String get_token() const; virtual Vector<String> get_csv_line(String delim = ",") const; /**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac) diff --git a/core/os/os.h b/core/os/os.h index 037ce436c1..11fe8b44e3 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -413,4 +413,6 @@ public: virtual ~OS(); }; +VARIANT_ENUM_CAST(PowerState); + #endif diff --git a/core/ustring.cpp b/core/ustring.cpp index 7a5129962b..6a93d7789e 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -489,6 +489,18 @@ signed char String::naturalnocasecmp_to(const String &p_str) const { const CharType *that_str = p_str.c_str(); if (this_str && that_str) { + + while (*this_str == '.' || *that_str == '.') { + if (*this_str++ != '.') + return 1; + if (*that_str++ != '.') + return -1; + if (!*that_str) + return 1; + if (!*this_str) + return -1; + } + while (*this_str) { if (!*that_str) diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 0d4d0429e7..55e2bb42e3 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -695,6 +695,106 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } return OK; + } else if (id == "Object") { + + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_PARENTHESIS_OPEN) { + r_err_str = "Expected '('"; + return ERR_PARSE_ERROR; + } + + get_token(p_stream, token, line, r_err_str); + + if (token.type != TK_IDENTIFIER) { + r_err_str = "Expected identifier with type of object"; + return ERR_PARSE_ERROR; + } + + String type = token.value; + + Object *obj = ClassDB::instance(type); + + if (!obj) { + r_err_str = "Can't instance Object() of type: " + type; + return ERR_PARSE_ERROR; + } + + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_COMMA) { + r_err_str = "Expected ',' after object type"; + return ERR_PARSE_ERROR; + } + + bool at_key = true; + String key; + Token token; + bool need_comma = false; + + while (true) { + + if (p_stream->is_eof()) { + r_err_str = "Unexpected End of File while parsing Object()"; + return ERR_FILE_CORRUPT; + } + + if (at_key) { + + Error err = get_token(p_stream, token, line, r_err_str); + if (err != OK) + return err; + + if (token.type == TK_PARENTHESIS_CLOSE) { + + return OK; + } + + if (need_comma) { + + if (token.type != TK_COMMA) { + + r_err_str = "Expected '}' or ','"; + return ERR_PARSE_ERROR; + } else { + need_comma = false; + continue; + } + } + + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_STRING) { + r_err_str = "Expected property name as string"; + return ERR_PARSE_ERROR; + } + + key = token.value; + + err = get_token(p_stream, token, line, r_err_str); + + if (err != OK) + return err; + if (token.type != TK_COLON) { + + r_err_str = "Expected ':'"; + return ERR_PARSE_ERROR; + } + at_key = false; + } else { + + Error err = get_token(p_stream, token, line, r_err_str); + if (err != OK) + return err; + + Variant v; + err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser); + if (err) + return err; + obj->set(key, v); + need_comma = true; + at_key = true; + } + } + + return OK; } else if (id == "Resource" || id == "SubResource" || id == "ExtResource") { @@ -1611,30 +1711,63 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::OBJECT: { - RES res = p_variant; - if (res.is_null()) { + Object *obj = p_variant; + + if (!obj) { p_store_string_func(p_store_string_ud, "null"); break; // don't save it } - String res_text; + RES res = p_variant; + if (res.is_valid()) { + //is resource + String res_text; - if (p_encode_res_func) { + //try external function + if (p_encode_res_func) { - res_text = p_encode_res_func(p_encode_res_ud, res); - } + res_text = p_encode_res_func(p_encode_res_ud, res); + } + + //try path because it's a file + if (res_text == String() && res->get_path().is_resource_file()) { - if (res_text == String() && res->get_path().is_resource_file()) { + //external resource + String path = res->get_path(); + res_text = "Resource( \"" + path + "\")"; + } - //external resource - String path = res->get_path(); - res_text = "Resource( \"" + path + "\")"; + //could come up with some sort of text + if (res_text != String()) { + p_store_string_func(p_store_string_ud, res_text); + break; + } } - if (res_text == String()) - res_text = "null"; + //store as generic object + + p_store_string_func(p_store_string_ud, "Object(" + obj->get_class() + ","); + + List<PropertyInfo> props; + obj->get_property_list(&props); + bool first = true; + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + + if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { + //must be serialized + + if (first) { + first = false; + } else { + p_store_string_func(p_store_string_ud, ","); + } + + p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":"); + write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); + } + } - p_store_string_func(p_store_string_ud, res_text); + p_store_string_func(p_store_string_ud, ")\n"); } break; |