summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/color.h34
-rw-r--r--core/image.cpp50
-rw-r--r--core/image.h8
-rw-r--r--core/io/image_loader.cpp4
-rw-r--r--core/io/image_loader.h4
-rw-r--r--core/method_ptrcall.h1
-rw-r--r--core/os/file_access.cpp21
-rw-r--r--core/os/file_access.h1
-rw-r--r--core/os/os.h2
-rw-r--r--core/ustring.cpp12
-rw-r--r--core/variant_parser.cpp159
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;