diff options
324 files changed, 5105 insertions, 1818 deletions
@@ -24,6 +24,7 @@ dankan1890 <mewuidev2@gmail.com> Daniel J. Ramirez <djrmuv@gmail.com> Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl> Emmanuel Barroga <emmanuelbarroga@gmail.com> +Eric M <itsjusteza@gmail.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com> Fabian <supagu@gmail.com> diff --git a/AUTHORS.md b/AUTHORS.md index 40aa50f8b6..8ae19cfdf7 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -66,6 +66,7 @@ name is available. Emmanuel Leblond (touilleMan) Eoin O'Neill (Eoin-ONeill-Yokai) Eric Lasota (elasota) + Eric M (EricEzaM) Eric Rybicki (ericrybick) Erik Selecký (rxlecky) est31 diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 8ccdecd307..757913f0bd 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -338,7 +338,7 @@ License: Expat Files: ./thirdparty/tinyexr/ Comment: TinyEXR -Copyright: 2014-2019, Syoyo Fujita +Copyright: 2014-2020, Syoyo Fujita 2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC License: BSD-3-clause @@ -27,16 +27,17 @@ generous deed immortalized in the next stable release of Godot Engine. ## Bronze sponsors Brandon Lamb + Garry Newman ## Mini sponsors AD Ford - Alan Beauchamp albinaask Alejandro Saucedo alex brown Andrew Dunai Christian Baune + Christoffer Sundbom Christopher Montesano Darkhan Baimyrza Darrin Massena @@ -46,7 +47,6 @@ generous deed immortalized in the next stable release of Godot Engine. Edward Flick Gamechuck GameDev.net - Grady Hein-Pieter van Braam Jacob McKenney Jasper Brooks @@ -78,7 +78,6 @@ generous deed immortalized in the next stable release of Godot Engine. Asher Glick Austen McRae Bernhard Werner - beVR Carlo Cabanilla Chris Goddard Christopher Case @@ -93,8 +92,11 @@ generous deed immortalized in the next stable release of Godot Engine. Florian Rämisch Forge Gamejunkey + Grady Jakub Grzesik Javier Roman + Jeff Nyte + Joan Fons Jon Woodward Karl Werf Klavdij Voncina @@ -103,7 +105,9 @@ generous deed immortalized in the next stable release of Godot Engine. Maciej Pendolski Manuele Finocchiaro Markus Wiesner + Mason Bially Matthew Hillier + m kaersten Mohamed Ikbel Boulabiar Monster Vial Officine Pixel S.n.c. @@ -114,10 +118,9 @@ generous deed immortalized in the next stable release of Godot Engine. Rob Messick Roland Fredenhagen Ronan Zeegers - Ryan Badour Sandro Jenny Sarksus - Scott Wadden + Sean Sergey Sofox Spicylewd @@ -133,13 +136,16 @@ generous deed immortalized in the next stable release of Godot Engine. Adam Nakonieczny Adam Neumann Alexander J Maynard + Alex de la Mare Alexey Dyadchenko Alex Khayrullin alice gambrell Andreas Funke André Frélicot Andrew Harris + Antoni Batchelli aoshiwik + Arisaka Mayuki Barugon Can Eris Carlos de Sousa Marques @@ -148,7 +154,6 @@ generous deed immortalized in the next stable release of Godot Engine. Chelsea Hash Chris Petrich Chris Serino - Christian Alexander Bjørklund Bøhler Christian Leth Jeppesen Cody Parker Conrad Curry @@ -164,19 +169,20 @@ generous deed immortalized in the next stable release of Godot Engine. Felix Brückner flesk F S + Gabrielius Vaiškūnas Gary Hulst gavlig GGGames.org GiulianoB + Green Fox Guilherme Felipe de C. G. da Silva Heath Hayes Hoai Nam Tran Horváth Péter Hu Hund + James Couzens Jared Jared White - Jeff Nyte - Joan Fons Joel Fivat Joel Höglund John G Gentzel @@ -186,26 +192,31 @@ generous deed immortalized in the next stable release of Godot Engine. Joshua Flores Joshua Lesperance Juan Velandia + Judd Julian Todd Juraj Móza + JUSTIN CARROLL Justo Delgado Baudí Kelteseth kickmaniac kinfox + kuku Lachie Lain Ballard Leo Fidel R Liban luca duran + Luc-Frédéric Langis MadScientistCarl Marcelo Dornbusch Lopes Marisa Clardy Markus Fehr Martin Eigel + Martin Kotz + Martin Soucek Matt Eunson Michael Michael Dürwald Mikado069 - m kaersten MuffinManKen Nick Abousselam Oliver Dick @@ -221,13 +232,13 @@ generous deed immortalized in the next stable release of Godot Engine. pl Ranoller Raymond Harris + razmie Ricardo Alcantara Rob Robert Willes Rob McInroy Rocknight Studios Ronnie Ashlock - Ryan Ryan Wilson Samuel Judd Scott Pilet @@ -235,9 +246,9 @@ generous deed immortalized in the next stable release of Godot Engine. Sean Robertson Sébastien Serban Serafimescu + Sergey Minakov Shishir Tandale SKison - SleepCircle spilldata Steven Landow Stoned Xander @@ -245,13 +256,14 @@ generous deed immortalized in the next stable release of Godot Engine. TheLevelOfDetail . Thomas Bjarnelöf Thomas Kurz + Tim Howard Timothy Pulliam Tobias Bocanegra Trent Fehl Valryia VikFro - Vincent Henderson Vojtěch + voxelv William Foster Wojciech Chojnacki Xavier PATRICELLI @@ -264,6 +276,7 @@ generous deed immortalized in the next stable release of Godot Engine. 1D_Inc Aaron + Aaron Passchier Abraham Haskins Acheron Adam @@ -275,9 +288,11 @@ generous deed immortalized in the next stable release of Godot Engine. Adam Smeltzer Adam Szymański Adisibio + Agar3s - Giovanny Beltrán Agustinus Arya Aidan O'Flannagain Aki Mimoto + Alan Beauchamp Albin Jonasson Svärdsby Alder Stefano AleMax @@ -290,6 +305,7 @@ generous deed immortalized in the next stable release of Godot Engine. Allen Schade Andreas Krampitz André Simões + Andre Stackhouse andrew james morris Andrew Mansuetti Andrew Rosenwinkel @@ -298,16 +314,18 @@ generous deed immortalized in the next stable release of Godot Engine. Anthony Avina AP Condomines Arda Erol - Arisaka Mayuki Armin Preiml Arseniy M Arthur S. Muszynski Ashley Claymore Ashton Scott Snapp + Astier Mickael Aubrey Falconer B A Balázs Batári + Balázs Kondákor Bartosz Bielecki + Bekhoucha Danyl Benedikt Ben Vercammen Bernd Jänichen @@ -315,6 +333,7 @@ generous deed immortalized in the next stable release of Godot Engine. Black Block Blair Allen Bobby CC Wong + Borkzilla Bram brian Brian mc gowan @@ -322,6 +341,7 @@ generous deed immortalized in the next stable release of Godot Engine. Burney Waring Caleb Gartner Cameron Meyer + Carlos Cejudo Carl van der Geest Carwyn Edwards Cas Brugman @@ -329,14 +349,15 @@ generous deed immortalized in the next stable release of Godot Engine. Chad Steadman Chris Brown Chris Chapin + Chris Jagusch + Christian Clavet Christian Winter Christoffer Dahlblom - Christoffer Sundbom Christophe Gagnier Christopher Schmitt - Christoph Woinke Clay Heaton Cole Johnson + Conall O Curt King CzechBlueBear Daniel De Macedo @@ -344,8 +365,10 @@ generous deed immortalized in the next stable release of Godot Engine. DanielMaximiano Daniel Szarfman Daniel Tebbutt + Danny Welch Daren Scot Wilson Dave Walker + David Bôle David May David Woodard David Zanetti @@ -377,7 +400,6 @@ generous deed immortalized in the next stable release of Godot Engine. Fekinox Felix Bohmann Flaredown - Florian Richer Forty Doubleu Frank FuDiggity @@ -385,6 +407,7 @@ generous deed immortalized in the next stable release of Godot Engine. gamedev by Celio Gary Thomas George Marques + Greg Lincoln Greg Olson GREGORY C FEIN Greyson Richey @@ -394,9 +417,11 @@ generous deed immortalized in the next stable release of Godot Engine. Guldoman Gustavo Loureiro dos Reis Hal A + helija Heribert Hirth Hunter Jones Hylpher + Ian Williams Iiari iKlem IndustrialRobot @@ -406,9 +431,11 @@ generous deed immortalized in the next stable release of Godot Engine. Jaguar Jaiden Gerig Jaime Ruiz-Borau Vizárraga + Jake Huxell Jako Danar James James A F Manley + James Thomas Jamiee H Jamie Massey Janders @@ -429,6 +456,7 @@ generous deed immortalized in the next stable release of Godot Engine. Jonatan R Jonathan G Jon Bonazza + Jon Oakes Jon Sully Jordy Goodridge Jorge Antunes @@ -437,12 +465,12 @@ generous deed immortalized in the next stable release of Godot Engine. Josh Mitchell Joshua Southerland Juanfran - Judd Julian Murgia June Little JungleRobba Justin Calleja Justin Hamilton + Justin Oaksford Justin Spedding KaDokta Karel Němec @@ -454,11 +482,13 @@ generous deed immortalized in the next stable release of Godot Engine. Kevin McPhillips Kiri Jolly Kjetil Haugland + Kristian Nygaard Jensen KsyTek Games Kuan Cheang kycho Kyle Appelgate Kyuppin + Laurent CHEA Laurent Tréguier LEMMiNO Leonardo Dimano @@ -496,9 +526,10 @@ generous deed immortalized in the next stable release of Godot Engine. Mikayla Mike Birkhead Mike Cunningham + Mitchell J. Wagner Molinghu + Molly Jameson MoM - Mored4u Nathan Fish Natrim nee @@ -520,25 +551,25 @@ generous deed immortalized in the next stable release of Godot Engine. Oleg Reva Olivier Omar Delarosa + Orinxlm Oscar Domingo Oscar Norlander - Pan Ip Parinya Teerakasemsuk Patrick Dully Patrick Nafarrete Paul Gieske Paul Mason Paweł Kowal + Paweł Łyczkowski Pedro Assuncao Penguin - Peter Philip Cohoe Pierre-Nicolas Tollitte Piotr Góral Point08 Preethi Vaidyanathan + Price Comstock pwab - Rad Cat Rafa Laguna Remi Rampin Rémi Verschelde @@ -547,6 +578,7 @@ generous deed immortalized in the next stable release of Godot Engine. Richard Ivánek Robert Farr (Larington) Robert Larnach + Rob Ruana Roger Smith Roland Rząsa Roman Tinkov @@ -558,6 +590,7 @@ generous deed immortalized in the next stable release of Godot Engine. Sam Caulfield Sam Edson Samuele Zolfanelli + sayaks Scott D. Yelich Scott Longley ScottMakesGames @@ -574,6 +607,7 @@ generous deed immortalized in the next stable release of Godot Engine. Simon Schoenenberger Simon Wenner Sintinium + Skalli smbe19 smo1704 soft circles @@ -581,9 +615,11 @@ generous deed immortalized in the next stable release of Godot Engine. Stefano Caronia Steve Cloete Svenne Krap + tadashi endo Tannen Helmers Terry tezuvholovdr + Theodore Lindsey TheVoiceInMyHead thomas Thomas Bechtold @@ -591,6 +627,7 @@ generous deed immortalized in the next stable release of Godot Engine. Thomas Kelly Tim Drumheller Tim Erskine + Tim Gleason Timothy B. MacDonald Tobbun Tobias Bradtke @@ -622,10 +659,16 @@ generous deed immortalized in the next stable release of Godot Engine. werner mendizabal Wiley Thompson Will + William Edwards + William F Siqueira + William Hogben + Windvis Wyatt Goodin + x1212 Yegor Smirnov YiYin Gu Yuri Sizov + Zak Stephens Zgegnesh Hemomancer ΒΑΣΙΛΗΣ ΓΕΩΡΓΑΚΟΠΟΥΛΟΣ 郝晨煜 diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp index b0dc47e655..117e47d538 100644 --- a/core/crypto/crypto_core.cpp +++ b/core/crypto/crypto_core.cpp @@ -140,13 +140,19 @@ Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst return ret ? FAILED : OK; } -Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { - int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst); +Error CryptoCore::AESContext::encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) { + int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, r_iv, p_src, r_dst); return ret ? FAILED : OK; } -Error CryptoCore::AESContext::encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) { - int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, r_iv, p_src, r_dst); +Error CryptoCore::AESContext::encrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst) { + size_t iv_off = 0; // Ignore and assume 16-byte alignment. + int ret = mbedtls_aes_crypt_cfb128((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, &iv_off, p_iv, p_src, r_dst); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { + int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst); return ret ? FAILED : OK; } @@ -155,6 +161,12 @@ Error CryptoCore::AESContext::decrypt_cbc(size_t p_length, uint8_t r_iv[16], con return ret ? FAILED : OK; } +Error CryptoCore::AESContext::decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst) { + size_t iv_off = 0; // Ignore and assume 16-byte alignment. + int ret = mbedtls_aes_crypt_cfb128((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_length, &iv_off, p_iv, p_src, r_dst); + return ret ? FAILED : OK; +} + // CryptoCore String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { int b64len = p_src_len / 3 * 4 + 4 + 1; diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h index 82df9c23a8..9ab2871caa 100644 --- a/core/crypto/crypto_core.h +++ b/core/crypto/crypto_core.h @@ -88,6 +88,8 @@ public: Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); Error encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst); Error decrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst); + Error encrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst); + Error decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst); }; static String b64_encode_str(const uint8_t *p_src, int p_src_len); diff --git a/core/image.cpp b/core/image.cpp index e2f353698f..b8a443eed2 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -363,6 +363,82 @@ void Image::get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int r_size = ofs2 - ofs; } +Image::Image3DValidateError Image::validate_3d_image(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_images) { + int w = p_width; + int h = p_height; + int d = p_depth; + + int arr_ofs = 0; + + while (true) { + for (int i = 0; i < d; i++) { + int idx = i + arr_ofs; + if (idx >= p_images.size()) { + return VALIDATE_3D_ERR_MISSING_IMAGES; + } + if (p_images[idx].is_null() || p_images[idx]->empty()) { + return VALIDATE_3D_ERR_IMAGE_EMPTY; + } + if (p_images[idx]->get_format() != p_format) { + return VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH; + } + if (p_images[idx]->get_width() != w || p_images[idx]->get_height() != h) { + return VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH; + } + if (p_images[idx]->has_mipmaps()) { + return VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS; + } + } + + arr_ofs += d; + + if (!p_mipmaps) { + break; + } + + if (w == 1 && h == 1 && d == 1) { + break; + } + + w = MAX(1, w >> 1); + h = MAX(1, h >> 1); + d = MAX(1, d >> 1); + } + + if (arr_ofs != p_images.size()) { + return VALIDATE_3D_ERR_EXTRA_IMAGES; + } + + return VALIDATE_3D_OK; +} + +String Image::get_3d_image_validation_error_text(Image3DValidateError p_error) { + switch (p_error) { + case VALIDATE_3D_OK: { + return TTR("Ok"); + } break; + case VALIDATE_3D_ERR_IMAGE_EMPTY: { + return TTR("Empty Image found"); + } break; + case VALIDATE_3D_ERR_MISSING_IMAGES: { + return TTR("Missing Images"); + } break; + case VALIDATE_3D_ERR_EXTRA_IMAGES: { + return TTR("Too many Images"); + } break; + case VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH: { + return TTR("Image size mismatch"); + } break; + case VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH: { + return TTR("Image format mismatch"); + } break; + case VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS: { + return TTR("Image has included mipmaps"); + } break; + } + return String(); +} + int Image::get_width() const { return width; } diff --git a/core/image.h b/core/image.h index d2572b072e..06794c7fed 100644 --- a/core/image.h +++ b/core/image.h @@ -230,6 +230,19 @@ public: void get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const; //get where the mipmap begins in data void get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const; //get where the mipmap begins in data + enum Image3DValidateError { + VALIDATE_3D_OK, + VALIDATE_3D_ERR_IMAGE_EMPTY, + VALIDATE_3D_ERR_MISSING_IMAGES, + VALIDATE_3D_ERR_EXTRA_IMAGES, + VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH, + VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH, + VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS, + }; + + static Image3DValidateError validate_3d_image(Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_images); + static String get_3d_image_validation_error_text(Image3DValidateError p_error); + /** * Resize the image, using the preferred interpolation method. */ diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 99ca8107e4..7480262835 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -180,8 +180,95 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p ERR_FAIL_V(-1); } +/** + This will handle both Gzip and Deflat streams. It will automatically allocate the output buffer into the provided p_dst_vect Vector. + This is required for compressed data who's final uncompressed size is unknown, as is the case for HTTP response bodies. + This is much slower however than using Compression::decompress because it may result in multiple full copies of the output buffer. +*/ +int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode) { + int ret; + uint8_t *dst = nullptr; + int out_mark = 0; + z_stream strm; + + ERR_FAIL_COND_V(p_src_size <= 0, Z_DATA_ERROR); + + // This function only supports GZip and Deflate + int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16; + ERR_FAIL_COND_V(p_mode != MODE_DEFLATE && p_mode != MODE_GZIP, Z_ERRNO); + + // Initialize the stream + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + int err = inflateInit2(&strm, window_bits); + ERR_FAIL_COND_V(err != Z_OK, -1); + + // Setup the stream inputs + strm.next_in = (Bytef *)p_src; + strm.avail_in = p_src_size; + + // Ensure the destination buffer is empty + p_dst_vect->resize(0); + + // decompress until deflate stream ends or end of file + do { + // Add another chunk size to the output buffer + // This forces a copy of the whole buffer + p_dst_vect->resize(p_dst_vect->size() + gzip_chunk); + // Get pointer to the actual output buffer + dst = p_dst_vect->ptrw(); + + // Set the stream to the new output stream + // Since it was copied, we need to reset the stream to the new buffer + strm.next_out = &(dst[out_mark]); + strm.avail_out = gzip_chunk; + + // run inflate() on input until output buffer is full and needs to be resized + // or input runs out + do { + ret = inflate(&strm, Z_SYNC_FLUSH); + + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; + [[fallthrough]]; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + case Z_STREAM_ERROR: + WARN_PRINT(strm.msg); + (void)inflateEnd(&strm); + p_dst_vect->resize(0); + return ret; + } + } while (strm.avail_out > 0 && strm.avail_in > 0); + + out_mark += gzip_chunk; + + // Encorce max output size + if (p_max_dst_size > -1 && strm.total_out > (uint64_t)p_max_dst_size) { + (void)inflateEnd(&strm); + p_dst_vect->resize(0); + return Z_BUF_ERROR; + } + } while (ret != Z_STREAM_END); + + // If all done successfully, resize the output if it's larger than the actual output + if (ret == Z_STREAM_END && (unsigned long)p_dst_vect->size() > strm.total_out) { + p_dst_vect->resize(strm.total_out); + } + + // clean up and return + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + int Compression::zlib_level = Z_DEFAULT_COMPRESSION; int Compression::gzip_level = Z_DEFAULT_COMPRESSION; int Compression::zstd_level = 3; bool Compression::zstd_long_distance_matching = false; int Compression::zstd_window_log_size = 27; // ZSTD_WINDOWLOG_LIMIT_DEFAULT +int Compression::gzip_chunk = 16384; diff --git a/core/io/compression.h b/core/io/compression.h index f195f96ba5..c103fa8eae 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -32,6 +32,7 @@ #define COMPRESSION_H #include "core/typedefs.h" +#include "core/vector.h" class Compression { public: @@ -40,6 +41,7 @@ public: static int zstd_level; static bool zstd_long_distance_matching; static int zstd_window_log_size; + static int gzip_chunk; enum Mode { MODE_FASTLZ, @@ -51,6 +53,7 @@ public: static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD); static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); + static int decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode); Compression() {} }; diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 5938914cb0..eb684f457e 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -37,52 +37,54 @@ #include <stdio.h> -#define COMP_MAGIC 0x43454447 - -Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) { +Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) { ERR_FAIL_COND_V_MSG(file != nullptr, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open."); ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER); pos = 0; eofed = false; + use_magic = p_with_magic; if (p_mode == MODE_WRITE_AES256) { data.clear(); writing = true; file = p_base; - mode = p_mode; key = p_key; } else if (p_mode == MODE_READ) { writing = false; key = p_key; - uint32_t magic = p_base->get_32(); - ERR_FAIL_COND_V(magic != COMP_MAGIC, ERR_FILE_UNRECOGNIZED); - mode = Mode(p_base->get_32()); - ERR_FAIL_INDEX_V(mode, MODE_MAX, ERR_FILE_CORRUPT); - ERR_FAIL_COND_V(mode == 0, ERR_FILE_CORRUPT); + if (use_magic) { + uint32_t magic = p_base->get_32(); + ERR_FAIL_COND_V(magic != ENCRYPTED_HEADER_MAGIC, ERR_FILE_UNRECOGNIZED); + } unsigned char md5d[16]; p_base->get_buffer(md5d, 16); length = p_base->get_64(); + + unsigned char iv[16]; + for (int i = 0; i < 16; i++) { + iv[i] = p_base->get_8(); + } + base = p_base->get_position(); ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT); uint32_t ds = length; if (ds % 16) { ds += 16 - (ds % 16); } - data.resize(ds); uint32_t blen = p_base->get_buffer(data.ptrw(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); - CryptoCore::AESContext ctx; - ctx.set_decode_key(key.ptrw(), 256); + { + CryptoCore::AESContext ctx; - for (size_t i = 0; i < ds; i += 16) { - ctx.decrypt_ecb(&data.write[i], &data.write[i]); + ctx.set_encode_key(key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption! + ctx.decrypt_cfb(ds, iv, data.ptrw(), data.ptrw()); } data.resize(length); @@ -119,6 +121,25 @@ void FileAccessEncrypted::close() { return; } + _release(); + + file->close(); + memdelete(file); + + file = nullptr; +} + +void FileAccessEncrypted::release() { + if (!file) { + return; + } + + _release(); + + file = nullptr; +} + +void FileAccessEncrypted::_release() { if (writing) { Vector<uint8_t> compressed; size_t len = data.size(); @@ -138,27 +159,23 @@ void FileAccessEncrypted::close() { CryptoCore::AESContext ctx; ctx.set_encode_key(key.ptrw(), 256); - for (size_t i = 0; i < len; i += 16) { - ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]); + if (use_magic) { + file->store_32(ENCRYPTED_HEADER_MAGIC); } - file->store_32(COMP_MAGIC); - file->store_32(mode); - file->store_buffer(hash, 16); file->store_64(data.size()); - file->store_buffer(compressed.ptr(), compressed.size()); - file->close(); - memdelete(file); - file = nullptr; - data.clear(); + unsigned char iv[16]; + for (int i = 0; i < 16; i++) { + iv[i] = Math::rand() % 256; + file->store_8(iv[i]); + } - } else { - file->close(); - memdelete(file); + ctx.encrypt_cfb(len, iv, compressed.ptrw(), compressed.ptrw()); + + file->store_buffer(compressed.ptr(), compressed.size()); data.clear(); - file = nullptr; } } diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index e269c1e30c..fddc6842f3 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -33,6 +33,8 @@ #include "core/os/file_access.h" +#define ENCRYPTED_HEADER_MAGIC 0x43454447 + class FileAccessEncrypted : public FileAccess { public: enum Mode { @@ -42,7 +44,6 @@ public: }; private: - Mode mode = MODE_MAX; Vector<uint8_t> key; bool writing = false; FileAccess *file = nullptr; @@ -51,13 +52,17 @@ private: Vector<uint8_t> data; mutable int pos = 0; mutable bool eofed = false; + bool use_magic = true; + + void _release(); public: - Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode); + Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true); Error open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode); virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file virtual void close(); ///< close a file + virtual void release(); ///< finish and keep base file open virtual bool is_open() const; ///< true when file is open virtual String get_path() const; /// returns the path for the current open file diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index cc8d68be83..8fdbb650d4 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -30,6 +30,8 @@ #include "file_access_pack.h" +#include "core/io/file_access_encrypted.h" +#include "core/script_language.h" #include "core/version.h" #include <stdio.h> @@ -44,13 +46,14 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_ return ERR_FILE_UNRECOGNIZED; } -void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) { +void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) { PathMD5 pmd5(path.md5_buffer()); //printf("adding path %s, %lli, %lli\n", path.utf8().get_data(), pmd5.a, pmd5.b); bool exists = files.has(pmd5); PackedFile pf; + pf.encrypted = p_encrypted; pf.pack = pkg_path; pf.offset = ofs; pf.size = size; @@ -179,6 +182,11 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, ERR_FAIL_V_MSG(false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "."); } + uint32_t pack_flags = f->get_32(); + uint64_t file_base = f->get_64(); + + bool enc_directory = (pack_flags & PACK_DIR_ENCRYPTED); + for (int i = 0; i < 16; i++) { //reserved f->get_32(); @@ -186,6 +194,30 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, int file_count = f->get_32(); + if (enc_directory) { + FileAccessEncrypted *fae = memnew(FileAccessEncrypted); + if (!fae) { + f->close(); + memdelete(f); + ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory."); + } + + Vector<uint8_t> key; + key.resize(32); + for (int i = 0; i < key.size(); i++) { + key.write[i] = script_encryption_key[i]; + } + + Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false); + if (err) { + f->close(); + memdelete(f); + memdelete(fae); + ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory."); + } + f = fae; + } + for (int i = 0; i < file_count; i++) { uint32_t sl = f->get_32(); CharString cs; @@ -196,11 +228,13 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, String path; path.parse_utf8(cs.ptr()); - uint64_t ofs = f->get_64(); + uint64_t ofs = file_base + f->get_64(); uint64_t size = f->get_64(); uint8_t md5[16]; f->get_buffer(md5, 16); - PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files); + uint32_t flags = f->get_32(); + + PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED)); } f->close(); @@ -234,7 +268,7 @@ void FileAccessPack::seek(size_t p_position) { eof = false; } - f->seek(pf.offset + p_position); + f->seek(off + p_position); pos = p_position; } @@ -319,12 +353,35 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'."); f->seek(pf.offset); + off = pf.offset; + + if (pf.encrypted) { + FileAccessEncrypted *fae = memnew(FileAccessEncrypted); + if (!fae) { + ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'."); + } + + Vector<uint8_t> key; + key.resize(32); + for (int i = 0; i < key.size(); i++) { + key.write[i] = script_encryption_key[i]; + } + + Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false); + if (err) { + memdelete(fae); + ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'."); + } + f = fae; + off = 0; + } pos = 0; eof = false; } FileAccessPack::~FileAccessPack() { if (f) { + f->close(); memdelete(f); } } diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 6e316119cb..d934b0deb5 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -40,7 +40,15 @@ // Godot's packed file magic header ("GDPC" in ASCII). #define PACK_HEADER_MAGIC 0x43504447 // The current packed file format version number. -#define PACK_FORMAT_VERSION 1 +#define PACK_FORMAT_VERSION 2 + +enum PackFlags { + PACK_DIR_ENCRYPTED = 1 << 0 +}; + +enum PackFileFlags { + PACK_FILE_ENCRYPTED = 1 << 0 +}; class PackSource; @@ -56,6 +64,7 @@ public: uint64_t size; uint8_t md5[16]; PackSource *src; + bool encrypted; }; private: @@ -102,7 +111,7 @@ private: public: void add_pack_source(PackSource *p_source); - void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files); // for PackSource + void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource void set_disabled(bool p_disabled) { disabled = p_disabled; } _FORCE_INLINE_ bool is_disabled() const { return disabled; } @@ -135,6 +144,7 @@ class FileAccessPack : public FileAccess { mutable size_t pos; mutable bool eof; + uint64_t off; FileAccess *f; virtual Error _open(const String &p_path, int p_mode_flags); diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index d75ca2fdc6..ce402fe8ed 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -200,7 +200,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_ files[fname] = f; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - PackedData::get_singleton()->add_path(p_path, fname, 1, 0, md5, this, p_replace_files); + PackedData::get_singleton()->add_path(p_path, fname, 1, 0, md5, this, p_replace_files, false); //printf("packed data add path %s, %s\n", p_name.utf8().get_data(), fname.utf8().get_data()); if ((i + 1) < gi.number_entry) { diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index 374b2a5e07..5480d3c535 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -30,36 +30,58 @@ #include "pck_packer.h" +#include "core/crypto/crypto_core.h" +#include "core/io/file_access_encrypted.h" #include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION #include "core/os/file_access.h" #include "core/version.h" -static uint64_t _align(uint64_t p_n, int p_alignment) { - if (p_alignment == 0) { - return p_n; +static int _get_pad(int p_alignment, int p_n) { + int rest = p_n % p_alignment; + int pad = 0; + if (rest > 0) { + pad = p_alignment - rest; } - uint64_t rest = p_n % p_alignment; - if (rest == 0) { - return p_n; - } else { - return p_n + (p_alignment - rest); - } -} - -static void _pad(FileAccess *p_file, int p_bytes) { - for (int i = 0; i < p_bytes; i++) { - p_file->store_8(0); - } + return pad; } void PCKPacker::_bind_methods() { - ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment"), &PCKPacker::pck_start, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path"), &PCKPacker::add_file); + ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(0), DEFVAL(String()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false)); ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false)); } -Error PCKPacker::pck_start(const String &p_file, int p_alignment) { +Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &p_key, bool p_encrypt_directory) { + ERR_FAIL_COND_V_MSG((p_key.empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long)."); + + String _key = p_key.to_lower(); + key.resize(32); + for (int i = 0; i < 32; i++) { + int v = 0; + if (i * 2 < _key.length()) { + char32_t ct = _key[i * 2]; + if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = 10 + ct - 'a'; + } + v |= ct << 4; + } + + if (i * 2 + 1 < _key.length()) { + char32_t ct = _key[i * 2 + 1]; + if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = 10 + ct - 'a'; + } + v |= ct; + } + key.write[i] = v; + } + enc_dir = p_encrypt_directory; + if (file != nullptr) { memdelete(file); } @@ -76,16 +98,19 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment) { file->store_32(VERSION_MINOR); file->store_32(VERSION_PATCH); - for (int i = 0; i < 16; i++) { - file->store_32(0); // reserved + uint32_t pack_flags = 0; + if (enc_dir) { + pack_flags |= PACK_DIR_ENCRYPTED; } + file->store_32(pack_flags); // flags files.clear(); + ofs = 0; return OK; } -Error PCKPacker::add_file(const String &p_file, const String &p_src) { +Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encrypt) { FileAccess *f = FileAccess::open(p_src, FileAccess::READ); if (!f) { return ERR_FILE_CANT_OPEN; @@ -94,8 +119,32 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src) { File pf; pf.path = p_file; pf.src_path = p_src; + pf.ofs = ofs; pf.size = f->get_len(); - pf.offset_offset = 0; + + Vector<uint8_t> data = FileAccess::get_file_as_array(p_src); + { + unsigned char hash[16]; + CryptoCore::md5(data.ptr(), data.size(), hash); + pf.md5.resize(16); + for (int i = 0; i < 16; i++) { + pf.md5.write[i] = hash[i]; + } + } + pf.encrypted = p_encrypt; + + uint64_t _size = pf.size; + if (p_encrypt) { // Add encryption overhead. + if (_size % 16) { // Pad to encryption block size. + _size += 16 - (_size % 16); + } + _size += 16; // hash + _size += 8; // data size + _size += 16; // iv + } + + int pad = _get_pad(alignment, ofs + _size); + ofs = ofs + _size + pad; files.push_back(pf); @@ -108,27 +157,64 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src) { Error PCKPacker::flush(bool p_verbose) { ERR_FAIL_COND_V_MSG(!file, ERR_INVALID_PARAMETER, "File must be opened before use."); - // write the index + int64_t file_base_ofs = file->get_position(); + file->store_64(0); // files base + for (int i = 0; i < 16; i++) { + file->store_32(0); // reserved + } + + // write the index file->store_32(files.size()); + FileAccessEncrypted *fae = nullptr; + FileAccess *fhead = file; + + if (enc_dir) { + fae = memnew(FileAccessEncrypted); + ERR_FAIL_COND_V(!fae, ERR_CANT_CREATE); + + Error err = fae->open_and_parse(file, key, FileAccessEncrypted::MODE_WRITE_AES256, false); + ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); + + fhead = fae; + } + for (int i = 0; i < files.size(); i++) { - file->store_pascal_string(files[i].path); - files.write[i].offset_offset = file->get_position(); - file->store_64(0); // offset - file->store_64(files[i].size); // size - - // # empty md5 - file->store_32(0); - file->store_32(0); - file->store_32(0); - file->store_32(0); + int string_len = files[i].path.utf8().length(); + int pad = _get_pad(4, string_len); + + fhead->store_32(string_len + pad); + fhead->store_buffer((const uint8_t *)files[i].path.utf8().get_data(), string_len); + for (int j = 0; j < pad; j++) { + fhead->store_8(0); + } + + fhead->store_64(files[i].ofs); + fhead->store_64(files[i].size); // pay attention here, this is where file is + fhead->store_buffer(files[i].md5.ptr(), 16); //also save md5 for file + + uint32_t flags = 0; + if (files[i].encrypted) { + flags |= PACK_FILE_ENCRYPTED; + } + fhead->store_32(flags); + } + + if (fae) { + fae->release(); + memdelete(fae); } - uint64_t ofs = file->get_position(); - ofs = _align(ofs, alignment); + int header_padding = _get_pad(alignment, file->get_position()); + for (int i = 0; i < header_padding; i++) { + file->store_8(Math::rand() % 256); + } - _pad(file, ofs - file->get_position()); + int64_t file_base = file->get_position(); + file->seek(file_base_ofs); + file->store_64(file_base); // update files base + file->seek(file_base); const uint32_t buf_max = 65536; uint8_t *buf = memnew_arr(uint8_t, buf_max); @@ -137,26 +223,41 @@ Error PCKPacker::flush(bool p_verbose) { for (int i = 0; i < files.size(); i++) { FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ); uint64_t to_write = files[i].size; + + fae = nullptr; + FileAccess *ftmp = file; + if (files[i].encrypted) { + fae = memnew(FileAccessEncrypted); + ERR_FAIL_COND_V(!fae, ERR_CANT_CREATE); + + Error err = fae->open_and_parse(file, key, FileAccessEncrypted::MODE_WRITE_AES256, false); + ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); + ftmp = fae; + } + while (to_write > 0) { int read = src->get_buffer(buf, MIN(to_write, buf_max)); - file->store_buffer(buf, read); + ftmp->store_buffer(buf, read); to_write -= read; } - uint64_t pos = file->get_position(); - file->seek(files[i].offset_offset); // go back to store the file's offset - file->store_64(ofs); - file->seek(pos); + if (fae) { + fae->release(); + memdelete(fae); + } - ofs = _align(ofs + files[i].size, alignment); - _pad(file, ofs - pos); + int pad = _get_pad(alignment, file->get_position()); + for (int j = 0; j < pad; j++) { + file->store_8(Math::rand() % 256); + } src->close(); memdelete(src); count += 1; - if (p_verbose && files.size() > 0) { + const int file_num = files.size(); + if (p_verbose && (file_num > 0)) { if (count % 100 == 0) { - printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100); + printf("%i/%i (%.2f)\r", count, file_num, float(count) / file_num * 100); fflush(stdout); } } diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h index 2929967a68..a6054dff2c 100644 --- a/core/io/pck_packer.h +++ b/core/io/pck_packer.h @@ -40,20 +40,26 @@ class PCKPacker : public Reference { FileAccess *file = nullptr; int alignment; + uint64_t ofs = 0; + + Vector<uint8_t> key; + bool enc_dir = false; static void _bind_methods(); struct File { String path; String src_path; - int size; - uint64_t offset_offset; + uint64_t ofs; + uint64_t size; + bool encrypted; + Vector<uint8_t> md5; }; Vector<File> files; public: - Error pck_start(const String &p_file, int p_alignment = 0); - Error add_file(const String &p_file, const String &p_src); + Error pck_start(const String &p_file, int p_alignment = 0, const String &p_key = String(), bool p_encrypt_directory = false); + Error add_file(const String &p_file, const String &p_src, bool p_encrypt = false); Error flush(bool p_verbose = false); PCKPacker() {} diff --git a/core/math/basis.h b/core/math/basis.h index 985fb0e44f..a86937ceb4 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -36,7 +36,11 @@ class Basis { public: - Vector3 elements[3]; + Vector3 elements[3] = { + Vector3(1, 0, 0), + Vector3(0, 1, 0), + Vector3(0, 0, 1) + }; _FORCE_INLINE_ const Vector3 &operator[](int axis) const { return elements[axis]; @@ -254,17 +258,7 @@ public: elements[2] = row2; } - _FORCE_INLINE_ Basis() { - elements[0][0] = 1; - elements[0][1] = 0; - elements[0][2] = 0; - elements[1][0] = 0; - elements[1][1] = 1; - elements[1][2] = 0; - elements[2][0] = 0; - elements[2][1] = 0; - elements[2][2] = 1; - } + _FORCE_INLINE_ Basis() {} }; _FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) { diff --git a/core/math/vector2.h b/core/math/vector2.h index 8a08d3bf64..0966d3392f 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -114,10 +114,10 @@ struct Vector2 { bool operator==(const Vector2 &p_vec2) const; bool operator!=(const Vector2 &p_vec2) const; - bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } - bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); } - bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); } + bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } + bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } + bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } + bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } real_t angle() const; diff --git a/core/math/vector3.h b/core/math/vector3.h index 0bc1a467f2..5370b297f1 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -322,8 +322,8 @@ bool Vector3::operator!=(const Vector3 &p_v) const { } bool Vector3::operator<(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z < p_v.z; } else { return y < p_v.y; @@ -334,8 +334,8 @@ bool Vector3::operator<(const Vector3 &p_v) const { } bool Vector3::operator>(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z > p_v.z; } else { return y > p_v.y; @@ -346,8 +346,8 @@ bool Vector3::operator>(const Vector3 &p_v) const { } bool Vector3::operator<=(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z <= p_v.z; } else { return y < p_v.y; @@ -358,8 +358,8 @@ bool Vector3::operator<=(const Vector3 &p_v) const { } bool Vector3::operator>=(const Vector3 &p_v) const { - if (Math::is_equal_approx(x, p_v.x)) { - if (Math::is_equal_approx(y, p_v.y)) { + if (x == p_v.x) { + if (y == p_v.y) { return z >= p_v.z; } else { return y > p_v.y; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 7a1fdbaafe..0ebb2f04a1 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -630,14 +630,14 @@ struct _VariantCall { VCALL_LOCALMEM0R(Array, min); static void _call_PackedByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) { - PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem); + Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array); String s; - if (ba->size() > 0) { - const uint8_t *r = ba->ptr(); + if (ba->array.size() > 0) { + const uint8_t *r = ba->array.ptr(); CharString cs; - cs.resize(ba->size() + 1); - copymem(cs.ptrw(), r, ba->size()); - cs[ba->size()] = 0; + cs.resize(ba->array.size() + 1); + copymem(cs.ptrw(), r, ba->array.size()); + cs[ba->array.size()] = 0; s = cs.get_data(); } @@ -645,11 +645,12 @@ struct _VariantCall { } static void _call_PackedByteArray_get_string_from_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) { - PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem); + Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array); + String s; - if (ba->size() > 0) { - const uint8_t *r = ba->ptr(); - s.parse_utf8((const char *)r, ba->size()); + if (ba->array.size() > 0) { + const uint8_t *r = ba->array.ptr(); + s.parse_utf8((const char *)r, ba->array.size()); } r_ret = s; } @@ -675,22 +676,23 @@ struct _VariantCall { } static void _call_PackedByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) { - PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem); + Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array); PackedByteArray compressed; - if (ba->size() > 0) { - Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); - compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); - int result = Compression::compress(compressed.ptrw(), ba->ptr(), ba->size(), mode); + if (ba->array.size() > 0) { + Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); + compressed.resize(Compression::get_max_compressed_buffer_size(ba->array.size(), mode)); + int result = Compression::compress(compressed.ptrw(), ba->array.ptr(), ba->array.size(), mode); result = result >= 0 ? result : 0; compressed.resize(result); } + r_ret = compressed; } static void _call_PackedByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) { - PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem); + Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array); PackedByteArray decompressed; Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]); @@ -702,7 +704,7 @@ struct _VariantCall { } decompressed.resize(buffer_size); - int result = Compression::decompress(decompressed.ptrw(), buffer_size, ba->ptr(), ba->size(), mode); + int result = Compression::decompress(decompressed.ptrw(), buffer_size, ba->array.ptr(), ba->array.size(), mode); result = result >= 0 ? result : 0; decompressed.resize(result); @@ -710,14 +712,31 @@ struct _VariantCall { r_ret = decompressed; } + static void _call_PackedByteArray_decompress_dynamic(Variant &r_ret, Variant &p_self, const Variant **p_args) { + Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array); + PackedByteArray decompressed; + int max_output_size = (int)(*p_args[0]); + Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]); + + int result = Compression::decompress_dynamic(&decompressed, max_output_size, ba->array.ptr(), ba->array.size(), mode); + + if (result == OK) { + r_ret = decompressed; + } else { + decompressed.clear(); + r_ret = decompressed; + ERR_FAIL_MSG("Decompression failed."); + } + } + static void _call_PackedByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) { - PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem); - if (ba->size() == 0) { + Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array); + if (ba->array.size() == 0) { r_ret = String(); return; } - const uint8_t *r = ba->ptr(); - String s = String::hex_encode_buffer(&r[0], ba->size()); + const uint8_t *r = ba->array.ptr(); + String s = String::hex_encode_buffer(&r[0], ba->array.size()); r_ret = s; } @@ -2175,6 +2194,7 @@ void register_variant_methods() { ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, hex_encode, varray()); ADDFUNC1R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, compress, INT, "compression_mode", varray(0)); ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0)); + ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, decompress_dynamic, INT, "max_output_size", INT, "compression_mode", varray(0)); ADDFUNC0R(PACKED_INT32_ARRAY, INT, PackedInt32Array, size, varray()); ADDFUNC0R(PACKED_INT32_ARRAY, BOOL, PackedInt32Array, empty, varray()); diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 61df5e092e..20579e0159 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -119,7 +119,8 @@ <return type="Variant"> </return> <description> - Returns the last element of the array. Throws an error and returns [code]null[/code] if the array is empty. + Returns the last element of the array. Prints an error and returns [code]null[/code] if the array is empty. + [b]Note:[/b] Calling this function is not the same as writing [code]array[-1][/code]. If the array is empty, accessing by index will pause project execution when running from the editor. </description> </method> <method name="bsearch"> @@ -216,7 +217,8 @@ <return type="Variant"> </return> <description> - Returns the first element of the array. Throws an error and returns [code]null[/code] if the array is empty. + Returns the first element of the array. Prints an error and returns [code]null[/code] if the array is empty. + [b]Note:[/b] Calling this function is not the same as writing [code]array[0][/code]. If the array is empty, accessing by index will pause project execution when running from the editor. </description> </method> <method name="has"> @@ -283,14 +285,14 @@ <return type="Variant"> </return> <description> - Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty. + Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. </description> </method> <method name="pop_front"> <return type="Variant"> </return> <description> - Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty. + Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty, wwithout printing an error message. </description> </method> <method name="push_back"> @@ -317,7 +319,7 @@ <argument index="0" name="position" type="int"> </argument> <description> - Removes an element from the array by index. + Removes an element from the array by index. If the index does not exist in the array, nothing happens. </description> </method> <method name="resize"> diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml index 3812b45b13..bf4d9383ac 100644 --- a/doc/classes/BaseButton.xml +++ b/doc/classes/BaseButton.xml @@ -65,8 +65,8 @@ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false"> If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if [member toggle_mode] is active). </member> - <member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut"> - [ShortCut] associated to the button. + <member name="shortcut" type="Shortcut" setter="set_shortcut" getter="get_shortcut"> + [Shortcut] associated to the button. </member> <member name="shortcut_in_tooltip" type="bool" setter="set_shortcut_in_tooltip" getter="is_shortcut_in_tooltip_enabled" default="true"> If [code]true[/code], the button will add information about its shortcut in the tooltip. diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml index e13dc43104..6ee794c5c4 100644 --- a/doc/classes/GridContainer.xml +++ b/doc/classes/GridContainer.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="GridContainer" inherits="Container" version="4.0"> <brief_description> - Grid container used to arrange elements in a grid like layout. + Grid container used to arrange Control-derived children in a grid like layout. </brief_description> <description> - Grid container will arrange its children in a grid like structure, the grid columns are specified using the [member columns] property and the number of rows will be equal to the number of children in the container divided by the number of columns. For example, if the container has 5 children, and 2 columns, there will be 3 rows in the container. + GridContainer will arrange its Control-derived children in a grid like structure, the grid columns are specified using the [member columns] property and the number of rows will be equal to the number of children in the container divided by the number of columns. For example, if the container has 5 children, and 2 columns, there will be 3 rows in the container. Notice that grid layout will preserve the columns and rows for every size of the container, and that empty columns will be expanded automatically. + [b]Note:[/b] GridContainer only works with child nodes inheriting from Control. It won't rearrange child nodes inheriting from Node2D. </description> <tutorials> </tutorials> @@ -13,7 +14,7 @@ </methods> <members> <member name="columns" type="int" setter="set_columns" getter="get_columns" default="1"> - The number of columns in the [GridContainer]. If modified, [GridContainer] reorders its children to accommodate the new layout. + The number of columns in the [GridContainer]. If modified, [GridContainer] reorders its Control-derived children to accommodate the new layout. </member> </members> <constants> diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index 4801af07d3..2ba2249d21 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -64,6 +64,11 @@ add_child(texture_rect) texture_rect.texture = texture [/codeblock] + + [b]Gzipped response bodies[/b] + HttpRequest will automatically handle decompression of response bodies. + A "Accept-Encoding" header will be automatically added to each of your requests, unless one is already specified. + Any response with a "Content-Encoding: gzip" header will automatically be decompressed and delivered to you as a uncompressed bytes. [b]Note:[/b] When performing HTTP requests from a project exported to HTML5, keep in mind the remote server may not allow requests from foreign origins due to [url=https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS]CORS[/url]. If you host the server in question, you should modify its backend to allow requests from foreign origins by adding the [code]Access-Control-Allow-Origin: *[/code] HTTP header. </description> <tutorials> @@ -119,10 +124,28 @@ [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example. </description> </method> + <method name="request_raw"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="url" type="String"> + </argument> + <argument index="1" name="custom_headers" type="PackedStringArray" default="PackedStringArray( )"> + </argument> + <argument index="2" name="ssl_validate_domain" type="bool" default="true"> + </argument> + <argument index="3" name="method" type="int" enum="HTTPClient.Method" default="0"> + </argument> + <argument index="4" name="request_data_raw" type="PackedByteArray" default="PackedByteArray()"> + </argument> + <description> + Creates request on the underlying [HTTPClient] using a raw array of bytes for the request body. If there is no configuration errors, it tries to connect using [method HTTPClient.connect_to_host] and passes parameters onto [method HTTPClient.request]. + Returns [constant OK] if request is successfully created. (Does not imply that the server has responded), [constant ERR_UNCONFIGURED] if not in the tree, [constant ERR_BUSY] if still processing previous request, [constant ERR_INVALID_PARAMETER] if given string is not a valid URL format, or [constant ERR_CANT_CONNECT] if not using thread and the [HTTPClient] cannot connect to host. + </description> + </method> </methods> <members> <member name="body_size_limit" type="int" setter="set_body_size_limit" getter="get_body_size_limit" default="-1"> - Maximum allowed size for response bodies. + Maximum allowed size for response bodies. If the response body is compressed, this will be used as the maximum allowed size for the decompressed body. </member> <member name="download_chunk_size" type="int" setter="set_download_chunk_size" getter="get_download_chunk_size" default="4096"> The size of the buffer used and maximum bytes to read per iteration. See [member HTTPClient.read_chunk_size]. @@ -139,6 +162,12 @@ <member name="use_threads" type="bool" setter="set_use_threads" getter="is_using_threads" default="false"> If [code]true[/code], multithreading is used to improve performance. </member> + <member name="accept_gzip" type="bool" setter="set_accept_gzip" getter="is_accepting_gzip" default="true"> + If [code]true[/code], this header will be added to each request: [code]Accept-Encoding: gzip, deflate[/code] telling servers that it's okay to compress response bodies. + Any Reponse body declaring a [code]Content-Encoding[/code] of either [code]gzip[/code] or [code]deflate[/code] will then be automatically decompressed, and the uncompressed bytes will be delivered via [code]request_completed[/code]. + If the user has specified their own [code]Accept-Encoding[/code] header, then no header will be added regaurdless of [code]accept_gzip[/code]. + If [code]false[/code] no header will be added, and no decompression will be performed on response bodies. The raw bytes of the response body will be returned via [code]request_completed[/code]. + </member> </members> <signals> <signal name="request_completed"> diff --git a/doc/classes/PCKPacker.xml b/doc/classes/PCKPacker.xml index 314869be49..6b500d5ac3 100644 --- a/doc/classes/PCKPacker.xml +++ b/doc/classes/PCKPacker.xml @@ -23,6 +23,8 @@ </argument> <argument index="1" name="source_path" type="String"> </argument> + <argument index="2" name="encrypt" type="bool" default="false"> + </argument> <description> Adds the [code]source_path[/code] file to the current PCK package at the [code]pck_path[/code] internal path (should start with [code]res://[/code]). </description> @@ -43,6 +45,10 @@ </argument> <argument index="1" name="alignment" type="int" default="0"> </argument> + <argument index="2" name="key" type="String" default=""""> + </argument> + <argument index="3" name="encrypt_directory" type="bool" default="false"> + </argument> <description> Creates a new PCK file with the name [code]pck_name[/code]. The [code].pck[/code] file extension isn't added automatically, so it should be part of [code]pck_name[/code] (even though it's not required). </description> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index b1c4e54854..7bfc502fbb 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -57,6 +57,20 @@ Returns a new [PackedByteArray] with the data decompressed. Set [code]buffer_size[/code] to the size of the uncompressed data. Set the compression mode using one of [enum File.CompressionMode]'s constants. </description> </method> + <method name="decompress_dynamic"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="max_output_size" type="int" default="0"> + </argument> + <argument index="1" name="compression_mode" type="int" default="0"> + </argument> + <description> + Returns a new [PackedByteArray] with the data decompressed. Set the compression mode using one of [enum File.CompressionMode]'s constants. [b]This method only accepts gzip and deflate compression modes.[/b] + This method is potentially slower than [code]decompress[/code], as it may have to re-allocate it's output buffer multiple times while decompressing, where as [code]decompress[/code] knows it's output buffer size from the begining. + + GZIP has a maximal compression ratio of 1032:1, meaning it's very possible for a small compressed payload to decompress to a potentially very large output. To guard against this, you may provide a maximum size this function is allowed to allocate in bytes via [code]max_output_size[/code]. Passing -1 will allow for unbounded output. If any positive value is passed, and the decompression exceeds that ammount in bytes, then an error will be returned. + </description> + </method> <method name="empty"> <return type="bool"> </return> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 2af0f500a0..b1ec9a222a 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -29,14 +29,14 @@ <method name="add_check_shortcut"> <return type="void"> </return> - <argument index="0" name="shortcut" type="ShortCut"> + <argument index="0" name="shortcut" type="Shortcut"> </argument> <argument index="1" name="id" type="int" default="-1"> </argument> <argument index="2" name="global" type="bool" default="false"> </argument> <description> - Adds a new checkable item and assigns the specified [ShortCut] to it. Sets the label of the checkbox to the [ShortCut]'s name. + Adds a new checkable item and assigns the specified [Shortcut] to it. Sets the label of the checkbox to the [Shortcut]'s name. An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index. [b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it. </description> @@ -63,14 +63,14 @@ </return> <argument index="0" name="texture" type="Texture2D"> </argument> - <argument index="1" name="shortcut" type="ShortCut"> + <argument index="1" name="shortcut" type="Shortcut"> </argument> <argument index="2" name="id" type="int" default="-1"> </argument> <argument index="3" name="global" type="bool" default="false"> </argument> <description> - Adds a new checkable item and assigns the specified [ShortCut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [ShortCut]'s name. + Adds a new checkable item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name. An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index. [b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it. </description> @@ -111,7 +111,7 @@ </return> <argument index="0" name="texture" type="Texture2D"> </argument> - <argument index="1" name="shortcut" type="ShortCut"> + <argument index="1" name="shortcut" type="Shortcut"> </argument> <argument index="2" name="id" type="int" default="-1"> </argument> @@ -126,14 +126,14 @@ </return> <argument index="0" name="texture" type="Texture2D"> </argument> - <argument index="1" name="shortcut" type="ShortCut"> + <argument index="1" name="shortcut" type="Shortcut"> </argument> <argument index="2" name="id" type="int" default="-1"> </argument> <argument index="3" name="global" type="bool" default="false"> </argument> <description> - Adds a new item and assigns the specified [ShortCut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [ShortCut]'s name. + Adds a new item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name. An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index. </description> </method> @@ -188,14 +188,14 @@ <method name="add_radio_check_shortcut"> <return type="void"> </return> - <argument index="0" name="shortcut" type="ShortCut"> + <argument index="0" name="shortcut" type="Shortcut"> </argument> <argument index="1" name="id" type="int" default="-1"> </argument> <argument index="2" name="global" type="bool" default="false"> </argument> <description> - Adds a new radio check button and assigns a [ShortCut] to it. Sets the label of the checkbox to the [ShortCut]'s name. + Adds a new radio check button and assigns a [Shortcut] to it. Sets the label of the checkbox to the [Shortcut]'s name. An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index. [b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it. </description> @@ -212,14 +212,14 @@ <method name="add_shortcut"> <return type="void"> </return> - <argument index="0" name="shortcut" type="ShortCut"> + <argument index="0" name="shortcut" type="Shortcut"> </argument> <argument index="1" name="id" type="int" default="-1"> </argument> <argument index="2" name="global" type="bool" default="false"> </argument> <description> - Adds a [ShortCut]. + Adds a [Shortcut]. An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index. </description> </method> @@ -303,12 +303,12 @@ </description> </method> <method name="get_item_shortcut" qualifiers="const"> - <return type="ShortCut"> + <return type="Shortcut"> </return> <argument index="0" name="idx" type="int"> </argument> <description> - Returns the [ShortCut] associated with the specified [code]idx[/code] item. + Returns the [Shortcut] associated with the specified [code]idx[/code] item. </description> </method> <method name="get_item_submenu" qualifiers="const"> @@ -521,12 +521,12 @@ </return> <argument index="0" name="idx" type="int"> </argument> - <argument index="1" name="shortcut" type="ShortCut"> + <argument index="1" name="shortcut" type="Shortcut"> </argument> <argument index="2" name="global" type="bool" default="false"> </argument> <description> - Sets a [ShortCut] for the specified item [code]idx[/code]. + Sets a [Shortcut] for the specified item [code]idx[/code]. </description> </method> <method name="set_item_shortcut_disabled"> @@ -537,7 +537,7 @@ <argument index="1" name="disabled" type="bool"> </argument> <description> - Disables the [ShortCut] of the specified index [code]idx[/code]. + Disables the [Shortcut] of the specified index [code]idx[/code]. </description> </method> <method name="set_item_submenu"> diff --git a/doc/classes/ShortCut.xml b/doc/classes/Shortcut.xml index 9a2a761969..55bbb083c9 100644 --- a/doc/classes/ShortCut.xml +++ b/doc/classes/Shortcut.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ShortCut" inherits="Resource" version="4.0"> +<class name="Shortcut" inherits="Resource" version="4.0"> <brief_description> A shortcut for binding input. </brief_description> diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index 3fc1db9dc6..ef1f370185 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -36,6 +36,13 @@ Returns [code]true[/code] if the offset buttons (the ones that appear when there's not enough space for all tabs) are visible. </description> </method> + <method name="get_previous_tab" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the previously active tab index. + </description> + </method> <method name="get_select_with_rmb" qualifiers="const"> <return type="bool"> </return> diff --git a/doc/classes/Texture3D.xml b/doc/classes/Texture3D.xml new file mode 100644 index 0000000000..85e940716d --- /dev/null +++ b/doc/classes/Texture3D.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Texture3D" inherits="Texture" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_data" qualifiers="const"> + <return type="Image[]"> + </return> + <description> + </description> + </method> + <method name="get_depth" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_format" qualifiers="const"> + <return type="int" enum="Image.Format"> + </return> + <description> + </description> + </method> + <method name="get_height" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_width" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="has_mipmaps" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml index 8e389e0b40..0c83ffffe4 100644 --- a/doc/classes/VisualShaderNodeTexture.xml +++ b/doc/classes/VisualShaderNodeTexture.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTexture" inherits="VisualShaderNode" version="4.0"> <brief_description> - Performs a texture lookup within the visual shader graph. + Performs a 2D texture lookup within the visual shader graph. </brief_description> <description> Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from. diff --git a/doc/classes/VisualShaderNodeTexture3D.xml b/doc/classes/VisualShaderNodeTexture3D.xml new file mode 100644 index 0000000000..17929e823e --- /dev/null +++ b/doc/classes/VisualShaderNodeTexture3D.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTexture3D" inherits="VisualShaderNodeSample3D" version="4.0"> + <brief_description> + Performs a 3D texture lookup within the visual shader graph. + </brief_description> + <description> + Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="texture" type="Texture3D" setter="set_texture" getter="get_texture"> + A source texture. Used if [member VisualShaderNodeSample3D.source] is set to [constant VisualShaderNodeSample3D.SOURCE_TEXTURE]. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTexture3DUniform.xml b/doc/classes/VisualShaderNodeTexture3DUniform.xml new file mode 100644 index 0000000000..d9e9acf117 --- /dev/null +++ b/doc/classes/VisualShaderNodeTexture3DUniform.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTexture3DUniform" inherits="VisualShaderNodeTextureUniform" version="4.0"> + <brief_description> + Provides a 3D texture uniform within the visual shader graph. + </brief_description> + <description> + Translated to [code]uniform sampler3D[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index aae476ccf4..cbde7d593a 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -144,7 +144,10 @@ EditorAbout::EditorAbout() { List<String> dev_sections; dev_sections.push_back(TTR("Project Founders")); dev_sections.push_back(TTR("Lead Developer")); - dev_sections.push_back(TTR("Project Manager ")); // " " appended to distinguish between 'project supervisor' and 'project list' + // TRANSLATORS: This refers to a job title. + // The trailing space is used to distinguish with the project list application, + // you do not have to keep it in your translation. + dev_sections.push_back(TTR("Project Manager ")); dev_sections.push_back(TTR("Developers")); const char *const *dev_src[] = { AUTHORS_FOUNDERS, AUTHORS_LEAD_DEVELOPERS, AUTHORS_PROJECT_MANAGERS, AUTHORS_DEVELOPERS }; diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 16e69734d3..1d7429eb64 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -32,6 +32,7 @@ #include "core/crypto/crypto_core.h" #include "core/io/config_file.h" +#include "core/io/file_access_encrypted.h" #include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -222,6 +223,42 @@ String EditorExportPreset::get_custom_features() const { return custom_features; } +void EditorExportPreset::set_enc_in_filter(const String &p_filter) { + enc_in_filters = p_filter; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_enc_in_filter() const { + return enc_in_filters; +} + +void EditorExportPreset::set_enc_ex_filter(const String &p_filter) { + enc_ex_filters = p_filter; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_enc_ex_filter() const { + return enc_ex_filters; +} + +void EditorExportPreset::set_enc_pck(bool p_enabled) { + enc_pck = p_enabled; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::get_enc_pck() const { + return enc_pck; +} + +void EditorExportPreset::set_enc_directory(bool p_enabled) { + enc_directory = p_enabled; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::get_enc_directory() const { + return enc_directory; +} + void EditorExportPreset::set_script_export_mode(int p_mode) { script_mode = p_mode; EditorExport::singleton->save_presets(); @@ -292,20 +329,55 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) } } -Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { +Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { PackData *pd = (PackData *)p_userdata; SavedData sd; sd.path_utf8 = p_path.utf8(); sd.ofs = pd->f->get_position(); sd.size = p_data.size(); + sd.encrypted = false; + + for (int i = 0; i < p_enc_in_filters.size(); ++i) { + if (p_path.matchn(p_enc_in_filters[i]) || p_path.replace("res://", "").matchn(p_enc_in_filters[i])) { + sd.encrypted = true; + break; + } + } + + for (int i = 0; i < p_enc_ex_filters.size(); ++i) { + if (p_path.matchn(p_enc_ex_filters[i]) || p_path.replace("res://", "").matchn(p_enc_ex_filters[i])) { + sd.encrypted = false; + break; + } + } - pd->f->store_buffer(p_data.ptr(), p_data.size()); - int pad = _get_pad(PCK_PADDING, sd.size); + FileAccessEncrypted *fae = nullptr; + FileAccess *ftmp = pd->f; + + if (sd.encrypted) { + fae = memnew(FileAccessEncrypted); + ERR_FAIL_COND_V(!fae, ERR_SKIP); + + Error err = fae->open_and_parse(ftmp, p_key, FileAccessEncrypted::MODE_WRITE_AES256, false); + ERR_FAIL_COND_V(err != OK, ERR_SKIP); + ftmp = fae; + } + + // Store file content. + ftmp->store_buffer(p_data.ptr(), p_data.size()); + + if (fae) { + fae->release(); + memdelete(fae); + } + + int pad = _get_pad(PCK_PADDING, pd->f->get_position()); for (int i = 0; i < pad; i++) { - pd->f->store_8(0); + pd->f->store_8(Math::rand() % 256); } + // Store MD5 of original file. { unsigned char hash[16]; CryptoCore::md5(p_data.ptr(), p_data.size(), hash); @@ -324,7 +396,7 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa return OK; } -Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { +Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { String path = p_path.replace_first("res://", ""); ZipData *zd = (ZipData *)p_userdata; @@ -694,6 +766,61 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & _edit_filter_list(paths, p_preset->get_include_filter(), false); _edit_filter_list(paths, p_preset->get_exclude_filter(), true); + // Get encryption filters. + bool enc_pck = p_preset->get_enc_pck(); + Vector<String> enc_in_filters; + Vector<String> enc_ex_filters; + Vector<uint8_t> key; + + if (enc_pck) { + Vector<String> enc_in_split = p_preset->get_enc_in_filter().split(","); + for (int i = 0; i < enc_in_split.size(); i++) { + String f = enc_in_split[i].strip_edges(); + if (f.empty()) { + continue; + } + enc_in_filters.push_back(f); + } + + Vector<String> enc_ex_split = p_preset->get_enc_ex_filter().split(","); + for (int i = 0; i < enc_ex_split.size(); i++) { + String f = enc_ex_split[i].strip_edges(); + if (f.empty()) { + continue; + } + enc_ex_filters.push_back(f); + } + + // Get encryption key. + String script_key = p_preset->get_script_encryption_key().to_lower(); + key.resize(32); + if (script_key.length() == 64) { + for (int i = 0; i < 32; i++) { + int v = 0; + if (i * 2 < script_key.length()) { + char32_t ct = script_key[i * 2]; + if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = 10 + ct - 'a'; + } + v |= ct << 4; + } + + if (i * 2 + 1 < script_key.length()) { + char32_t ct = script_key[i * 2 + 1]; + if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = 10 + ct - 'a'; + } + v |= ct; + } + key.write[i] = v; + } + } + } + Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); for (int i = 0; i < export_plugins.size(); i++) { export_plugins.write[i]->set_export_preset(p_preset); @@ -704,7 +831,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } } for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { - p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size()); + p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key); } export_plugins.write[i]->_clear(); @@ -756,14 +883,14 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & if (remap == "path") { String remapped_path = config->get_value("remap", remap); Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); - err = p_func(p_udata, remapped_path, array, idx, total); + err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); } else if (remap.begins_with("path.")) { String feature = remap.get_slice(".", 1); if (remap_features.has(feature)) { String remapped_path = config->get_value("remap", remap); Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); - err = p_func(p_udata, remapped_path, array, idx, total); + err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); } } } @@ -774,7 +901,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & //also save the .import file Vector<uint8_t> array = FileAccess::get_file_as_array(path + ".import"); - err = p_func(p_udata, path + ".import", array, idx, total); + err = p_func(p_udata, path + ".import", array, idx, total, enc_in_filters, enc_ex_filters, key); if (err != OK) { return err; @@ -795,7 +922,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { - p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total); + p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key); if (export_plugins[i]->extra_files[j].remap) { do_export = false; //if remap, do not path_remaps.push_back(path); @@ -815,7 +942,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & //just store it as it comes if (do_export) { Vector<uint8_t> array = FileAccess::get_file_as_array(path); - p_func(p_udata, path, array, idx, total); + p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); } } @@ -851,7 +978,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & new_file.write[j] = utf8[j]; } - p_func(p_udata, from + ".remap", new_file, idx, total); + p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key); } } else { //old remap mode, will still work, but it's unused because it's not multiple pck export friendly @@ -864,11 +991,11 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image"); if (icon != String() && FileAccess::exists(icon)) { Vector<uint8_t> array = FileAccess::get_file_as_array(icon); - p_func(p_udata, icon, array, idx, total); + p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key); } if (splash != String() && FileAccess::exists(splash) && icon != splash) { Vector<uint8_t> array = FileAccess::get_file_as_array(splash); - p_func(p_udata, splash, array, idx, total); + p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key); } String config_file = "project.binary"; @@ -877,7 +1004,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); DirAccess::remove_file_or_error(engine_cfb); - p_func(p_udata, "res://" + config_file, data, idx, total); + p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key); return OK; } @@ -953,6 +1080,17 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c f->store_32(VERSION_MINOR); f->store_32(VERSION_PATCH); + uint32_t pack_flags = 0; + bool enc_pck = p_preset->get_enc_pck(); + bool enc_directory = p_preset->get_enc_directory(); + if (enc_pck && enc_directory) { + pack_flags |= PACK_DIR_ENCRYPTED; + } + f->store_32(pack_flags); // flags + + uint64_t file_base_ofs = f->get_position(); + f->store_64(0); // files base + for (int i = 0; i < 16; i++) { //reserved f->store_32(0); @@ -960,40 +1098,82 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c f->store_32(pd.file_ofs.size()); //amount of files - int64_t header_size = f->get_position(); + FileAccessEncrypted *fae = nullptr; + FileAccess *fhead = f; + + if (enc_pck && enc_directory) { + String script_key = p_preset->get_script_encryption_key().to_lower(); + Vector<uint8_t> key; + key.resize(32); + if (script_key.length() == 64) { + for (int i = 0; i < 32; i++) { + int v = 0; + if (i * 2 < script_key.length()) { + char32_t ct = script_key[i * 2]; + if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = 10 + ct - 'a'; + } + v |= ct << 4; + } - //precalculate header size + if (i * 2 + 1 < script_key.length()) { + char32_t ct = script_key[i * 2 + 1]; + if (ct >= '0' && ct <= '9') { + ct = ct - '0'; + } else if (ct >= 'a' && ct <= 'f') { + ct = 10 + ct - 'a'; + } + v |= ct; + } + key.write[i] = v; + } + } + fae = memnew(FileAccessEncrypted); + ERR_FAIL_COND_V(!fae, ERR_SKIP); - for (int i = 0; i < pd.file_ofs.size(); i++) { - header_size += 4; // size of path string (32 bits is enough) - int string_len = pd.file_ofs[i].path_utf8.length(); - header_size += string_len + _get_pad(4, string_len); ///size of path string - header_size += 8; // offset to file _with_ header size included - header_size += 8; // size of file - header_size += 16; // md5 - } + err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_WRITE_AES256, false); + ERR_FAIL_COND_V(err != OK, ERR_SKIP); - int header_padding = _get_pad(PCK_PADDING, header_size); + fhead = fae; + } for (int i = 0; i < pd.file_ofs.size(); i++) { int string_len = pd.file_ofs[i].path_utf8.length(); int pad = _get_pad(4, string_len); - f->store_32(string_len + pad); - f->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len); + fhead->store_32(string_len + pad); + fhead->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len); for (int j = 0; j < pad; j++) { - f->store_8(0); + fhead->store_8(0); } - f->store_64(pd.file_ofs[i].ofs + header_padding + header_size); - f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is - f->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file + fhead->store_64(pd.file_ofs[i].ofs); + fhead->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is + fhead->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file + uint32_t flags = 0; + if (pd.file_ofs[i].encrypted) { + flags |= PACK_FILE_ENCRYPTED; + } + fhead->store_32(flags); } + if (fae) { + fae->release(); + memdelete(fae); + } + + int header_padding = _get_pad(PCK_PADDING, f->get_position()); for (int i = 0; i < header_padding; i++) { - f->store_8(0); + f->store_8(Math::rand() % 256); } + uint64_t file_base = f->get_position(); + f->seek(file_base_ofs); + f->store_64(file_base); // update files base + f->seek(file_base); + // Save the rest of the data. ftmp = FileAccess::open(tmppath, FileAccess::READ); @@ -1162,6 +1342,10 @@ void EditorExport::_save() { config->set_value(section, "exclude_filter", preset->get_exclude_filter()); config->set_value(section, "export_path", preset->get_export_path()); config->set_value(section, "patch_list", preset->get_patches()); + config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); + config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); + config->set_value(section, "encrypt_pck", preset->get_enc_pck()); + config->set_value(section, "encrypt_directory", preset->get_enc_directory()); config->set_value(section, "script_export_mode", preset->get_script_export_mode()); config->set_value(section, "script_encryption_key", preset->get_script_encryption_key()); @@ -1337,6 +1521,18 @@ void EditorExport::load_config() { preset->add_patch(patch_list[i]); } + if (config->has_section_key(section, "encrypt_pck")) { + preset->set_enc_pck(config->get_value(section, "encrypt_pck")); + } + if (config->has_section_key(section, "encrypt_directory")) { + preset->set_enc_directory(config->get_value(section, "encrypt_directory")); + } + if (config->has_section_key(section, "encryption_include_filters")) { + preset->set_enc_in_filter(config->get_value(section, "encryption_include_filters")); + } + if (config->has_section_key(section, "encryption_exclude_filters")) { + preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters")); + } if (config->has_section_key(section, "script_export_mode")) { preset->set_script_export_mode(config->get_value(section, "script_export_mode")); } diff --git a/editor/editor_export.h b/editor/editor_export.h index bb701b94ec..ac1051571c 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -55,7 +55,6 @@ public: enum ScriptExportMode { MODE_SCRIPT_TEXT, MODE_SCRIPT_COMPILED, - MODE_SCRIPT_ENCRYPTED, }; private: @@ -81,6 +80,11 @@ private: String custom_features; + String enc_in_filters; + String enc_ex_filters; + bool enc_pck = false; + bool enc_directory = false; + int script_mode = MODE_SCRIPT_COMPILED; String script_key; @@ -129,6 +133,18 @@ public: void set_export_path(const String &p_path); String get_export_path() const; + void set_enc_in_filter(const String &p_filter); + String get_enc_in_filter() const; + + void set_enc_ex_filter(const String &p_filter); + String get_enc_ex_filter() const; + + void set_enc_pck(bool p_enabled); + bool get_enc_pck() const; + + void set_enc_directory(bool p_enabled); + bool get_enc_directory() const; + void set_script_export_mode(int p_mode); int get_script_export_mode() const; @@ -156,13 +172,14 @@ class EditorExportPlatform : public Reference { GDCLASS(EditorExportPlatform, Reference); public: - typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total); + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); private: struct SavedData { uint64_t ofs; uint64_t size; + bool encrypted; Vector<uint8_t> md5; CharString path_utf8; @@ -192,8 +209,8 @@ private: void _export_find_dependencies(const String &p_path, Set<String> &p_paths); void gen_debug_flags(Vector<String> &r_flags, int p_flags); - static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total); - static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total); + static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); void _edit_files_with_filter(DirAccess *da, const Vector<String> &p_filters, Set<String> &r_list, bool exclude); void _edit_filter_list(Set<String> &r_list, const String &p_filter, bool exclude); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e90f30496c..4835b4beab 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -157,6 +157,7 @@ #include "editor/plugins/sprite_frames_editor_plugin.h" #include "editor/plugins/style_box_editor_plugin.h" #include "editor/plugins/text_editor.h" +#include "editor/plugins/texture_3d_editor_plugin.h" #include "editor/plugins/texture_editor_plugin.h" #include "editor/plugins/texture_layered_editor_plugin.h" #include "editor/plugins/texture_region_editor_plugin.h" @@ -2818,9 +2819,9 @@ void EditorNode::_discard_changes(const String &p_str) { } void EditorNode::_update_file_menu_opened() { - Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene"); + Ref<Shortcut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene"); close_scene_sc->set_name(TTR("Close Scene")); - Ref<ShortCut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene"); + Ref<Shortcut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene"); reopen_closed_scene_sc->set_name(TTR("Reopen Closed Scene")); PopupMenu *pop = file_menu->get_popup(); pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.empty()); @@ -4713,10 +4714,10 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) { scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE); scene_tabs_context_menu->add_separator(); - Ref<ShortCut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene"); + Ref<Shortcut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene"); close_tab_sc->set_name(TTR("Close Tab")); scene_tabs_context_menu->add_shortcut(close_tab_sc, FILE_CLOSE); - Ref<ShortCut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene"); + Ref<Shortcut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene"); undo_close_tab_sc->set_name(TTR("Undo Close Tab")); scene_tabs_context_menu->add_shortcut(undo_close_tab_sc, FILE_OPEN_PREV); if (previous_scenes.empty()) { @@ -5620,10 +5621,10 @@ EditorNode::EditorNode() { import_cubemap_array->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP_ARRAY); ResourceFormatImporter::get_singleton()->add_importer(import_cubemap_array); - /*Ref<ResourceImporterLayeredTexture> import_3d; + Ref<ResourceImporterLayeredTexture> import_3d; import_3d.instance(); import_3d->set_mode(ResourceImporterLayeredTexture::MODE_3D); - ResourceFormatImporter::get_singleton()->add_importer(import_3d);*/ + ResourceFormatImporter::get_singleton()->add_importer(import_3d); Ref<ResourceImporterImage> import_image; import_image.instance(); @@ -6622,6 +6623,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(CurveEditorPlugin(this))); add_editor_plugin(memnew(TextureEditorPlugin(this))); add_editor_plugin(memnew(TextureLayeredEditorPlugin(this))); + add_editor_plugin(memnew(Texture3DEditorPlugin(this))); add_editor_plugin(memnew(AudioStreamEditorPlugin(this))); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); add_editor_plugin(memnew(Skeleton3DEditorPlugin(this))); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 0aefef7018..8be157ffb5 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -77,7 +77,7 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) String name = arr[i]; Ref<InputEvent> shortcut = arr[i + 1]; - Ref<ShortCut> sc; + Ref<Shortcut> sc; sc.instance(); sc->set_shortcut(shortcut); add_shortcut(name, sc); @@ -120,8 +120,8 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { if (p_name.operator String() == "shortcuts") { Array arr; - for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) { - Ref<ShortCut> sc = E->get(); + for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) { + Ref<Shortcut> sc = E->get(); if (optimize_save) { if (!sc->has_meta("original")) { @@ -1481,50 +1481,50 @@ String EditorSettings::get_editor_layouts_config() const { // Shortcuts -void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut) { +void EditorSettings::add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut) { shortcuts[p_name] = p_shortcut; } bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const { - const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name); + const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name); ERR_FAIL_COND_V_MSG(!E, false, "Unknown Shortcut: " + p_name + "."); return E->get()->is_shortcut(p_event); } -Ref<ShortCut> EditorSettings::get_shortcut(const String &p_name) const { - const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name); +Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const { + const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name); if (!E) { - return Ref<ShortCut>(); + return Ref<Shortcut>(); } return E->get(); } void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) { - for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) { + for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) { r_shortcuts->push_back(E->key()); } } -Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path) { +Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path) { if (!EditorSettings::get_singleton()) { return nullptr; } - Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); ERR_FAIL_COND_V_MSG(!sc.is_valid(), sc, "Used ED_GET_SHORTCUT with invalid shortcut: " + p_path + "."); return sc; } -struct ShortCutMapping { +struct ShortcutMapping { const char *path; uint32_t keycode; }; -Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) { +Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) { #ifdef OSX_ENABLED // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS if (p_keycode == KEY_DELETE) { @@ -1545,7 +1545,7 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p } if (!EditorSettings::get_singleton()) { - Ref<ShortCut> sc; + Ref<Shortcut> sc; sc.instance(); sc->set_name(p_name); sc->set_shortcut(ie); @@ -1553,7 +1553,7 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p return sc; } - Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); if (sc.is_valid()) { sc->set_name(p_name); //keep name (the ones that come from disk have no name) sc->set_meta("original", ie); //to compare against changes diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 13aebb7ea6..4896fb58db 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -85,7 +85,7 @@ private: int last_order; Ref<Resource> clipboard; - Map<String, Ref<ShortCut>> shortcuts; + Map<String, Ref<Shortcut>> shortcuts; String resource_path; String settings_dir; @@ -182,9 +182,9 @@ public: Vector<String> get_script_templates(const String &p_extension, const String &p_custom_path = String()); String get_editor_layouts_config() const; - void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut); + void add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut); bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const; - Ref<ShortCut> get_shortcut(const String &p_name) const; + Ref<Shortcut> get_shortcut(const String &p_name) const; void get_shortcut_list(List<String> *r_shortcuts); void notify_changes(); @@ -203,7 +203,7 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re Variant _EDITOR_GET(const String &p_setting); #define ED_IS_SHORTCUT(p_name, p_ev) (EditorSettings::get_singleton()->is_shortcut(p_name, p_ev)) -Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode = 0); -Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path); +Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode = 0); +Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path); #endif // EDITOR_SETTINGS_H diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 31903c89be..0071f169ac 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2300,6 +2300,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { // Right click is pressed in the tree. Vector<String> paths = _tree_get_selected(false); + tree_popup->clear(); if (paths.size() == 1) { if (paths[0].ends_with("/")) { tree_popup->add_icon_item(get_theme_icon("GuiTreeArrowDown", "EditorIcons"), TTR("Expand All"), FOLDER_EXPAND_ALL); @@ -2310,7 +2311,6 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { // Popup. if (!paths.empty()) { - tree_popup->clear(); tree_popup->set_size(Size2(1, 1)); _file_and_folders_fill_popup(tree_popup, paths); tree_popup->set_position(tree->get_screen_position() + p_pos); diff --git a/editor/icons/ShortCut.svg b/editor/icons/Shortcut.svg index 4ef16f0401..4ef16f0401 100644 --- a/editor/icons/ShortCut.svg +++ b/editor/icons/Shortcut.svg diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index f954931cee..bbf62596d0 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -70,7 +70,7 @@ String ResourceImporterLayeredTexture::get_visible_name() const { return "CubemapArray"; } break; case MODE_3D: { - return "3D"; + return "Texture3D"; } break; } @@ -156,15 +156,103 @@ void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_op } void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) { - for (int i = 0; i < p_images.size(); i++) { - if (p_force_po2) { - p_images.write[i]->resize_to_po2(); + Vector<Ref<Image>> mipmap_images; //for 3D + + if (mode == MODE_3D) { + //3D saves in its own way + + for (int i = 0; i < p_images.size(); i++) { + if (p_images.write[i]->has_mipmaps()) { + p_images.write[i]->clear_mipmaps(); + } + + if (p_force_po2) { + p_images.write[i]->resize_to_po2(); + } } if (p_mipmaps) { - p_images.write[i]->generate_mipmaps(); - } else { - p_images.write[i]->clear_mipmaps(); + Vector<Ref<Image>> parent_images = p_images; + //create 3D mipmaps, this is horrible, though not used very often + int w = p_images[0]->get_width(); + int h = p_images[0]->get_height(); + int d = p_images.size(); + + while (w > 1 || h > 1 || d > 1) { + Vector<Ref<Image>> mipmaps; + int mm_w = MAX(1, w >> 1); + int mm_h = MAX(1, h >> 1); + int mm_d = MAX(1, d >> 1); + + for (int i = 0; i < mm_d; i++) { + Ref<Image> mm; + mm.instance(); + mm->create(mm_w, mm_h, false, p_images[0]->get_format()); + Vector3 pos; + pos.z = float(i) * float(d) / float(mm_d) + 0.5; + for (int x = 0; x < mm_w; x++) { + for (int y = 0; y < mm_h; y++) { + pos.x = float(x) * float(w) / float(mm_w) + 0.5; + pos.y = float(y) * float(h) / float(mm_h) + 0.5; + + Vector3i posi = Vector3i(pos); + Vector3 fract = pos - Vector3(posi); + Vector3i posi_n = posi; + if (posi_n.x < w - 1) { + posi_n.x++; + } + if (posi_n.y < h - 1) { + posi_n.y++; + } + if (posi_n.z < d - 1) { + posi_n.z++; + } + + Color c000 = parent_images[posi.z]->get_pixel(posi.x, posi.y); + Color c100 = parent_images[posi.z]->get_pixel(posi_n.x, posi.y); + Color c010 = parent_images[posi.z]->get_pixel(posi.x, posi_n.y); + Color c110 = parent_images[posi.z]->get_pixel(posi_n.x, posi_n.y); + Color c001 = parent_images[posi_n.z]->get_pixel(posi.x, posi.y); + Color c101 = parent_images[posi_n.z]->get_pixel(posi_n.x, posi.y); + Color c011 = parent_images[posi_n.z]->get_pixel(posi.x, posi_n.y); + Color c111 = parent_images[posi_n.z]->get_pixel(posi_n.x, posi_n.y); + + Color cx00 = c000.lerp(c100, fract.x); + Color cx01 = c001.lerp(c101, fract.x); + Color cx10 = c010.lerp(c110, fract.x); + Color cx11 = c011.lerp(c111, fract.x); + + Color cy0 = cx00.lerp(cx10, fract.y); + Color cy1 = cx01.lerp(cx11, fract.y); + + Color cz = cy0.lerp(cy1, fract.z); + + mm->set_pixel(x, y, cz); + } + } + + mipmaps.push_back(mm); + } + + w = mm_w; + h = mm_h; + d = mm_d; + + mipmap_images.append_array(mipmaps); + parent_images = mipmaps; + } + } + } else { + for (int i = 0; i < p_images.size(); i++) { + if (p_force_po2) { + p_images.write[i]->resize_to_po2(); + } + + if (p_mipmaps) { + p_images.write[i]->generate_mipmaps(); + } else { + p_images.write[i]->clear_mipmaps(); + } } } @@ -175,13 +263,12 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons f->store_8('L'); f->store_32(StreamTextureLayered::FORMAT_VERSION); - f->store_32(p_images.size()); + f->store_32(p_images.size()); //2d layers or 3d depth f->store_32(mode); - f->store_32(0); //dataformat - f->store_32(0); //mipmap limit + f->store_32(0); - //reserved f->store_32(0); + f->store_32(mipmap_images.size()); // amount of mipmaps f->store_32(0); f->store_32(0); @@ -189,6 +276,10 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons ResourceImporterTexture::save_to_stex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy); } + for (int i = 0; i < mipmap_images.size(); i++) { + ResourceImporterTexture::save_to_stex_format(f, mipmap_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy); + } + f->close(); } diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 2d50889e9e..b54923be00 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -93,10 +93,6 @@ private: static const char *compression_formats[]; protected: - static void _texture_reimport_srgb(const Ref<StreamTexture2D> &p_tex); - static void _texture_reimport_3d(const Ref<StreamTexture2D> &p_tex); - static void _texture_reimport_normal(const Ref<StreamTexture2D> &p_tex); - static ResourceImporterLayeredTexture *singleton; public: diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index ea58fb1e36..859e80befe 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -400,11 +400,11 @@ private: Ref<Texture2D> select_handle; Ref<Texture2D> anchor_handle; - Ref<ShortCut> drag_pivot_shortcut; - Ref<ShortCut> set_pivot_shortcut; - Ref<ShortCut> multiply_grid_step_shortcut; - Ref<ShortCut> divide_grid_step_shortcut; - Ref<ShortCut> pan_view_shortcut; + Ref<Shortcut> drag_pivot_shortcut; + Ref<Shortcut> set_pivot_shortcut; + Ref<Shortcut> multiply_grid_step_shortcut; + Ref<Shortcut> divide_grid_step_shortcut; + Ref<Shortcut> pan_view_shortcut; bool _is_node_locked(const Node *p_node); bool _is_node_movable(const Node *p_node, bool p_popup_warning = false); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 952487c13c..d28bbadf39 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2246,7 +2246,7 @@ Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouse } static bool is_shortcut_pressed(const String &p_path) { - Ref<ShortCut> shortcut = ED_GET_SHORTCUT(p_path); + Ref<Shortcut> shortcut = ED_GET_SHORTCUT(p_path); if (shortcut.is_null()) { return false; } diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp new file mode 100644 index 0000000000..ba2eef8484 --- /dev/null +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -0,0 +1,213 @@ +/*************************************************************************/ +/* texture_3d_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "texture_3d_editor_plugin.h" + +#include "core/io/resource_loader.h" +#include "core/project_settings.h" +#include "editor/editor_settings.h" + +void Texture3DEditor::_gui_input(Ref<InputEvent> p_event) { +} + +void Texture3DEditor::_texture_rect_draw() { + texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1)); +} + +void Texture3DEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_READY) { + //get_scene()->connect("node_removed",this,"_node_removed"); + } + if (p_what == NOTIFICATION_RESIZED) { + _texture_rect_update_area(); + } + + if (p_what == NOTIFICATION_DRAW) { + Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons"); + Size2 size = get_size(); + + draw_texture_rect(checkerboard, Rect2(Point2(), size), true); + } +} + +void Texture3DEditor::_changed_callback(Object *p_changed, const char *p_prop) { + if (!is_visible()) { + return; + } + update(); +} + +void Texture3DEditor::_update_material() { + material->set_shader_param("layer", (layer->get_value() + 0.5) / texture->get_depth()); + material->set_shader_param("tex", texture->get_rid()); + + String format = Image::get_format_name(texture->get_format()); + + String text; + text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + "x" + itos(texture->get_depth()) + " " + format; + + info->set_text(text); +} + +void Texture3DEditor::_make_shaders() { + String shader_3d = "" + "shader_type canvas_item;\n" + "uniform sampler3D tex;\n" + "uniform float layer;\n" + "void fragment() {\n" + " COLOR = textureLod(tex,vec3(UV,layer),0.0);\n" + "}"; + + shader.instance(); + shader->set_code(shader_3d); + material.instance(); + material->set_shader(shader); +} + +void Texture3DEditor::_texture_rect_update_area() { + Size2 size = get_size(); + int tex_width = texture->get_width() * size.height / texture->get_height(); + int tex_height = size.height; + + if (tex_width > size.width) { + tex_width = size.width; + tex_height = texture->get_height() * tex_width / texture->get_width(); + } + + // Prevent the texture from being unpreviewable after the rescale, so that we can still see something + if (tex_height <= 0) { + tex_height = 1; + } + if (tex_width <= 0) { + tex_width = 1; + } + + int ofs_x = (size.width - tex_width) / 2; + int ofs_y = (size.height - tex_height) / 2; + + texture_rect->set_position(Vector2(ofs_x, ofs_y)); + texture_rect->set_size(Vector2(tex_width, tex_height)); +} + +void Texture3DEditor::edit(Ref<Texture3D> p_texture) { + if (!texture.is_null()) { + texture->remove_change_receptor(this); + } + + texture = p_texture; + + if (!texture.is_null()) { + if (shader.is_null()) { + _make_shaders(); + } + + texture->add_change_receptor(this); + update(); + texture_rect->set_material(material); + setting = true; + layer->set_max(texture->get_depth() - 1); + layer->set_value(0); + layer->show(); + _update_material(); + setting = false; + _texture_rect_update_area(); + } else { + hide(); + } +} + +void Texture3DEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("_gui_input"), &Texture3DEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_layer_changed"), &Texture3DEditor::_layer_changed); +} + +Texture3DEditor::Texture3DEditor() { + set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED); + set_custom_minimum_size(Size2(1, 150)); + texture_rect = memnew(Control); + texture_rect->connect("draw", callable_mp(this, &Texture3DEditor::_texture_rect_draw)); + texture_rect->set_mouse_filter(MOUSE_FILTER_IGNORE); + add_child(texture_rect); + + layer = memnew(SpinBox); + layer->set_step(1); + layer->set_max(100); + add_child(layer); + layer->set_anchor(MARGIN_RIGHT, 1); + layer->set_anchor(MARGIN_LEFT, 1); + layer->set_h_grow_direction(GROW_DIRECTION_BEGIN); + layer->set_modulate(Color(1, 1, 1, 0.8)); + info = memnew(Label); + add_child(info); + info->set_anchor(MARGIN_RIGHT, 1); + info->set_anchor(MARGIN_LEFT, 1); + info->set_anchor(MARGIN_BOTTOM, 1); + info->set_anchor(MARGIN_TOP, 1); + info->set_h_grow_direction(GROW_DIRECTION_BEGIN); + info->set_v_grow_direction(GROW_DIRECTION_BEGIN); + info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); + info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5)); + info->add_theme_constant_override("shadow_as_outline", 1); + info->add_theme_constant_override("shadow_offset_x", 2); + info->add_theme_constant_override("shadow_offset_y", 2); + + setting = false; + layer->connect("value_changed", Callable(this, "_layer_changed")); +} + +Texture3DEditor::~Texture3DEditor() { + if (!texture.is_null()) { + texture->remove_change_receptor(this); + } +} + +// +bool EditorInspectorPlugin3DTexture::can_handle(Object *p_object) { + return Object::cast_to<Texture3D>(p_object) != nullptr; +} + +void EditorInspectorPlugin3DTexture::parse_begin(Object *p_object) { + Texture3D *texture = Object::cast_to<Texture3D>(p_object); + if (!texture) { + return; + } + Ref<Texture3D> m(texture); + + Texture3DEditor *editor = memnew(Texture3DEditor); + editor->edit(m); + add_custom_control(editor); +} + +Texture3DEditorPlugin::Texture3DEditorPlugin(EditorNode *p_node) { + Ref<EditorInspectorPlugin3DTexture> plugin; + plugin.instance(); + add_inspector_plugin(plugin); +} diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h new file mode 100644 index 0000000000..4fbf47ecfe --- /dev/null +++ b/editor/plugins/texture_3d_editor_plugin.h @@ -0,0 +1,93 @@ +/*************************************************************************/ +/* texture_3d_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEXTURE_3D_EDITOR_PLUGIN_H +#define TEXTURE_3D_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "scene/resources/shader.h" +#include "scene/resources/texture.h" + +class Texture3DEditor : public Control { + GDCLASS(Texture3DEditor, Control); + + SpinBox *layer; + Label *info; + Ref<Texture3D> texture; + + Ref<Shader> shader; + Ref<ShaderMaterial> material; + + Control *texture_rect; + + void _make_shaders(); + + void _update_material(); + bool setting; + void _layer_changed(double) { + if (!setting) { + _update_material(); + } + } + + void _texture_rect_update_area(); + void _texture_rect_draw(); + +protected: + void _notification(int p_what); + void _gui_input(Ref<InputEvent> p_event); + void _changed_callback(Object *p_changed, const char *p_prop) override; + static void _bind_methods(); + +public: + void edit(Ref<Texture3D> p_texture); + Texture3DEditor(); + ~Texture3DEditor(); +}; + +class EditorInspectorPlugin3DTexture : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPlugin3DTexture, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object) override; + virtual void parse_begin(Object *p_object) override; +}; + +class Texture3DEditorPlugin : public EditorPlugin { + GDCLASS(Texture3DEditorPlugin, EditorPlugin); + +public: + virtual String get_name() const override { return "Texture3D"; } + + Texture3DEditorPlugin(EditorNode *p_node); +}; + +#endif // TEXTURE_EDITOR_PLUGIN_H diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 30ae3dd4bb..734255ca55 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -60,6 +60,88 @@ void VisualShaderNodePlugin::_bind_methods() { /////////////////// +VisualShaderGraphPlugin::VisualShaderGraphPlugin() { +} + +void VisualShaderGraphPlugin::_bind_methods() { + ClassDB::bind_method("show_port_preview", &VisualShaderGraphPlugin::show_port_preview); +} + +void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) { + visual_shader = Ref<VisualShader>(p_shader); +} + +void VisualShaderGraphPlugin::show_port_preview(int p_port_id, int p_node_id) { + if (links.has(p_node_id) && links[p_node_id].type == visual_shader->get_shader_type()) { + for (Map<int, Port>::Element *E = links[p_node_id].output_ports.front(); E; E = E->next()) { + E->value().preview_button->set_pressed(false); + } + + if (links[p_node_id].preview_visible && !is_dirty()) { + links[p_node_id].graph_node->remove_child(links[p_node_id].preview_box); + links[p_node_id].graph_node->set_size(Vector2(-1, -1)); + links[p_node_id].preview_visible = false; + } + + if (p_port_id != -1) { + if (is_dirty()) { + links[p_node_id].preview_pos = links[p_node_id].graph_node->get_child_count(); + } + + VBoxContainer *vbox = memnew(VBoxContainer); + links[p_node_id].graph_node->add_child(vbox); + if (links[p_node_id].preview_pos != -1) { + links[p_node_id].graph_node->move_child(vbox, links[p_node_id].preview_pos); + } + + Control *offset = memnew(Control); + offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); + vbox->add_child(offset); + + VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); + port_preview->setup(visual_shader, visual_shader->get_shader_type(), p_node_id, p_port_id); + port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER); + vbox->add_child(port_preview); + links[p_node_id].preview_visible = true; + links[p_node_id].preview_box = vbox; + links[p_node_id].output_ports[p_port_id].preview_button->set_pressed(true); + } + } +} + +bool VisualShaderGraphPlugin::is_preview_visible(int p_id) const { + return links[p_id].preview_visible; +} + +void VisualShaderGraphPlugin::clear_links() { + links.clear(); +} + +bool VisualShaderGraphPlugin::is_dirty() const { + return dirty; +} + +void VisualShaderGraphPlugin::make_dirty(bool p_enabled) { + dirty = p_enabled; +} + +void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) { + links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, Port>(), nullptr }); + + if (!p_visual_node->is_connected("show_port_preview", callable_mp(this, &VisualShaderGraphPlugin::show_port_preview))) { + p_visual_node->connect("show_port_preview", callable_mp(this, &VisualShaderGraphPlugin::show_port_preview), varray(p_id), CONNECT_DEFERRED); + } +} + +void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) { + links[p_node_id].output_ports.insert(p_port, { p_button }); +} + +VisualShaderGraphPlugin::~VisualShaderGraphPlugin() { +} + +///////////////// + void VisualShaderEditor::edit(VisualShader *p_visual_shader) { bool changed = false; if (p_visual_shader) { @@ -71,6 +153,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { } } visual_shader = Ref<VisualShader>(p_visual_shader); + graph_plugin->register_shader(visual_shader.ptr()); if (!visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) { visual_shader->connect("changed", callable_mp(this, &VisualShaderEditor::_update_preview)); } @@ -81,6 +164,19 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { } #endif visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE); + + if (visual_shader->get_mode() == VisualShader::MODE_PARTICLES) { + edit_type_standart->set_visible(false); + edit_type_particles->set_visible(true); + edit_type = edit_type_particles; + particles_mode = true; + } else { + edit_type_particles->set_visible(false); + edit_type_standart->set_visible(true); + edit_type = edit_type_standart; + particles_mode = false; + } + visual_shader->set_shader_type(get_current_shader_type()); } else { if (visual_shader.is_valid()) { if (visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) { @@ -168,18 +264,15 @@ bool VisualShaderEditor::_is_available(int p_mode) { if (p_mode != -1) { switch (current_mode) { - case VisualShader::TYPE_VERTEX: + case 0: // Vertex or Emit current_mode = 1; break; - case VisualShader::TYPE_FRAGMENT: + case 1: // Fragment or Process current_mode = 2; break; - case VisualShader::TYPE_LIGHT: + case 2: // Light or End current_mode = 4; break; - case VisualShader::TYPE_COMPUTE: - current_mode = 8; - break; default: break; } @@ -448,7 +541,8 @@ void VisualShaderEditor::_update_graph() { graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE); - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); + graph->clear_connections(); //erase all nodes for (int i = 0; i < graph->get_child_count(); i++) { @@ -517,6 +611,9 @@ void VisualShaderEditor::_update_graph() { Control *offset; + graph_plugin->clear_links(); + graph_plugin->make_dirty(true); + for (int n_i = 0; n_i < nodes.size(); n_i++) { Vector2 position = visual_shader->get_node_position(type, nodes[n_i]); Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]); @@ -530,6 +627,8 @@ void VisualShaderEditor::_update_graph() { String expression = ""; GraphNode *node = memnew(GraphNode); + visual_shader->set_graph_node(type, nodes[n_i], node); + graph_plugin->register_link(type, nodes[n_i], vsnode.ptr(), node); if (is_group) { size = group_node->get_size(); @@ -801,9 +900,7 @@ void VisualShaderEditor::_update_graph() { preview->set_pressed_texture(get_theme_icon("GuiVisibilityVisible", "EditorIcons")); preview->set_v_size_flags(SIZE_SHRINK_CENTER); - if (vsnode->get_output_port_for_preview() == i) { - preview->set_pressed(true); - } + graph_plugin->register_output_port(nodes[n_i], i, preview); preview->connect("pressed", callable_mp(this, &VisualShaderEditor::_preview_select_port), varray(nodes[n_i], i), CONNECT_DEFERRED); hb->add_child(preview); @@ -822,18 +919,7 @@ void VisualShaderEditor::_update_graph() { } if (vsnode->get_output_port_for_preview() >= 0) { - int port_type = vsnode->get_output_port_type(vsnode->get_output_port_for_preview()); - - if (port_type != VisualShaderNode::PORT_TYPE_TRANSFORM && port_type != VisualShaderNode::PORT_TYPE_SAMPLER) { - offset = memnew(Control); - offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE)); - node->add_child(offset); - - VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); - port_preview->setup(visual_shader, type, nodes[n_i], vsnode->get_output_port_for_preview()); - port_preview->set_h_size_flags(SIZE_SHRINK_CENTER); - node->add_child(port_preview); - } + graph_plugin->show_port_preview(vsnode->get_output_port_for_preview(), nodes[n_i]); } offset = memnew(Control); @@ -896,6 +982,8 @@ void VisualShaderEditor::_update_graph() { } } + graph_plugin->make_dirty(false); + for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { int from = E->get().from_node; int from_idx = E->get().from_port; @@ -906,8 +994,18 @@ void VisualShaderEditor::_update_graph() { } } +VisualShader::Type VisualShaderEditor::get_current_shader_type() const { + VisualShader::Type type; + if (particles_mode) { + type = VisualShader::Type(edit_type->get_selected() + 3); + } else { + type = VisualShader::Type(edit_type->get_selected()); + } + return type; +} + void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type, const String &p_name) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -924,7 +1022,7 @@ void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type } void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_type, const String &p_name) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -941,7 +1039,7 @@ void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_typ } void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_port) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -958,7 +1056,7 @@ void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_p } void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_port) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -975,7 +1073,7 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_ } void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); @@ -989,7 +1087,7 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *l } void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); @@ -1003,7 +1101,7 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object * } void VisualShaderEditor::_remove_input_port(int p_node, int p_port) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -1046,7 +1144,7 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) { } void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -1089,7 +1187,7 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { } void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -1117,7 +1215,7 @@ void VisualShaderEditor::_rebuild() { } void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) { - VisualShader::Type type = VisualShader::Type(p_type); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -1164,7 +1262,7 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p } void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, int p_node) { - VisualShader::Type type = VisualShader::Type(p_type); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -1177,7 +1275,7 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in } void VisualShaderEditor::_preview_select_port(int p_node, int p_port) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; @@ -1186,16 +1284,14 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) { if (node->get_output_port_for_preview() == p_port) { p_port = -1; //toggle it } - undo_redo->create_action(TTR("Set Uniform Name")); + undo_redo->create_action(p_port == -1 ? TTR("Hide Port Preview") : TTR("Show Port Preview")); undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port); undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", node->get_output_port_for_preview()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); } void VisualShaderEditor::_line_edit_changed(const String &p_text, Object *line_edit, int p_node_id) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeUniform> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); @@ -1220,7 +1316,7 @@ void VisualShaderEditor::_line_edit_focus_out(Object *line_edit, int p_node_id) } void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); @@ -1271,7 +1367,7 @@ void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, } void VisualShaderEditor::_port_edited() { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Variant value = property_editor->get_variant(); Ref<VisualShaderNode> vsn = visual_shader->get_node(type, editing_node); @@ -1288,7 +1384,7 @@ void VisualShaderEditor::_port_edited() { } void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, int p_port) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNode> vsn = visual_shader->get_node(type, p_node); @@ -1454,7 +1550,7 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { } saved_node_pos_dirty = false; - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); int id_to_use = visual_shader->get_valid_node_id(type); @@ -1496,20 +1592,16 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { } void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); - updating = true; undo_redo->create_action(TTR("Node Moved")); undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", type, p_node, p_to); undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", type, p_node, p_from); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); - updating = false; } void VisualShaderEditor::_connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); int from = p_from.to_int(); int to = p_to.to_int(); @@ -1540,7 +1632,7 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) { graph->disconnect_node(p_from, p_from_index, p_to, p_to_index); - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); int from = p_from.to_int(); int to = p_to.to_int(); @@ -1568,7 +1660,7 @@ void VisualShaderEditor::_connection_from_empty(const String &p_to, int p_to_slo } void VisualShaderEditor::_delete_request(int which) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNode> node = Ref<VisualShaderNode>(visual_shader->get_node(type, which)); undo_redo->create_action(TTR("Delete Node")); @@ -1607,7 +1699,7 @@ void VisualShaderEditor::_delete_request(int which) { } void VisualShaderEditor::_node_selected(Object *p_node) { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); GraphNode *gn = Object::cast_to<GraphNode>(p_node); ERR_FAIL_COND(!gn); @@ -1965,7 +2057,7 @@ void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 } void VisualShaderEditor::_delete_nodes() { - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); List<int> to_erase; for (int i = 0; i < graph->get_child_count(); i++) { @@ -2035,6 +2127,7 @@ void VisualShaderEditor::_delete_nodes() { } void VisualShaderEditor::_mode_selected(int p_id) { + visual_shader->set_shader_type(VisualShader::Type(p_id)); _update_options_menu(); _update_graph(); } @@ -2056,7 +2149,7 @@ void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> input, St if (type_changed) { //restore connections if type changed - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); int id = visual_shader->find_node_id(type, input); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); @@ -2090,7 +2183,7 @@ void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_ if (type_changed) { //restore connections if type changed - VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); + VisualShader::Type type = get_current_shader_type(); int id = visual_shader->find_node_id(type, p_uniform_ref); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); @@ -2415,15 +2508,26 @@ VisualShaderEditor::VisualShaderEditor() { graph->get_zoom_hbox()->add_child(vs); graph->get_zoom_hbox()->move_child(vs, 0); - edit_type = memnew(OptionButton); - edit_type->add_item(TTR("Vertex")); - edit_type->add_item(TTR("Fragment")); - edit_type->add_item(TTR("Light")); - edit_type->add_item(TTR("Compute")); - edit_type->select(1); - edit_type->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); - graph->get_zoom_hbox()->add_child(edit_type); - graph->get_zoom_hbox()->move_child(edit_type, 0); + edit_type_standart = memnew(OptionButton); + edit_type_standart->add_item(TTR("Vertex")); + edit_type_standart->add_item(TTR("Fragment")); + edit_type_standart->add_item(TTR("Light")); + edit_type_standart->select(1); + edit_type_standart->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); + + edit_type_particles = memnew(OptionButton); + edit_type_particles->add_item(TTR("Emit")); + edit_type_particles->add_item(TTR("Process")); + edit_type_particles->add_item(TTR("End")); + edit_type_particles->select(0); + edit_type_particles->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); + + edit_type = edit_type_standart; + + graph->get_zoom_hbox()->add_child(edit_type_particles); + graph->get_zoom_hbox()->move_child(edit_type_particles, 0); + graph->get_zoom_hbox()->add_child(edit_type_standart); + graph->get_zoom_hbox()->move_child(edit_type_standart, 0); add_node = memnew(Button); add_node->set_flat(true); @@ -2601,26 +2705,26 @@ VisualShaderEditor::VisualShaderEditor() { // INPUT - // SPATIAL-FOR-ALL (except COMPUTE) + // SPATIAL-FOR-ALL - const String input_param_shader_modes = TTR("'%s' input parameter for vertex/fragment/light shader modes."); - add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), "output_is_srgb", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "viewport_size"), "viewport_size", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_SPATIAL)); + const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes."); + add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), "output_is_srgb", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "viewport_size"), "viewport_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); - // CANVASITEM-FOR-ALL (except COMPUTE) + // CANVASITEM-FOR-ALL - add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), "texture_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), "texture_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); ///////////////// @@ -2633,7 +2737,10 @@ VisualShaderEditor::VisualShaderEditor() { const String input_param_for_fragment_shader_mode = TTR("'%s' input parameter for fragment shader mode."); const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode."); const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode."); - const String input_param_for_compute_shader_mode = TTR("'%s' input parameter for compute shader mode."); + const String input_param_for_emit_shader_mode = TTR("'%s' input parameter for emit shader mode."); + const String input_param_for_process_shader_mode = TTR("'%s' input parameter for process shader mode."); + const String input_param_for_end_shader_mode = TTR("'%s' input parameter for end shader mode."); + const String input_param_for_emit_and_process_shader_mode = TTR("'%s' input parameter for emit and process shader mode."); const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode."); add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); @@ -2707,19 +2814,47 @@ VisualShaderEditor::VisualShaderEditor() { // PARTICLES INPUTS - add_options.push_back(AddOption("Active", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Alpha", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CustomAlpha", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Delta", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("EmissionTransform", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("LifeTime", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Restart", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Time", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Transform", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "Compute", "VisualShaderNodeInput", vformat(input_param_for_compute_shader_mode, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COMPUTE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Active", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Alpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CustomAlpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Delta", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("EmissionTransform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("LifeTime", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Restart", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Time", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Transform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + + add_options.push_back(AddOption("Active", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Alpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CustomAlpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Delta", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("EmissionTransform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("LifeTime", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Restart", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Time", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Transform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + + add_options.push_back(AddOption("Active", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Alpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CustomAlpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Delta", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("EmissionTransform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("LifeTime", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Restart", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Time", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Transform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); // SKY INPUTS @@ -2839,12 +2974,15 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1)); texture_node_option_idx = add_options.size(); - add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, -1)); - add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1)); + add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1)); add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1)); + add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup."), -1, -1)); + + add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1)); add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1)); add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup."), -1, -1, -1, -1, -1)); + add_options.push_back(AddOption("Texture3DUniform", "Textures", "Variables", "VisualShaderNodeTexture3DUniform", TTR("3D texture uniform lookup."), -1, -1, -1, -1, -1)); // TRANSFORM @@ -2969,12 +3107,16 @@ VisualShaderEditor::VisualShaderEditor() { default_plugin.instance(); add_plugin(default_plugin); + graph_plugin.instance(); + property_editor = memnew(CustomPropertyEditor); add_child(property_editor); property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited)); } +///////////////// + void VisualShaderEditorPlugin::edit(Object *p_object) { visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object)); } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index ff2b0dc6ab..59d4765ec9 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -50,8 +50,50 @@ public: virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node); }; +class VisualShaderGraphPlugin : public Reference { + GDCLASS(VisualShaderGraphPlugin, Reference); + +private: + struct Port { + TextureButton *preview_button; + }; + + struct Link { + VisualShader::Type type; + VisualShaderNode *visual_node; + GraphNode *graph_node; + bool preview_visible; + int preview_pos; + Map<int, Port> output_ports; + VBoxContainer *preview_box; + }; + + Ref<VisualShader> visual_shader; + Map<int, Link> links; + bool dirty = false; + +protected: + static void _bind_methods(); + +public: + void register_shader(VisualShader *p_visual_shader); + void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node); + void register_output_port(int p_id, int p_port, TextureButton *p_button); + void clear_links(); + void set_shader_type(VisualShader::Type p_type); + bool is_preview_visible(int p_id) const; + bool is_dirty() const; + void make_dirty(bool p_enabled); + + void show_port_preview(int p_node_id, int p_port_id); + + VisualShaderGraphPlugin(); + ~VisualShaderGraphPlugin(); +}; + class VisualShaderEditor : public VBoxContainer { GDCLASS(VisualShaderEditor, VBoxContainer); + friend class VisualShaderGraphPlugin; CustomPropertyEditor *property_editor; int editing_node; @@ -63,7 +105,9 @@ class VisualShaderEditor : public VBoxContainer { Button *add_node; Button *preview_shader; - OptionButton *edit_type; + OptionButton *edit_type = nullptr; + OptionButton *edit_type_standart; + OptionButton *edit_type_particles; PanelContainer *error_panel; Label *error_label; @@ -84,13 +128,18 @@ class VisualShaderEditor : public VBoxContainer { MenuButton *tools; bool preview_showed; + bool particles_mode; enum TypeFlags { TYPE_FLAGS_VERTEX = 1, TYPE_FLAGS_FRAGMENT = 2, TYPE_FLAGS_LIGHT = 4, - TYPE_FLAGS_COMPUTE = 8, - TYPE_FLAGS_VERTEX_FRAGMENT_LIGHT = TYPE_FLAGS_VERTEX | TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, + }; + + enum ParticlesTypeFlags { + TYPE_FLAGS_EMIT = 1, + TYPE_FLAGS_PROCESS = 2, + TYPE_FLAGS_END = 4 }; enum ToolsMenuOptions { @@ -235,6 +284,7 @@ class VisualShaderEditor : public VBoxContainer { void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2()); Vector<Ref<VisualShaderNodePlugin>> plugins; + Ref<VisualShaderGraphPlugin> graph_plugin; void _mode_selected(int p_id); void _rebuild(); @@ -242,6 +292,8 @@ class VisualShaderEditor : public VBoxContainer { void _input_select_item(Ref<VisualShaderNodeInput> input, String name); void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name); + VisualShader::Type get_current_shader_type() const; + void _add_input_port(int p_node, int p_port, int p_port_type, const String &p_name); void _remove_input_port(int p_node, int p_port); void _change_input_port_type(int p_type, int p_node, int p_port); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index f45161d87b..1f553ba0de 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -310,6 +310,24 @@ void ProjectExportDialog::_edit_preset(int p_index) { _update_export_all(); child_controls_changed(); + String enc_in_filters_str = current->get_enc_in_filter(); + String enc_ex_filters_str = current->get_enc_ex_filter(); + if (!updating_enc_filters) { + enc_in_filters->set_text(enc_in_filters_str); + enc_ex_filters->set_text(enc_ex_filters_str); + } + + bool enc_pck_mode = current->get_enc_pck(); + enc_pck->set_pressed(enc_pck_mode); + + enc_directory->set_disabled(!enc_pck_mode); + enc_in_filters->set_editable(enc_pck_mode); + enc_ex_filters->set_editable(enc_pck_mode); + script_key->set_editable(enc_pck_mode); + + bool enc_directory_mode = current->get_enc_directory(); + enc_directory->set_pressed(enc_directory_mode); + int script_export_mode = current->get_script_export_mode(); script_mode->select(script_export_mode); @@ -317,7 +335,7 @@ void ProjectExportDialog::_edit_preset(int p_index) { if (!updating_script_key) { script_key->set_text(key); } - if (script_export_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) { + if (enc_pck_mode) { script_key->set_editable(true); bool key_valid = _validate_script_encryption_key(key); @@ -519,6 +537,56 @@ void ProjectExportDialog::_export_path_changed(const StringName &p_property, con _update_presets(); } +void ProjectExportDialog::_enc_filters_changed(const String &p_filters) { + if (updating) { + return; + } + + Ref<EditorExportPreset> current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + current->set_enc_in_filter(enc_in_filters->get_text()); + current->set_enc_ex_filter(enc_ex_filters->get_text()); + + updating_enc_filters = true; + _update_current_preset(); + updating_enc_filters = false; +} + +void ProjectExportDialog::_open_key_help_link() { + OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/development/compiling/compiling_with_script_encryption_key.html"); +} + +void ProjectExportDialog::_enc_pck_changed(bool p_pressed) { + if (updating) { + return; + } + + Ref<EditorExportPreset> current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + current->set_enc_pck(p_pressed); + enc_directory->set_disabled(!p_pressed); + enc_in_filters->set_editable(p_pressed); + enc_ex_filters->set_editable(p_pressed); + script_key->set_editable(p_pressed); + + _update_current_preset(); +} + +void ProjectExportDialog::_enc_directory_changed(bool p_pressed) { + if (updating) { + return; + } + + Ref<EditorExportPreset> current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + current->set_enc_directory(p_pressed); + + _update_current_preset(); +} + void ProjectExportDialog::_script_export_mode_changed(int p_mode) { if (updating) { return; @@ -1148,6 +1216,12 @@ ProjectExportDialog::ProjectExportDialog() { exclude_filters); exclude_filters->connect("text_changed", callable_mp(this, &ProjectExportDialog::_filter_changed)); + script_mode = memnew(OptionButton); + resources_vb->add_margin_child(TTR("Script Export Mode:"), script_mode); + script_mode->add_item(TTR("Text"), (int)EditorExportPreset::MODE_SCRIPT_TEXT); + script_mode->add_item(TTR("Compiled"), (int)EditorExportPreset::MODE_SCRIPT_COMPILED); + script_mode->connect("item_selected", callable_mp(this, &ProjectExportDialog::_script_export_mode_changed)); + // Patch packages. VBoxContainer *patch_vb = memnew(VBoxContainer); @@ -1205,23 +1279,50 @@ ProjectExportDialog::ProjectExportDialog() { // Script export parameters. updating_script_key = false; + updating_enc_filters = false; + + VBoxContainer *sec_vb = memnew(VBoxContainer); + sec_vb->set_name(TTR("Encryption")); + + enc_pck = memnew(CheckButton); + enc_pck->connect("toggled", callable_mp(this, &ProjectExportDialog::_enc_pck_changed)); + enc_pck->set_text(TTR("Encrypt exported PCK")); + sec_vb->add_child(enc_pck); + + enc_directory = memnew(CheckButton); + enc_directory->connect("toggled", callable_mp(this, &ProjectExportDialog::_enc_directory_changed)); + enc_directory->set_text("Encrypt index (file names and info)."); + sec_vb->add_child(enc_directory); + + enc_in_filters = memnew(LineEdit); + enc_in_filters->connect("text_changed", callable_mp(this, &ProjectExportDialog::_enc_filters_changed)); + sec_vb->add_margin_child( + TTR("Filters to include files/folders\n(comma-separated, e.g: *.tscn, *.tres, scenes/*)"), + enc_in_filters); + + enc_ex_filters = memnew(LineEdit); + enc_ex_filters->connect("text_changed", callable_mp(this, &ProjectExportDialog::_enc_filters_changed)); + sec_vb->add_margin_child( + TTR("Filters to exclude files/folders\n(comma-separated, e.g: *.stex, *.import, music/*)"), + enc_ex_filters); - VBoxContainer *script_vb = memnew(VBoxContainer); - script_vb->set_name(TTR("Script")); - script_mode = memnew(OptionButton); - script_vb->add_margin_child(TTR("Script Export Mode:"), script_mode); - script_mode->add_item(TTR("Text"), (int)EditorExportPreset::MODE_SCRIPT_TEXT); - script_mode->add_item(TTR("Compiled"), (int)EditorExportPreset::MODE_SCRIPT_COMPILED); - script_mode->add_item(TTR("Encrypted (Provide Key Below)"), (int)EditorExportPreset::MODE_SCRIPT_ENCRYPTED); - script_mode->connect("item_selected", callable_mp(this, &ProjectExportDialog::_script_export_mode_changed)); script_key = memnew(LineEdit); script_key->connect("text_changed", callable_mp(this, &ProjectExportDialog::_script_encryption_key_changed)); script_key_error = memnew(Label); script_key_error->set_text("- " + TTR("Invalid Encryption Key (must be 64 characters long)")); script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("error_color", "Editor")); - script_vb->add_margin_child(TTR("Script Encryption Key (256-bits as hex):"), script_key); - script_vb->add_child(script_key_error); - sections->add_child(script_vb); + sec_vb->add_margin_child(TTR("Encryption Key (256-bits as hex):"), script_key); + sec_vb->add_child(script_key_error); + sections->add_child(sec_vb); + + Label *sec_info = memnew(Label); + sec_info->set_text(TTR("Note: Encryption key needs to be stored in the binary,\nyou need to build the export templates from source.")); + sec_vb->add_child(sec_info); + + LinkButton *sec_more_info = memnew(LinkButton); + sec_more_info->set_text(TTR("More Info...")); + sec_more_info->connect("pressed", callable_mp(this, &ProjectExportDialog::_open_key_help_link)); + sec_vb->add_child(sec_more_info); sections->connect("tab_changed", callable_mp(this, &ProjectExportDialog::_tab_changed)); diff --git a/editor/project_export.h b/editor/project_export.h index cfa00773d8..75402dc334 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -145,6 +145,11 @@ private: CheckBox *export_debug; CheckBox *export_pck_zip_debug; + CheckButton *enc_pck; + CheckButton *enc_directory; + LineEdit *enc_in_filters; + LineEdit *enc_ex_filters; + void _open_export_template_manager(); void _export_pck_zip(); @@ -161,10 +166,16 @@ private: void _custom_features_changed(const String &p_text); bool updating_script_key; + bool updating_enc_filters; + void _enc_pck_changed(bool p_pressed); + void _enc_directory_changed(bool p_pressed); + void _enc_filters_changed(const String &p_text); void _script_export_mode_changed(int p_mode); void _script_encryption_key_changed(const String &p_key); bool _validate_script_encryption_key(const String &p_key); + void _open_key_help_link(); + void _tab_changed(int); protected: diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index ea55029de0..1fb889d793 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -2388,6 +2388,7 @@ ProjectManager::ProjectManager() { String cp; cp += 0xA9; + // TRANSLATORS: This refers to the application where users manage their Godot projects. DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors"); FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 35610ef71b..5da682a148 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -202,7 +202,7 @@ void EditorSettingsDialog::_update_shortcuts() { Map<String, TreeItem *> sections; for (List<String>::Element *E = slist.front(); E; E = E->next()) { - Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(E->get()); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E->get()); if (!sc->has_meta("original")) { continue; } @@ -268,7 +268,7 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column ERR_FAIL_COND(!ti); String item = ti->get_metadata(0); - Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(item); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item); if (p_idx == 0) { press_a_key_label->set_text(TTR("Press a Key...")); @@ -335,7 +335,7 @@ void EditorSettingsDialog::_press_a_key_confirm() { ie->set_alt(last_wait_for_key->get_alt()); ie->set_metakey(last_wait_for_key->get_metakey()); - Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured); undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_configured + "'"); undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie); diff --git a/editor/translations/af.po b/editor/translations/af.po index 526fe331ae..c439941fb8 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -1164,6 +1164,9 @@ msgstr "Projek Stigters" msgid "Lead Developer" msgstr "Hoof Ontwikkelaar" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp #, fuzzy msgid "Project Manager " @@ -9913,6 +9916,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Projek Bestuurder" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index d5b9ecc9d4..fecec9b136 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -1148,6 +1148,9 @@ msgstr "مؤسسون المشروع" msgid "Lead Developer" msgstr "قائد المطوريين" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "مدير المشروع " @@ -9870,6 +9873,7 @@ msgstr "" "هل أنت متأكد من فحص %s من المجلدات بحثاً عن مشاريع غودوت متوافرة؟\n" "قد يستغرق وقتاً." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "مدير المشروع" diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 6582fc6fec..c327d96e57 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -1097,6 +1097,9 @@ msgstr "Основатели на проекта" msgid "Lead Developer" msgstr "Главен разработчик" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Ръководител на проекта " @@ -9651,6 +9654,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Управление на проектите" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index e92b95ae74..dd713b6b81 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -1193,6 +1193,9 @@ msgstr "প্রজেক্ট ফাউন্ডার" msgid "Lead Developer" msgstr "মূল ডেভেলপার" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp #, fuzzy msgid "Project Manager " @@ -10528,6 +10531,7 @@ msgstr "" "বিদ্যমান Godot প্রজেক্টের খোঁজে আপনি %s ফোল্ডারসমূহ স্ক্যান করতে যাচ্ছেন। আপনি কি " "সুনিশ্চিত?" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "প্রজেক্ট ম্যানেজার" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 5f1f1c4cc5..feb0f8fea4 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -1127,6 +1127,9 @@ msgstr "Fundadors del Projecte" msgid "Lead Developer" msgstr "Desenvolupador Principal" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Gestor del Projecte " @@ -10146,6 +10149,7 @@ msgstr "" "existents?\n" "Això pot trigar una estona." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Gestor del Projecte" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 3a77f37c2a..f6bb57006a 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -1133,6 +1133,9 @@ msgstr "Zakladatelé projektu" msgid "Lead Developer" msgstr "Vedoucí vývojář" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Správce projektu " @@ -9882,6 +9885,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Správce projektů" diff --git a/editor/translations/da.po b/editor/translations/da.po index d472b338d8..6925853253 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -1168,6 +1168,9 @@ msgstr "Projekt grundlæggere" msgid "Lead Developer" msgstr "Ledende Udvikler" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projektleder " @@ -10119,9 +10122,10 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" -msgstr "Projektleder" +msgstr "Projekt Manager" #: editor/project_manager.cpp #, fuzzy diff --git a/editor/translations/de.po b/editor/translations/de.po index 9b89e7e1d6..3d9af3cdd4 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -1176,9 +1176,12 @@ msgstr "Projektgründer" msgid "Lead Developer" msgstr "Hauptentwickler" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Projektverwaltung " +msgstr "Projektleiter " #: editor/editor_about.cpp msgid "Developers" @@ -9985,6 +9988,7 @@ msgstr "" "Sollen wirklich %s Ordner nach Godot-Projekten durchsucht werden?\n" "Dies kann eine Weile dauern." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Projektverwaltung" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 93e62289e0..e544f254cd 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -1080,6 +1080,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9469,6 +9472,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index c0c08edc2f..34ca85d1bd 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -1126,6 +1126,9 @@ msgstr "Ιδρυτές του έργου" msgid "Lead Developer" msgstr "Επικεφαλής προγραμματιστής" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Διαχειριστής έργων " @@ -9934,6 +9937,7 @@ msgstr "" "Θέλετε να σαρώσετε %s φακέλους για υπαρκτά έργα Godot;\n" "Αυτό μπορεί να πάρει κάποια ώρα." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Διαχειριστής" diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 3b58b56f85..8595625d56 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -1119,6 +1119,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9618,6 +9621,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/es.po b/editor/translations/es.po index a685eeb7ff..9092ba4566 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -1172,9 +1172,12 @@ msgstr "Fundadores del Proyecto" msgid "Lead Developer" msgstr "Desarrollador Principal" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Administrador del Proyecto " +msgstr "Gestor del Proyecto " #: editor/editor_about.cpp msgid "Developers" @@ -9975,6 +9978,7 @@ msgstr "" "existentes?\n" "Esto puede tardar un poco." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Administrador de Proyectos" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index f80c3ba2c0..d9255df906 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -1133,6 +1133,9 @@ msgstr "Fundadores del Proyecto" msgid "Lead Developer" msgstr "Desarrollador Principal" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Gestor de Proyectos " @@ -9926,6 +9929,7 @@ msgstr "" "existentes?\n" "Podría demorar un rato." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Gestor de Proyectos" diff --git a/editor/translations/et.po b/editor/translations/et.po index b2b51b8676..d3e7c9e930 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -1093,6 +1093,9 @@ msgstr "Projekti asutajad" msgid "Lead Developer" msgstr "Juhtiv arendaja" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projekti juht " @@ -9512,6 +9515,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "projektihaldur" diff --git a/editor/translations/eu.po b/editor/translations/eu.po index f2f5f51348..8042403f9d 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -1090,6 +1090,9 @@ msgstr "Proiektuaren sortzaileak" msgid "Lead Developer" msgstr "Garatzaile nagusia" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Proiektu-kudeatzailea " @@ -9491,6 +9494,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/extract.py b/editor/translations/extract.py index 02ed65131f..93124ec30c 100755 --- a/editor/translations/extract.py +++ b/editor/translations/extract.py @@ -49,28 +49,27 @@ msgstr "" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\\n" "MIME-Version: 1.0\\n" "Content-Type: text/plain; charset=UTF-8\\n" -"Content-Transfer-Encoding: 8-bit\\n" +"Content-Transfer-Encoding: 8-bit\\n"\n """ def _write_message(msgctx, msg, msg_plural, location): global main_po - main_po += "\n#: " + location + "\n" + main_po += "#: " + location + "\n" if msgctx != "": main_po += 'msgctxt "' + msgctx + '"\n' main_po += 'msgid "' + msg + '"\n' if msg_plural != "": main_po += 'msgid_plural "' + msg_plural + '"\n' main_po += 'msgstr[0] ""\n' - main_po += 'msgstr[1] ""\n' + main_po += 'msgstr[1] ""\n\n' else: - main_po += 'msgstr ""\n' + main_po += 'msgstr ""\n\n' def _add_additional_location(msgctx, msg, location): global main_po - # Add additional location to previous occurrence - msg_pos = -1 + # Add additional location to previous occurrence. if msgctx != "": msg_pos = main_po.find('\nmsgctxt "' + msgctx + '"\nmsgid "' + msg + '"') else: @@ -81,18 +80,137 @@ def _add_additional_location(msgctx, msg, location): main_po = main_po[:msg_pos] + " " + location + main_po[msg_pos:] +def _write_translator_comment(msgctx, msg, translator_comment): + if translator_comment == "": + return + + global main_po + if msgctx != "": + msg_pos = main_po.find('\nmsgctxt "' + msgctx + '"\nmsgid "' + msg + '"') + else: + msg_pos = main_po.find('\nmsgid "' + msg + '"') + + # If it's a new message, just append comment to the end of PO file. + if msg_pos == -1: + main_po += _format_translator_comment(translator_comment, True) + return + + # Find position just before location. Translator comment will be added there. + translator_comment_pos = main_po.rfind("\n\n#", 0, msg_pos) + 2 + if translator_comment_pos - 2 == -1: + print("translator_comment_pos not found") + return + + # Check if a previous translator comment already exists. If so, merge them together. + if main_po.find("TRANSLATORS:", translator_comment_pos, msg_pos) != -1: + translator_comment_pos = main_po.find("\n#:", translator_comment_pos, msg_pos) + 1 + if translator_comment_pos == 0: + print('translator_comment_pos after "TRANSLATORS:" not found') + return + main_po = ( + main_po[:translator_comment_pos] + + _format_translator_comment(translator_comment, False) + + main_po[translator_comment_pos:] + ) + return + + main_po = ( + main_po[:translator_comment_pos] + + _format_translator_comment(translator_comment, True) + + main_po[translator_comment_pos:] + ) + + +def _format_translator_comment(comment, new): + if not comment: + return "" + + comment_lines = comment.split("\n") + + formatted_comment = "" + if not new: + for comment in comment_lines: + formatted_comment += "#. " + comment.strip() + "\n" + return formatted_comment + + formatted_comment = "#. TRANSLATORS: " + for i in range(len(comment_lines)): + if i == 0: + formatted_comment += comment_lines[i].strip() + "\n" + else: + formatted_comment += "#. " + comment_lines[i].strip() + "\n" + return formatted_comment + + +def _is_block_translator_comment(translator_line): + line = translator_line.strip() + if line.find("//") == 0: + return False + else: + return True + + +def _extract_translator_comment(line, is_block_translator_comment): + line = line.strip() + reached_end = False + extracted_comment = "" + + start = line.find("TRANSLATORS:") + if start == -1: + start = 0 + else: + start += len("TRANSLATORS:") + + if is_block_translator_comment: + # If '*/' is found, then it's the end. + if line.rfind("*/") != -1: + extracted_comment = line[start : line.rfind("*/")] + reached_end = True + else: + extracted_comment = line[start:] + else: + # If beginning is not '//', then it's the end. + if line.find("//") != 0: + reached_end = True + else: + start = 2 if start == 0 else start + extracted_comment = line[start:] + + return (not reached_end, extracted_comment) + + def process_file(f, fname): global main_po, unique_str, unique_loc + patterns = ['RTR("', 'TTR("', 'TTRC("', 'TTRN("', 'RTRN("'] + l = f.readline() lc = 1 + reading_translator_comment = False + is_block_translator_comment = False + translator_comment = "" + while l: - patterns = ['RTR("', 'TTR("', 'TTRC("', 'TTRN("', 'RTRN("'] + # Detect translator comments. + if not reading_translator_comment and l.find("TRANSLATORS:") != -1: + reading_translator_comment = True + is_block_translator_comment = _is_block_translator_comment(l) + translator_comment = "" + + # Gather translator comments. It will be gathered for the next translation function. + if reading_translator_comment: + reading_translator_comment, extracted_comment = _extract_translator_comment(l, is_block_translator_comment) + if extracted_comment != "": + translator_comment += extracted_comment + "\n" + if not reading_translator_comment: + translator_comment = translator_comment[:-1] # Remove extra \n at the end. + idx = 0 pos = 0 - while pos >= 0: + + while not reading_translator_comment and pos >= 0: # Loop until a pattern is found. If not, next line. pos = l.find(patterns[idx], pos) if pos == -1: @@ -140,6 +258,10 @@ def process_file(f, fname): if line_nb: location += ":" + str(lc) + # Write translator comment. + _write_translator_comment(msgctx, msg, translator_comment) + translator_comment = "" + if msgctx != "": # If it's a new context or a new message within an existing context, then write new msgid. # Else add location to existing msgid. @@ -160,6 +282,7 @@ def process_file(f, fname): elif not location in unique_loc[msg]: _add_additional_location(msgctx, msg, location) unique_loc[msg].append(location) + l = f.readline() lc += 1 diff --git a/editor/translations/fa.po b/editor/translations/fa.po index 0b87c12532..dee4ae4030 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -1120,6 +1120,9 @@ msgstr "بنیانگذاران پروژه" msgid "Lead Developer" msgstr "توسعهدهندهی اصلی" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "مدیر پروژه " @@ -9941,6 +9944,7 @@ msgstr "" "شما درخواست بررسی پوشه های s٪ برای پیدا کردن پروژه های گودات را داده اید. " "آیا انجام این عمل را تایید می کنید؟" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "مدیر پروژه" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 62c2e7a951..bc8d755714 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-08-05 16:58+0000\n" +"PO-Revision-Date: 2020-09-05 09:37+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -24,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1117,6 +1117,9 @@ msgstr "Projektin perustajat" msgid "Lead Developer" msgstr "Pääkehittäjä" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projektipäällikkö " @@ -1138,14 +1141,12 @@ msgid "Gold Sponsors" msgstr "Kultasponsorit" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "Hopealahjoittajat" +msgstr "Hopeasponsorit" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "Pronssilahjoittajat" +msgstr "Pronssisponsorit" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -9872,6 +9873,7 @@ msgstr "" "Haluatko varmasti etsiä %s kansiosta olemassa olevia Godot-projekteja?\n" "Tämä saattaa kestää hetken." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Projektinhallinta" diff --git a/editor/translations/fil.po b/editor/translations/fil.po index faf4436839..697692ac9c 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -1094,6 +1094,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9494,6 +9497,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 8c1d67af83..d3ec3b7719 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -79,8 +79,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-08-01 11:14+0000\n" -"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n" +"PO-Revision-Date: 2020-09-08 13:44+0200\n" +"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -88,7 +88,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Poedit 2.4.1\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -136,7 +136,7 @@ msgstr "Lors de l’appel à '%s' :" #: core/ustring.cpp msgid "B" -msgstr "Octet" +msgstr "o" #: core/ustring.cpp msgid "KiB" @@ -1196,9 +1196,12 @@ msgstr "Fondateurs du projet" msgid "Lead Developer" msgstr "Développeur principal" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Gestionnaire de projets " +msgstr "Chef de projet " #: editor/editor_about.cpp msgid "Developers" @@ -1217,14 +1220,12 @@ msgid "Gold Sponsors" msgstr "Sponsors Or" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "Donateurs Argent" +msgstr "Sponsors Argent" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "Donateurs Bronze" +msgstr "Sponsors Bronze" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -8590,7 +8591,7 @@ msgstr "Système de contrôle de version" #: editor/plugins/version_control_editor_plugin.cpp msgid "Initialize" -msgstr "initialiser" +msgstr "Initialiser" #: editor/plugins/version_control_editor_plugin.cpp msgid "Staging area" @@ -10027,6 +10028,7 @@ msgstr "" "Godot existants ?\n" "Cela pourrait prendre un moment." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Gestionnaire de projets" diff --git a/editor/translations/ga.po b/editor/translations/ga.po index da64cfe007..d3733ca614 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -1086,6 +1086,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9489,6 +9492,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/he.po b/editor/translations/he.po index 48bb2ad5c0..2661ed39ff 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-04 06:51+0000\n" +"PO-Revision-Date: 2020-09-08 11:40+0000\n" "Last-Translator: Ziv D <wizdavid@gmail.com>\n" "Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/" "godot/he/>\n" @@ -1133,6 +1133,9 @@ msgstr "מקימי המיזם" msgid "Lead Developer" msgstr "מפתחים ראשיים" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "מנהל המיזם " @@ -9961,6 +9964,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "מנהל המיזמים" @@ -12174,11 +12178,11 @@ msgstr "מזהה לא חוקי:" #: platform/iphone/export/export.cpp msgid "Required icon is not specified in the preset." -msgstr "" +msgstr "סמליל נדרש אינו מוגדר בהגדרות יצוא." #: platform/javascript/export/export.cpp msgid "Stop HTTP Server" -msgstr "" +msgstr "עצירת שרת HTTP" #: platform/javascript/export/export.cpp msgid "Run in Browser" @@ -12213,74 +12217,74 @@ msgid "Using default boot splash image." msgstr "נעשה שימוש בתמונת הפתיח כבררת מחדל." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package short name." -msgstr "שם שגוי." +msgstr "שם קצר של חבילה לא חוקי." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package unique name." -msgstr "שם שגוי." +msgstr "שם יחודי של חבילה לא חוקי." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package publisher display name." -msgstr "שם שגוי." +msgstr "שם תצוגה של מפרסם החבילה לא חוקי." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid product GUID." -msgstr "שם שגוי." +msgstr "GUID מוצר לא חוקי." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid publisher GUID." -msgstr "נתיב שגוי." +msgstr "GUID מפרסם לא חוקי." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid background color." -msgstr "שם שגוי." +msgstr "צבע רקע לא חוקי." #: platform/uwp/export/export.cpp msgid "Invalid Store Logo image dimensions (should be 50x50)." -msgstr "" +msgstr "מידות תמונת לוגו חנות לא חוקיות (צריכות להיות 50x50)." #: platform/uwp/export/export.cpp msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." -msgstr "" +msgstr "מידות תמונת לוגו מרובעות 44x44 לא חוקיות (צריכות להיות 44x44)." #: platform/uwp/export/export.cpp msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." -msgstr "" +msgstr "מידות תמונת לוגו מרובעות 71x71 לא חוקיות (צריכות להיות 71x71)." #: platform/uwp/export/export.cpp msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." msgstr "" +"מידות תמונת לוגו מרובעות בגודל 150x150 לא חוקיות (צריכות להיות 150x150)." #: platform/uwp/export/export.cpp msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." msgstr "" +"מידות תמונת לוגו מרובעות בגודל 310x310 אינן חוקיות (צריכות להיות 310x310)." #: platform/uwp/export/export.cpp msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." -msgstr "" +msgstr "מידות תמונת לוגו רחבה 310x150 לא חוקיות (צריכות להיות 310x150)." #: platform/uwp/export/export.cpp msgid "Invalid splash screen image dimensions (should be 620x300)." -msgstr "" +msgstr "מידות תמונת פתיח לא חוקיות (צריכות להיות 620x300)." #: scene/2d/animated_sprite.cpp msgid "" "A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" +"יש ליצור או להגדיר משאב SpriteFrames במאפיין \"Frames\" כדי ש- " +"AnimatedSprite יציג תמוניות." #: scene/2d/canvas_modulate.cpp msgid "" "Only one visible CanvasModulate is allowed per scene (or set of instanced " "scenes). The first created one will work, while the rest will be ignored." msgstr "" +"מותר רק CanvasModulate גלוי אחד לכל סצנה (או סט מופעי סצינות). הראשון שנוצר " +"יעבוד, ואילו השאר לא." #: scene/2d/collision_object_2d.cpp msgid "" @@ -12288,6 +12292,9 @@ msgid "" "Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " "define its shape." msgstr "" +"למפרק זה אין צורה ולכן הוא לא יכול להתנגש או לקיים אינטראקציה עם אובייקטים " +"אחרים.\n" +"הוספת CollisionShape2D או CollisionPolygon2D כילד תגדיר את צורתו." #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -12295,6 +12302,9 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" +"CollisionPolygon2D משמש רק להספקת צורת התנגשות למפרק היורש מ-" +"CollisionObject2D. השימוש בו הוא רק כילד של Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D וכו'." #: scene/2d/collision_polygon_2d.cpp msgid "An empty CollisionPolygon2D has no effect on collision." @@ -12306,18 +12316,23 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" +"CollisionShape2D משמש רק להספקת צורת התנגשות למפרק היורש מ-" +"CollisionObject2D. השימוש בו הוא רק כילד של Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D וכו'." #: scene/2d/collision_shape_2d.cpp msgid "" "A shape must be provided for CollisionShape2D to function. Please create a " "shape resource for it!" -msgstr "" +msgstr "יש לספק צורה כדי ש-CollisionShape2D יתפקד. יש ליצור משאב צורה עבורו!" #: scene/2d/collision_shape_2d.cpp msgid "" "Polygon-based shapes are not meant be used nor edited directly through the " "CollisionShape2D node. Please use the CollisionPolygon2D node instead." msgstr "" +"צורות מבוססות מצולע אינן מיועדות לשימוש או לעריכה ישירות דרך מפרק " +"CollisionShape2D. במקום זאת יש להשתמש במפרק מסוג CollisionPolygon2D." #: scene/2d/cpu_particles_2d.cpp msgid "" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index 0fd6f92fbb..0704292af5 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -1115,6 +1115,9 @@ msgstr "परियोजना के संस्थापक" msgid "Lead Developer" msgstr "प्रमुख डेवलपर" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "परियोजना प्रबंधक " @@ -9685,6 +9688,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "प्रोजेक्ट मैनेजर" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index 2779300580..e4ea6d0a1a 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -1102,6 +1102,9 @@ msgstr "Osnivači projekta" msgid "Lead Developer" msgstr "Glavni razvijatelj" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projektni menadžer " @@ -9539,6 +9542,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 40a6462c90..59a6e0ad25 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -11,12 +11,13 @@ # Máté Lugosi <mate.lugosi@gmail.com>, 2019. # sztrovacsek <magadeve@gmail.com>, 2019. # Ács Zoltán <acszoltan111@gmail.com>, 2020. +# cefrebevalo <szmarci711@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-08-11 14:04+0000\n" -"Last-Translator: Ács Zoltán <acszoltan111@gmail.com>\n" +"PO-Revision-Date: 2020-09-05 09:37+0000\n" +"Last-Translator: cefrebevalo <szmarci711@gmail.com>\n" "Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/" "godot/hu/>\n" "Language: hu\n" @@ -24,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -33,9 +34,8 @@ msgstr "" "Érvénytelen típus argumentum a convert()-hez használjon TYPE_* konstansokat." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp -#, fuzzy msgid "Expected a string of length 1 (a character)." -msgstr "Egy karakter hosszúságú string-et várt." +msgstr "A várt string egy karakter hosszú." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -64,10 +64,8 @@ msgid "Invalid named index '%s' for base type %s" msgstr "Érvénytelen nevezett index '%s' %s alaptípushoz" #: core/math/expression.cpp -#, fuzzy msgid "Invalid arguments to construct '%s'" msgstr "" -"Érvénytelen típus argumentum a convert()-hez használjon TYPE_* konstansokat." #: core/math/expression.cpp msgid "On call to '%s':" @@ -204,14 +202,12 @@ msgid "Change Animation Loop" msgstr "Animációs ciklus változtatása" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Property Track" -msgstr "Tulajdonság Követés" +msgstr "Tulajdonságkövetés" #: editor/animation_track_editor.cpp -#, fuzzy msgid "3D Transform Track" -msgstr "UV Térkép Transzformálása" +msgstr "" #: editor/animation_track_editor.cpp msgid "Call Method Track" @@ -226,9 +222,8 @@ msgid "Audio Playback Track" msgstr "Hang lejátszás követése" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Playback Track" -msgstr "Animáció lejátszásának leállítása. (S)" +msgstr "" #: editor/animation_track_editor.cpp msgid "Animation length (frames)" @@ -239,9 +234,8 @@ msgid "Animation length (seconds)" msgstr "Animáció hossza (másodpercben)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Track" -msgstr "Animáció nyomvonal hozzáadás" +msgstr "Nyomvonal hozzáadása" #: editor/animation_track_editor.cpp msgid "Animation Looping" @@ -261,9 +255,8 @@ msgid "Anim Clips:" msgstr "" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Track Path" -msgstr "Tömb Értékének Megváltoztatása" +msgstr "" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." @@ -1167,6 +1160,9 @@ msgstr "Projekt Alapítói" msgid "Lead Developer" msgstr "Vezető Fejlesztő" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projekt Kezelő " @@ -10228,6 +10224,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Projektkezelő" diff --git a/editor/translations/id.po b/editor/translations/id.po index 34c15ae95f..9bd5244ee5 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -1139,6 +1139,9 @@ msgstr "Penemu Proyek" msgid "Lead Developer" msgstr "Pengembang Utama" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Manajer Proyek " @@ -9897,6 +9900,7 @@ msgstr "" "Apakah Anda yakin untuk memindai %s folder untuk proyek Godot yang ada?\n" "Ini bisa memakan waktu yang lama." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Manajer Proyek" diff --git a/editor/translations/is.po b/editor/translations/is.po index 16958ecf41..7b4ed6415b 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -1122,6 +1122,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Verkefna Stjóri " @@ -9595,6 +9598,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Verkefna Stjóri" diff --git a/editor/translations/it.po b/editor/translations/it.po index 7617e0e8de..ba09df0418 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -59,8 +59,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-02 14:35+0000\n" -"Last-Translator: Ziv D <wizdavid@gmail.com>\n" +"PO-Revision-Date: 2020-09-08 11:40+0000\n" +"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -1168,6 +1168,9 @@ msgstr "Fondatori del progetto" msgid "Lead Developer" msgstr "Sviluppatore principale" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Gestore progetto " @@ -1189,14 +1192,12 @@ msgid "Gold Sponsors" msgstr "Sponsor oro" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "Donatori argento" +msgstr "Sponsor Argento" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "Donatori bronzo" +msgstr "Sponsor Bronzo" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -9981,6 +9982,7 @@ msgstr "" "esistenti?\n" "Per questo potrebbe volerci un pò." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Gestore dei progetti" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 8e82a94abf..bdab275f0f 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -1143,6 +1143,9 @@ msgstr "プロジェクト創始者" msgid "Lead Developer" msgstr "開発リーダー" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "プロジェクトマネージャー " @@ -9883,6 +9886,7 @@ msgstr "" "既存のGodotプロジェクトの%sフォルダをスキャンしますか?\n" "これにはしばらく時間がかかります。" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "プロジェクトマネージャー" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index 75fbad354b..7ec9bbd88a 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -1164,6 +1164,9 @@ msgstr "პროექტის დამფუძნებლები" msgid "Lead Developer" msgstr "მთავარი დეველოპერი" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "პროექტის მენეჯერი. " @@ -9793,6 +9796,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index f9fa96982f..83853be57c 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -1129,6 +1129,9 @@ msgstr "프로젝트 창립자" msgid "Lead Developer" msgstr "리드 개발자" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "프로젝트 매니저 " @@ -9812,6 +9815,7 @@ msgstr "" "Godot 프로젝트를 확인하기 위해 %s 폴더를 스캔할까요?\n" "시간이 걸릴 수 있습니다." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "프로젝트 매니저" diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 6449d264ad..01d9abae70 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -1127,6 +1127,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9770,6 +9773,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 6cf590f8c5..43bcc6beb0 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -1119,6 +1119,9 @@ msgstr "Projekta Dibinātāji" msgid "Lead Developer" msgstr "Galvenais Izstrādātājs" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projekta Menedžeris " @@ -9586,6 +9589,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 30ac5ce885..8f922c0f43 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -1078,6 +1078,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9467,6 +9470,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 70be9f00c8..458429641d 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -1088,6 +1088,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9483,6 +9486,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index a9719278c0..dc88f027c0 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -1085,6 +1085,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9474,6 +9477,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index 940feeb863..b25e23a674 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-02 14:35+0000\n" +"PO-Revision-Date: 2020-09-08 11:40+0000\n" "Last-Translator: Keviindran Ramachandran <keviinx@yahoo.com>\n" "Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/" "ms/>\n" @@ -1122,6 +1122,9 @@ msgstr "Pengasas Projek" msgid "Lead Developer" msgstr "Pemaju Utama" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Pengurus Projek " @@ -2379,65 +2382,68 @@ msgstr "Sumber %s yang diubahsuai telah disimpan." #: editor/editor_node.cpp msgid "A root node is required to save the scene." -msgstr "" +msgstr "Nod akar diperlukan untuk menyimpan adegan." #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "" +msgstr "Simpan Adegan Sebagai..." #: editor/editor_node.cpp msgid "No" -msgstr "" +msgstr "Tidak" #: editor/editor_node.cpp msgid "Yes" -msgstr "" +msgstr "Ya" #: editor/editor_node.cpp msgid "This scene has never been saved. Save before running?" -msgstr "" +msgstr "Adegan ini tidak pernah disimpan. Simpan sebelum menjalankan?" #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." -msgstr "" +msgstr "Operasi ini tidak boleh dilakukan tanpa adegan." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "Eksport Perpustakaan Mesh" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "" +msgstr "Operasi ini tidak boleh dilakukan tanpa nod akar." #: editor/editor_node.cpp msgid "Export Tile Set" -msgstr "" +msgstr "Eksport Tile Set" #: editor/editor_node.cpp msgid "This operation can't be done without a selected node." -msgstr "" +msgstr "Operasi ini tidak dapat dilakukan tanpa nod terpilih." #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "" +msgstr "Adegan semasa tidak disimpan. Masih buka?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "" +msgstr "Tidak dapat memuatkan semula adegan yang tidak pernah disimpan." #: editor/editor_node.cpp msgid "Reload Saved Scene" -msgstr "" +msgstr "Muatkan semula Adegan yang Disimpan" #: editor/editor_node.cpp msgid "" "The current scene has unsaved changes.\n" "Reload the saved scene anyway? This action cannot be undone." msgstr "" +"Adegan semasa mempunyai perubahan yang belum disimpan.\n" +"Masih muat semula adegan yang telah disimpan? Tindakan ini tidak boleh " +"dibuat asal." #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "" +msgstr "Jalan Cepat Adegan..." #: editor/editor_node.cpp msgid "Quit" @@ -9586,6 +9592,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 7837db5c53..a31504e186 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -1178,6 +1178,9 @@ msgstr "Prosjektgrunnleggere" msgid "Lead Developer" msgstr "Utviklingsleder" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Prosjektstyring " @@ -10312,6 +10315,7 @@ msgstr "" "Godotprosjekter.\n" "Det kan ta en stund." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Prosjektstyring" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index ac5761f63d..1dabe25c73 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -1160,6 +1160,9 @@ msgstr "Projectoprichters" msgid "Lead Developer" msgstr "Hoofdontwikkelaar" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Projectbeheer " @@ -9942,6 +9945,7 @@ msgstr "" "Wil je %s mappen doorzoeken naar bestaande Godot projecten?\n" "Dit kan een tijdje duren." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Projectbeheer" diff --git a/editor/translations/or.po b/editor/translations/or.po index 9bb6ba7410..220638494d 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -1084,6 +1084,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9473,6 +9476,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 6d7265c085..dd93a0ec83 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -1152,6 +1152,9 @@ msgstr "Założyciele projektu" msgid "Lead Developer" msgstr "Deweloper naczelny" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Menedżer projektu " @@ -9909,6 +9912,7 @@ msgstr "" "projektów Godota?\n" "To może chwilę zająć." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Menedżer projektów" diff --git a/editor/translations/pr.po b/editor/translations/pr.po index d03994f21a..9640ed40f1 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -1127,6 +1127,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9797,6 +9800,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 510cbdee51..3e9e709aab 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -1209,9 +1209,12 @@ msgstr "Fundadores do Projeto" msgid "Lead Developer" msgstr "Desenvolvedor-chefe" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Gerenciador de Projetos " +msgstr "Gerente do Projeto " #: editor/editor_about.cpp msgid "Developers" @@ -9976,6 +9979,7 @@ msgstr "" "existentes?\n" "Isso pode levar algum tempo." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Gerenciador de Projetos" diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index 489a8012f5..63c82c84ba 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po @@ -1129,6 +1129,9 @@ msgstr "Fundadores do Projeto" msgid "Lead Developer" msgstr "Desenvolvedor-chefe" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Gestor de Projeto " @@ -9875,6 +9878,7 @@ msgstr "" "Pretende pesquisar %s pastas por projetos Godot existentes?\n" "Pode demorar um pouco." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Gestor de Projetos" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index ef64a09d92..5a8c083d54 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -1126,6 +1126,9 @@ msgstr "Fondatorii Proiectului" msgid "Lead Developer" msgstr "Dezvoltator Principal" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Manager de Proiect " @@ -9922,6 +9925,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index 71711ad333..9e0ecb8e8d 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -86,12 +86,13 @@ # Ron788 <ustinov200511@gmail.com>, 2020. # Daniel <dan.ef1999@gmail.com>, 2020. # NeoLan Qu <it.bulla@mail.ru>, 2020. +# Nikita Epifanov <nikgreens@protonmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-08-15 09:32+0000\n" -"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" +"PO-Revision-Date: 2020-09-08 11:40+0000\n" +"Last-Translator: Nikita Epifanov <nikgreens@protonmail.com>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -100,7 +101,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1198,6 +1199,9 @@ msgstr "Основатели Проекта" msgid "Lead Developer" msgstr "Ведущий разработчик" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Менеджер проектов " @@ -1219,14 +1223,12 @@ msgid "Gold Sponsors" msgstr "Золотые спонсоры" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "Серебряные доноры" +msgstr "Серебряные спонсоры" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "Бронзовые доноры" +msgstr "Бронзовые спонсоры" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -9950,6 +9952,7 @@ msgstr "" "Вы действительно хотите поискать существующие проекты Godot в %s папках?\n" "Это может занять много времени." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Менеджер проектов" diff --git a/editor/translations/si.po b/editor/translations/si.po index 2ca3642fce..6db6ba355a 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -1107,6 +1107,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9550,6 +9553,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 13482d4c59..7a5bd57c4c 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-04 06:51+0000\n" +"PO-Revision-Date: 2020-09-08 11:40+0000\n" "Last-Translator: Richard Urban <redasuio1@gmail.com>\n" "Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/" "godot/sk/>\n" @@ -1114,6 +1114,9 @@ msgstr "Zakladatelia Projektu" msgid "Lead Developer" msgstr "Vedúci Vývojár" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Manažér Projektu " @@ -1135,14 +1138,12 @@ msgid "Gold Sponsors" msgstr "Zlatý Sponzori" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "Strieborný Darcovia" +msgstr "Strieborný Sponzori" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "Bronzový Darcovia" +msgstr "Bronzový Sponzori" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -5657,208 +5658,199 @@ msgstr "Vytvoriť Polygon3D" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly" -msgstr "" +msgstr "Upraviť Poly" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "Upraviť Poly (Odstrániť Bod)" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" -msgstr "" +msgstr "Nastaviť Rukoväť" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Load Emission Mask" -msgstr "" +msgstr "Načíť Emisnú Masku" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Restart" -msgstr "Uložiť súbor" +msgstr "Reštartovať" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" -msgstr "" +msgstr "Zmazať Emisnú Masku" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Particles" -msgstr "" +msgstr "Particly" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generated Point Count:" -msgstr "" +msgstr "Generovaný Bodový Počet:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Mask" -msgstr "" +msgstr "Emisná Maska" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Solid Pixels" -msgstr "" +msgstr "Pevné Pixely" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Border Pixels" -msgstr "" +msgstr "Ohraničené Pixely" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Directed Border Pixels" -msgstr "Priečinky a Súbory:" +msgstr "Pixely s Priamym Ohraničením" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Capture from Pixel" -msgstr "" +msgstr "Snímanie z Pixelu" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "" +msgstr "Emisné Farby" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" -msgstr "" +msgstr "CPUParticly" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "" +msgstr "Vytvoriť Emisné Body z Mesh-u" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "" +msgstr "Vytvoriť Emisné Body z Node-u" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 0" -msgstr "" +msgstr "Plochý 0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 1" -msgstr "" +msgstr "Plochý 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" -msgstr "" +msgstr "Zvyšovanie" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease Out" -msgstr "" +msgstr "Znižovanie" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" -msgstr "" +msgstr "Hladkýkrok" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Point" -msgstr "" +msgstr "Modifikovať Bod Krivky" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Tangent" -msgstr "" +msgstr "Modifikovať Tangetu Krivky" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Curve Preset" -msgstr "" +msgstr "Načítať Predvoľbu Krivky" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Signály:" +msgstr "Pridať Bod" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Všetky vybrané" +msgstr "Vymazať Bod" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "Lineárne" +msgstr "Lineárne Vľavo" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Lineárne" +msgstr "Lineárne Vpravo" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Načítať predvolené" +msgstr "Načítať Predvoľbu" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Curve Point" -msgstr "Všetky vybrané" +msgstr "Vymazať Bod Krivky" #: editor/plugins/curve_editor_plugin.cpp msgid "Toggle Curve Linear Tangent" -msgstr "" +msgstr "Prepnúť Lineárnu Tangetu Krivky" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" -msgstr "" +msgstr "Podržte Shift aby ste upravili tangetu individuálne" #: editor/plugins/curve_editor_plugin.cpp msgid "Right click to add point" -msgstr "" +msgstr "Pravým kliknutím pridáťe Bod" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "" +msgstr "Vypiecť GI Probe" #: editor/plugins/gradient_editor_plugin.cpp msgid "Gradient Edited" -msgstr "" +msgstr "Prechod je Upravený" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" -msgstr "" +msgstr "Predmet %d" #: editor/plugins/item_list_editor_plugin.cpp msgid "Items" -msgstr "" +msgstr "Predmety" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item List Editor" -msgstr "" +msgstr "List Editor Predmetov" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" -msgstr "" +msgstr "Vytvoriť Occluder Polygon" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "" +msgstr "Mesh je prázdny!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Couldn't create a Trimesh collision shape." -msgstr "Vytvoriť adresár" +msgstr "Nepodarilo sa vytvoriť Trimesh collision shape." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "" +msgstr "Vytvoriť Static Trimesh Telo" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" -msgstr "" +msgstr "Toto nefunguje na koreni scény!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Shape" -msgstr "" +msgstr "Vytvoriť Trimesh Static Shape" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create a single convex collision shape for the scene root." @@ -9827,6 +9819,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 4316ed06b1..b095b4d9b7 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -1172,6 +1172,9 @@ msgstr "Ustanovitelji Projekta" msgid "Lead Developer" msgstr "Vodilni Razvajalec" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Upravljalnik Projekta " @@ -10176,6 +10179,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Upravljalnik Projekta" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index 7c6d2e2f74..b4789e5591 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -1114,6 +1114,9 @@ msgstr "Themeluesit e Projektit" msgid "Lead Developer" msgstr "Krye Zhvilluesi" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Menaxheri Projektit " @@ -9827,6 +9830,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 84536220b9..09a0750482 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -1228,6 +1228,9 @@ msgstr "Оснивачи пројекта" msgid "Lead Developer" msgstr "Главни девелопер" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp #, fuzzy msgid "Project Manager " @@ -11004,6 +11007,7 @@ msgstr "" "пројектима?\n" "Ово може потрајати." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Менаџер пројекта" diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index b53b92a4e1..14f9fd8d1f 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -1116,6 +1116,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9625,6 +9628,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index d6e91a34b3..562939496f 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -1130,9 +1130,12 @@ msgstr "Projektgrundare" msgid "Lead Developer" msgstr "Ledande utvecklare" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Projekthanterare " +msgstr "Projektledare " #: editor/editor_about.cpp msgid "Developers" @@ -10067,6 +10070,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Projektledare" diff --git a/editor/translations/ta.po b/editor/translations/ta.po index cf057954a2..a6df89a718 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -1112,6 +1112,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9548,6 +9551,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/te.po b/editor/translations/te.po index 3ad5326ea6..ce1fc1d478 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -1086,6 +1086,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9476,6 +9479,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index 673cca50b2..1408e9edb3 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -1101,6 +1101,9 @@ msgstr "ผู้ริเริ่มโครงการ" msgid "Lead Developer" msgstr "ผู้พัฒนาหลัก" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "ผู้จัดการโครงการ " @@ -9857,6 +9860,7 @@ msgstr "" "ทำการสแกนหาโปรเจกต์ ในโฟลเดอร์ %s หรือไม่?\n" "อาจจะใช้เวลาสักครู่" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "ตัวจัดการโปรเจกต์" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 7710872d7b..1ac1204e09 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -1161,6 +1161,9 @@ msgstr "Projenin Kurucuları" msgid "Lead Developer" msgstr "Baş Geliştirici" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Proje Yöneticisi " @@ -9909,6 +9912,7 @@ msgstr "" "misiniz?\n" "Bu biraz zaman alabilir." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Proje Yöneticisi" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index a35264b40d..672785a2aa 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-08-04 06:43+0000\n" +"PO-Revision-Date: 2020-09-05 09:37+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -29,7 +29,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1136,6 +1136,9 @@ msgstr "Засновники проєкту" msgid "Lead Developer" msgstr "Ведучий розробник" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Керівник проектів " @@ -1157,12 +1160,10 @@ msgid "Gold Sponsors" msgstr "Золоті спонсори" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" msgstr "Срібні донори" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" msgstr "Бронзові донори" @@ -9912,6 +9913,7 @@ msgstr "" "Ви справді хочете виконати пошук у %s теках наявних проєктів Godot?\n" "Пошук може бути доволі тривалим." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Керівник проекту" diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 6b152e43b3..89208b4070 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -1104,6 +1104,9 @@ msgstr "" msgid "Lead Developer" msgstr "" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "" @@ -9711,6 +9714,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index eb260d535e..579b8550ee 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -1128,6 +1128,9 @@ msgstr "Các đồng sáng lập dự án" msgid "Lead Developer" msgstr "Phát triển chính" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "Quản lí Dự án " @@ -9893,6 +9896,7 @@ msgstr "" "Bạn có chắc chắn quét các thư mục %s để tìm các dự án Godot có sẵn?\n" "Điều này sẽ mất chút thời gian." +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "Trình quản lý Dự án" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index 5d2787f995..fede4b0528 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -75,8 +75,8 @@ msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2020-08-24 13:17+0000\n" -"Last-Translator: UnluckyNinja <unluckyninja1994@gmail.com>\n" +"PO-Revision-Date: 2020-09-05 09:37+0000\n" +"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -84,7 +84,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.2.1-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1169,6 +1169,9 @@ msgstr "项目创始人" msgid "Lead Developer" msgstr "主要开发者" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "项目管理员 " @@ -1190,14 +1193,12 @@ msgid "Gold Sponsors" msgstr "黄金赞助" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "白银捐赠者" +msgstr "白银赞助" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "青铜捐赠者" +msgstr "青铜赞助" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -9759,6 +9760,7 @@ msgstr "" "您确定要扫描%s文件夹中的现有Godot项目吗? \n" "这可能需要一段时间。" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "项目管理器" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index 3fdbcd4f76..7c7571fff0 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -1158,6 +1158,9 @@ msgstr "專案開荒人" msgid "Lead Developer" msgstr "主要開發者" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "開啟 Project Manager " @@ -10140,6 +10143,7 @@ msgid "" "This could take a while." msgstr "" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index b1cf13ad94..9063126888 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -29,8 +29,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-07-31 03:47+0000\n" -"Last-Translator: MintSoda <lionlxh@qq.com>\n" +"PO-Revision-Date: 2020-09-08 11:40+0000\n" +"Last-Translator: BinotaLIU <me@binota.org>\n" "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hant/>\n" "Language: zh_TW\n" @@ -38,7 +38,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1124,6 +1124,9 @@ msgstr "專案創始人" msgid "Lead Developer" msgstr "主要開發者" +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " msgstr "專案管理員 " @@ -1145,14 +1148,12 @@ msgid "Gold Sponsors" msgstr "黃金贊助" #: editor/editor_about.cpp -#, fuzzy msgid "Silver Sponsors" -msgstr "白銀捐贈者" +msgstr "白銀贊助" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "紅銅捐贈者" +msgstr "青銅贊助" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -9720,6 +9721,7 @@ msgstr "" "確定要掃描 %s 中的 Godot 專案嗎?\n" "這可能需要一段時間。" +#. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp msgid "Project Manager" msgstr "專案管理員" diff --git a/glsl_builders.py b/glsl_builders.py index af9afcae70..e1a6e41bea 100644 --- a/glsl_builders.py +++ b/glsl_builders.py @@ -211,11 +211,6 @@ def build_raw_header(filename): fd.close() -def build_rd_headers(target, source, env): - for x in source: - build_rd_header(str(x)) - - def build_raw_headers(target, source, env): for x in source: build_raw_header(str(x)) diff --git a/misc/dist/html/fixed-size.html b/misc/dist/html/fixed-size.html index a5633115d5..85064b34fd 100644 --- a/misc/dist/html/fixed-size.html +++ b/misc/dist/html/fixed-size.html @@ -236,7 +236,6 @@ $GODOT_HEAD_INCLUDE const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED; const INDETERMINATE_STATUS_STEP_MS = 100; - var container = document.getElementById('container'); var canvas = document.getElementById('canvas'); var statusProgress = document.getElementById('status-progress'); var statusProgressInner = document.getElementById('status-progress-inner'); diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html index 435013cb5e..be25ce4839 100644 --- a/misc/dist/html/full-size.html +++ b/misc/dist/html/full-size.html @@ -201,7 +201,7 @@ $GODOT_HEAD_INCLUDE throw new Error('Invalid status mode'); } statusMode = mode; - } + }; function animateStatusIndeterminate(ms) { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 8fbc5bcb25..b4ede55f0a 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2077,18 +2077,32 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod push_error(vformat(R"(Cannot find constant "%s" on type "%s".)", name, base.to_string()), p_identifier); } } else { - Callable::CallError temp; - Variant dummy = Variant::construct(base.builtin_type, nullptr, 0, temp); - List<PropertyInfo> properties; - dummy.get_property_list(&properties); - for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) { - const PropertyInfo &prop = E->get(); - if (prop.name == name) { - p_identifier->set_datatype(type_from_property(prop)); + switch (base.builtin_type) { + case Variant::NIL: { + push_error(vformat(R"(Invalid get index "%s" on base Nil)", name), p_identifier); return; } + case Variant::DICTIONARY: { + GDScriptParser::DataType dummy; + dummy.kind = GDScriptParser::DataType::VARIANT; + p_identifier->set_datatype(dummy); + return; + } + default: { + Callable::CallError temp; + Variant dummy = Variant::construct(base.builtin_type, nullptr, 0, temp); + List<PropertyInfo> properties; + dummy.get_property_list(&properties); + for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) { + const PropertyInfo &prop = E->get(); + if (prop.name == name) { + p_identifier->set_datatype(type_from_property(prop)); + return; + } + } + push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier); + } } - push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier); } return; } diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 992f8f4b58..57b95f5b21 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -108,20 +108,20 @@ GDScriptParserRef::~GDScriptParserRef() { if (analyzer != nullptr) { memdelete(analyzer); } - MutexLock(GDScriptCache::singleton->lock); + MutexLock lock(GDScriptCache::singleton->lock); GDScriptCache::singleton->parser_map.erase(path); } GDScriptCache *GDScriptCache::singleton = nullptr; void GDScriptCache::remove_script(const String &p_path) { - MutexLock(singleton->lock); + MutexLock lock(singleton->lock); singleton->shallow_gdscript_cache.erase(p_path); singleton->full_gdscript_cache.erase(p_path); } Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptParserRef::Status p_status, Error &r_error, const String &p_owner) { - MutexLock(singleton->lock); + MutexLock lock(singleton->lock); Ref<GDScriptParserRef> ref; if (p_owner != String()) { singleton->dependencies[p_owner].insert(p_path); @@ -168,7 +168,7 @@ String GDScriptCache::get_source_code(const String &p_path) { } Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const String &p_owner) { - MutexLock(singleton->lock); + MutexLock lock(singleton->lock); if (p_owner != String()) { singleton->dependencies[p_owner].insert(p_path); } @@ -190,7 +190,7 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri } Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) { - MutexLock(singleton->lock); + MutexLock lock(singleton->lock); if (p_owner != String()) { singleton->dependencies[p_owner].insert(p_path); diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 7dad878eb1..da4cbe34c7 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -84,7 +84,7 @@ public: return; } - // TODO: Readd compiled/encrypted GDScript on export. + // TODO: Readd compiled GDScript on export. return; } }; diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index 6f318aab4a..cc0da44a13 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -2,6 +2,7 @@ using GodotTools.Core; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace GodotTools.ProjectEditor @@ -88,7 +89,7 @@ namespace GodotTools.ProjectEditor string solutionPath = Path.Combine(DirectoryPath, Name + ".sln"); string content = string.Format(SolutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg); - File.WriteAllText(solutionPath, content); + File.WriteAllText(solutionPath, content, Encoding.UTF8); // UTF-8 with BOM } public DotNetSolution(string name) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 26bd828a5b..3dff37279b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -670,41 +670,37 @@ namespace Godot public static bool operator <(Vector2 left, Vector2 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { return left.y < right.y; } - return left.x < right.x; } public static bool operator >(Vector2 left, Vector2 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { return left.y > right.y; } - return left.x > right.x; } public static bool operator <=(Vector2 left, Vector2 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { return left.y <= right.y; } - return left.x <= right.x; } public static bool operator >=(Vector2 left, Vector2 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { return left.y >= right.y; } - return left.x >= right.x; } @@ -714,7 +710,6 @@ namespace Godot { return Equals((Vector2)obj); } - return false; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index d9b16a6afd..4a4a2a43cd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -713,49 +713,53 @@ namespace Godot public static bool operator <(Vector3 left, Vector3 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { - if (Mathf.IsEqualApprox(left.y, right.y)) + if (left.y == right.y) + { return left.z < right.z; + } return left.y < right.y; } - return left.x < right.x; } public static bool operator >(Vector3 left, Vector3 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { - if (Mathf.IsEqualApprox(left.y, right.y)) + if (left.y == right.y) + { return left.z > right.z; + } return left.y > right.y; } - return left.x > right.x; } public static bool operator <=(Vector3 left, Vector3 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { - if (Mathf.IsEqualApprox(left.y, right.y)) + if (left.y == right.y) + { return left.z <= right.z; + } return left.y < right.y; } - return left.x < right.x; } public static bool operator >=(Vector3 left, Vector3 right) { - if (Mathf.IsEqualApprox(left.x, right.x)) + if (left.x == right.x) { - if (Mathf.IsEqualApprox(left.y, right.y)) + if (left.y == right.y) + { return left.z >= right.z; + } return left.y > right.y; } - return left.x > right.x; } diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 6d7b771fd3..6e351001d4 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -107,7 +107,7 @@ void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]] GDMonoAssembly *gdassembly = memnew(GDMonoAssembly(name, image, assembly)); #ifdef GD_MONO_HOT_RELOAD - const char *path = mono_image_get_filename(image); + String path = String::utf8(mono_image_get_filename(image)); if (FileAccess::exists(path)) { gdassembly->modified_time = FileAccess::get_modified_time(path); } diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index 3aceaf11c5..346833ab9c 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -158,14 +158,16 @@ void AudioStreamOGGVorbis::clear_data() { void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) { int src_data_len = p_data.size(); -#define MAX_TEST_MEM (1 << 20) - uint32_t alloc_try = 1024; Vector<char> alloc_mem; char *w; stb_vorbis *ogg_stream = nullptr; stb_vorbis_alloc ogg_alloc; + // Vorbis comments may be up to UINT32_MAX, but that's arguably pretty rare. + // Let's go with 2^30 so we don't risk going out of bounds. + const uint32_t MAX_TEST_MEM = 1 << 30; + while (alloc_try < MAX_TEST_MEM) { alloc_mem.resize(alloc_try); w = alloc_mem.ptrw(); @@ -205,6 +207,8 @@ void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) { break; } } + + ERR_FAIL_COND_MSG(alloc_try == MAX_TEST_MEM, vformat("Couldn't set vorbis data even with an alloc buffer of %d bytes, report bug.", MAX_TEST_MEM)); } Vector<uint8_t> AudioStreamOGGVorbis::get_data() const { diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 9e7266b95a..5bdcb84244 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -73,8 +73,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f } // Read HALF channel as FLOAT. (GH-13490) + bool use_float16 = false; for (int i = 0; i < exr_header.num_channels; i++) { if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) { + use_float16 = true; exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; } } @@ -102,33 +104,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f idxB = c; } else if (strcmp(exr_header.channels[c].name, "A") == 0) { idxA = c; - } - } - - if (exr_header.num_channels == 1) { - // Grayscale channel only. - idxR = 0; - idxG = 0; - idxB = 0; - idxA = 0; - } else { - // Assume RGB(A) - if (idxR == -1) { - ERR_PRINT("TinyEXR: R channel not found."); - // @todo { free exr_image } - return ERR_FILE_CORRUPT; - } - - if (idxG == -1) { - ERR_PRINT("TinyEXR: G channel not found."); - // @todo { free exr_image } - return ERR_FILE_CORRUPT; - } - - if (idxB == -1) { - ERR_PRINT("TinyEXR: B channel not found."); - // @todo { free exr_image } - return ERR_FILE_CORRUPT; + } else if (strcmp(exr_header.channels[c].name, "Y") == 0) { + idxR = c; + idxG = c; + idxB = c; } } @@ -138,14 +117,27 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f Image::Format format; int output_channels = 0; + int channel_size = use_float16 ? 2 : 4; if (idxA != -1) { - imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16 - format = Image::FORMAT_RGBAH; + imgdata.resize(exr_image.width * exr_image.height * 4 * channel_size); //RGBA + format = use_float16 ? Image::FORMAT_RGBAH : Image::FORMAT_RGBAF; output_channels = 4; - } else { - imgdata.resize(exr_image.width * exr_image.height * 6); //RGB16 - format = Image::FORMAT_RGBH; + } else if (idxB != -1) { + ERR_FAIL_COND_V(idxG == -1, ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT); + imgdata.resize(exr_image.width * exr_image.height * 3 * channel_size); //RGB + format = use_float16 ? Image::FORMAT_RGBH : Image::FORMAT_RGBF; output_channels = 3; + } else if (idxG != -1) { + ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT); + imgdata.resize(exr_image.width * exr_image.height * 2 * channel_size); //RG + format = use_float16 ? Image::FORMAT_RGH : Image::FORMAT_RGF; + output_channels = 2; + } else { + ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT); + imgdata.resize(exr_image.width * exr_image.height * 1 * channel_size); //R + format = use_float16 ? Image::FORMAT_RH : Image::FORMAT_RF; + output_channels = 1; } EXRTile single_image_tile; @@ -175,9 +167,11 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f exr_tiles = exr_image.tiles; } + //print_line("reading format: " + Image::get_format_name(format)); { uint8_t *wd = imgdata.ptrw(); - uint16_t *iw = (uint16_t *)wd; + uint16_t *iw16 = (uint16_t *)wd; + float *iw32 = (float *)wd; // Assume `out_rgba` have enough memory allocated. for (int tile_index = 0; tile_index < num_tiles; tile_index++) { @@ -187,41 +181,99 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f int th = tile.height; const float *r_channel_start = reinterpret_cast<const float *>(tile.images[idxR]); - const float *g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]); - const float *b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]); + const float *g_channel_start = nullptr; + const float *b_channel_start = nullptr; const float *a_channel_start = nullptr; + if (idxG != -1) { + g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]); + } + if (idxB != -1) { + b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]); + } if (idxA != -1) { a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]); } - uint16_t *first_row_w = iw + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels; + uint16_t *first_row_w16 = iw16 + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels; + float *first_row_w32 = iw32 + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels; for (int y = 0; y < th; y++) { const float *r_channel = r_channel_start + y * tile_width; - const float *g_channel = g_channel_start + y * tile_width; - const float *b_channel = b_channel_start + y * tile_width; + const float *g_channel = nullptr; + const float *b_channel = nullptr; const float *a_channel = nullptr; - + if (g_channel_start) { + g_channel = g_channel_start + y * tile_width; + } + if (b_channel_start) { + b_channel = b_channel_start + y * tile_width; + } if (a_channel_start) { a_channel = a_channel_start + y * tile_width; } - uint16_t *row_w = first_row_w + (y * exr_image.width * output_channels); - - for (int x = 0; x < tw; x++) { - Color color(*r_channel++, *g_channel++, *b_channel++); - - if (p_force_linear) { - color = color.to_linear(); + if (use_float16) { + uint16_t *row_w = first_row_w16 + (y * exr_image.width * output_channels); + + for (int x = 0; x < tw; x++) { + Color color; + color.r = *r_channel++; + if (g_channel) { + color.g = *g_channel++; + } + if (b_channel) { + color.b = *b_channel++; + } + if (a_channel) { + color.a = *a_channel++; + } + + if (p_force_linear) { + color = color.to_linear(); + } + + *row_w++ = Math::make_half_float(color.r); + if (g_channel) { + *row_w++ = Math::make_half_float(color.g); + } + if (b_channel) { + *row_w++ = Math::make_half_float(color.b); + } + if (a_channel) { + *row_w++ = Math::make_half_float(color.a); + } } - - *row_w++ = Math::make_half_float(color.r); - *row_w++ = Math::make_half_float(color.g); - *row_w++ = Math::make_half_float(color.b); - - if (idxA != -1) { - *row_w++ = Math::make_half_float(*a_channel++); + } else { + float *row_w = first_row_w32 + (y * exr_image.width * output_channels); + + for (int x = 0; x < tw; x++) { + Color color; + color.r = *r_channel++; + if (g_channel) { + color.g = *g_channel++; + } + if (b_channel) { + color.b = *b_channel++; + } + if (a_channel) { + color.a = *a_channel++; + } + + if (p_force_linear) { + color = color.to_linear(); + } + + *row_w++ = color.r; + if (g_channel) { + *row_w++ = color.g; + } + if (b_channel) { + *row_w++ = color.b; + } + if (a_channel) { + *row_w++ = color.a; + } } } } diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml index 2054276655..c80b903e39 100644 --- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml +++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml @@ -97,7 +97,7 @@ { "urls": [ "turn:turn.example.com:3478" ], # One or more TURN servers. "username": "a_username", # Optional username for the TURN server. - "credentials": "a_password", # Optional password for the TURN server. + "credential": "a_password", # Optional password for the TURN server. } ] } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index e318b35495..9a144c0a78 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -723,7 +723,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { return OK; } - static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { APKExportData *ed = (APKExportData *)p_userdata; String dst_path = p_path.replace_first("res://", "assets/"); @@ -731,7 +731,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { return OK; } - static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { return OK; } @@ -1525,7 +1525,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } public: - typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total); + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override { diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 209a664f8f..95f870bc35 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -99,7 +99,7 @@ Error store_string_at_path(const String &p_path, const String &p_data) { // It is used by the export_project_files method to save all the asset files into the gradle project. // It's functionality mirrors that of the method save_apk_file. // This method will be called ONLY when custom build is enabled. -Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { +Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { String dst_path = p_path.replace_first("res://", "res://android/build/assets/"); Error err = store_file_at_path(dst_path, p_data); return err; diff --git a/platform/javascript/engine/engine.js b/platform/javascript/engine/engine.js index d709422abb..2630812814 100644 --- a/platform/javascript/engine/engine.js +++ b/platform/javascript/engine/engine.js @@ -121,7 +121,7 @@ Function('return this')()['Engine'] = (function() { if (me.onExit) me.onExit(code); me.rtenv = null; - } + }; return new Promise(function(resolve, reject) { preloader.preloadedFiles.forEach(function(file) { me.rtenv['copyToFS'](file.path, file.buffer); @@ -207,18 +207,18 @@ Function('return this')()['Engine'] = (function() { if (this.rtenv) this.rtenv.onExecute = onExecute; this.onExecute = onExecute; - } + }; Engine.prototype.setOnExit = function(onExit) { this.onExit = onExit; - } + }; Engine.prototype.copyToFS = function(path, buffer) { if (this.rtenv == null) { throw new Error("Engine must be inited before copying files"); } this.rtenv['copyToFS'](path, buffer); - } + }; // Closure compiler exported engine methods. /** @export */ diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index ede0d7c76b..5679ec3eac 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -961,7 +961,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform { return true; } - static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { AppxPackager *packager = (AppxPackager *)p_userdata; String dst_path = p_path.replace_first("res://", "game/"); diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 6fef44481a..211082d610 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -60,7 +60,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventMouseButton> mouse_button = p_event; bool ui_accept = p_event->is_action("ui_accept") && !p_event->is_echo(); - bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) > 0; + bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) != 0; if (button_masked || ui_accept) { on_action_event(p_event); return; @@ -326,12 +326,12 @@ bool BaseButton::is_keep_pressed_outside() const { return keep_pressed_outside; } -void BaseButton::set_shortcut(const Ref<ShortCut> &p_shortcut) { +void BaseButton::set_shortcut(const Ref<Shortcut> &p_shortcut) { shortcut = p_shortcut; set_process_unhandled_input(shortcut.is_valid()); } -Ref<ShortCut> BaseButton::get_shortcut() const { +Ref<Shortcut> BaseButton::get_shortcut() const { return shortcut; } @@ -414,7 +414,7 @@ void BaseButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask"); ADD_PROPERTY(PropertyInfo(Variant::INT, "enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_enabled_focus_mode", "get_enabled_focus_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "ShortCut"), "set_shortcut", "get_shortcut"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group"); BIND_ENUM_CONSTANT(DRAW_NORMAL); diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 12272446d5..8e71931f8b 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -50,7 +50,7 @@ private: bool shortcut_in_tooltip; bool keep_pressed_outside; FocusMode enabled_focus_mode; - Ref<ShortCut> shortcut; + Ref<Shortcut> shortcut; ActionMode action_mode; struct Status { @@ -118,8 +118,8 @@ public: void set_enabled_focus_mode(FocusMode p_mode); FocusMode get_enabled_focus_mode() const; - void set_shortcut(const Ref<ShortCut> &p_shortcut); - Ref<ShortCut> get_shortcut() const; + void set_shortcut(const Ref<Shortcut> &p_shortcut); + Ref<Shortcut> get_shortcut() const; virtual String get_tooltip(const Point2 &p_pos) const override; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index fafbb298b7..cbe0367c7b 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -873,6 +873,7 @@ void ColorPickerButton::_color_changed(const Color &p_color) { void ColorPickerButton::_modal_closed() { emit_signal("popup_closed"); + set_pressed(false); } void ColorPickerButton::pressed() { @@ -976,9 +977,8 @@ void ColorPickerButton::_update_picker() { popup->add_child(picker); add_child(popup); picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed)); - popup->connect("modal_closed", callable_mp(this, &ColorPickerButton::_modal_closed)); popup->connect("about_to_popup", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true)); - popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false)); + popup->connect("popup_hide", callable_mp(this, &ColorPickerButton::_modal_closed)); picker->set_pick_color(color); picker->set_edit_alpha(edit_alpha); emit_signal("picker_created"); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 8b95acff70..1b8f04297d 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -313,7 +313,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { DisplayServer::get_singleton()->virtual_keyboard_hide(); } - return; } break; case KEY_BACKSPACE: { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 2fdcf11ca8..bc70809ad5 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -717,7 +717,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int } #define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global) \ - ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid ShortCut."); \ + ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid Shortcut."); \ _ref_shortcut(p_shortcut); \ item.text = p_shortcut->get_name(); \ item.xl_text = tr(item.text); \ @@ -725,7 +725,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int item.shortcut = p_shortcut; \ item.shortcut_is_global = p_global; -void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); items.push_back(item); @@ -733,7 +733,7 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_g child_controls_changed(); } -void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); item.icon = p_icon; @@ -742,7 +742,7 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortC child_controls_changed(); } -void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; @@ -751,7 +751,7 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo child_controls_changed(); } -void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); item.icon = p_icon; @@ -761,7 +761,7 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref< child_controls_changed(); } -void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; @@ -770,7 +770,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ child_controls_changed(); } -void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); item.icon = p_icon; @@ -931,8 +931,8 @@ String PopupMenu::get_item_tooltip(int p_idx) const { return items[p_idx].tooltip; } -Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<ShortCut>()); +Ref<Shortcut> PopupMenu::get_item_shortcut(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Shortcut>()); return items[p_idx].shortcut; } @@ -970,7 +970,7 @@ void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) { control->update(); } -void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global) { +void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global) { ERR_FAIL_INDEX(p_idx, items.size()); if (items[p_idx].shortcut.is_valid()) { _unref_shortcut(items[p_idx].shortcut); @@ -1209,7 +1209,7 @@ Array PopupMenu::_get_items() const { return items; } -void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) { +void PopupMenu::_ref_shortcut(Ref<Shortcut> p_sc) { if (!shortcut_refcount.has(p_sc)) { shortcut_refcount[p_sc] = 1; p_sc->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); @@ -1218,7 +1218,7 @@ void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) { } } -void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) { +void PopupMenu::_unref_shortcut(Ref<Shortcut> p_sc) { ERR_FAIL_COND(!shortcut_refcount.has(p_sc)); shortcut_refcount[p_sc]--; if (shortcut_refcount[p_sc] == 0) { diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 45a3336747..9535fd07d7 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -61,7 +61,7 @@ class PopupMenu : public Popup { int _ofs_cache; int _height_cache; int h_ofs; - Ref<ShortCut> shortcut; + Ref<Shortcut> shortcut; bool shortcut_is_global; bool shortcut_is_disabled; @@ -114,10 +114,10 @@ class PopupMenu : public Popup { Array _get_items() const; void _set_items(const Array &p_items); - Map<Ref<ShortCut>, int> shortcut_refcount; + Map<Ref<Shortcut>, int> shortcut_refcount; - void _ref_shortcut(Ref<ShortCut> p_sc); - void _unref_shortcut(Ref<ShortCut> p_sc); + void _ref_shortcut(Ref<Shortcut> p_sc); + void _unref_shortcut(Ref<Shortcut> p_sc); bool allow_search; uint64_t search_time_msec; @@ -145,12 +145,12 @@ public: void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, uint32_t p_accel = 0); - void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false); void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1); @@ -166,7 +166,7 @@ public: void set_item_as_checkable(int p_idx, bool p_checkable); void set_item_as_radio_checkable(int p_idx, bool p_radio_checkable); void set_item_tooltip(int p_idx, const String &p_tooltip); - void set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global = false); + void set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global = false); void set_item_h_offset(int p_idx, int p_offset); void set_item_multistate(int p_idx, int p_state); void toggle_item_multistate(int p_idx); @@ -189,7 +189,7 @@ public: bool is_item_radio_checkable(int p_idx) const; bool is_item_shortcut_disabled(int p_idx) const; String get_item_tooltip(int p_idx) const; - Ref<ShortCut> get_item_shortcut(int p_idx) const; + Ref<Shortcut> get_item_shortcut(int p_idx) const; int get_item_state(int p_idx) const; int get_current_index() const; diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp index 9f5b9c40c2..f8c7bc44a7 100644 --- a/scene/gui/shortcut.cpp +++ b/scene/gui/shortcut.cpp @@ -32,20 +32,20 @@ #include "core/os/keyboard.h" -void ShortCut::set_shortcut(const Ref<InputEvent> &p_shortcut) { +void Shortcut::set_shortcut(const Ref<InputEvent> &p_shortcut) { shortcut = p_shortcut; emit_changed(); } -Ref<InputEvent> ShortCut::get_shortcut() const { +Ref<InputEvent> Shortcut::get_shortcut() const { return shortcut; } -bool ShortCut::is_shortcut(const Ref<InputEvent> &p_event) const { +bool Shortcut::is_shortcut(const Ref<InputEvent> &p_event) const { return shortcut.is_valid() && shortcut->shortcut_match(p_event); } -String ShortCut::get_as_text() const { +String Shortcut::get_as_text() const { if (shortcut.is_valid()) { return shortcut->as_text(); } else { @@ -53,21 +53,21 @@ String ShortCut::get_as_text() const { } } -bool ShortCut::is_valid() const { +bool Shortcut::is_valid() const { return shortcut.is_valid(); } -void ShortCut::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &ShortCut::set_shortcut); - ClassDB::bind_method(D_METHOD("get_shortcut"), &ShortCut::get_shortcut); +void Shortcut::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &Shortcut::set_shortcut); + ClassDB::bind_method(D_METHOD("get_shortcut"), &Shortcut::get_shortcut); - ClassDB::bind_method(D_METHOD("is_valid"), &ShortCut::is_valid); + ClassDB::bind_method(D_METHOD("is_valid"), &Shortcut::is_valid); - ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &ShortCut::is_shortcut); - ClassDB::bind_method(D_METHOD("get_as_text"), &ShortCut::get_as_text); + ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &Shortcut::is_shortcut); + ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_shortcut", "get_shortcut"); } -ShortCut::ShortCut() { +Shortcut::Shortcut() { } diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h index 063d4e43dc..0d7809e5cf 100644 --- a/scene/gui/shortcut.h +++ b/scene/gui/shortcut.h @@ -34,8 +34,8 @@ #include "core/input/input_event.h" #include "core/resource.h" -class ShortCut : public Resource { - GDCLASS(ShortCut, Resource); +class Shortcut : public Resource { + GDCLASS(Shortcut, Resource); Ref<InputEvent> shortcut; @@ -50,7 +50,7 @@ public: String get_as_text() const; - ShortCut(); + Shortcut(); }; #endif // SHORTCUT_H diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 8f71aa7cab..d47f771d1d 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -388,6 +388,7 @@ void Tabs::set_current_tab(int p_current) { } ERR_FAIL_INDEX(p_current, get_tab_count()); + previous = current; current = p_current; _change_notify("current_tab"); @@ -401,6 +402,10 @@ int Tabs::get_current_tab() const { return current; } +int Tabs::get_previous_tab() const { + return previous; +} + int Tabs::get_hovered_tab() const { return hover; } @@ -588,6 +593,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { void Tabs::clear_tabs() { tabs.clear(); current = 0; + previous = 0; call_deferred("_update_hover"); update(); } @@ -605,6 +611,7 @@ void Tabs::remove_tab(int p_idx) { if (current < 0) { current = 0; + previous = 0; } if (current >= tabs.size()) { current = tabs.size() - 1; @@ -917,6 +924,7 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count); ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab); ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab); + ClassDB::bind_method(D_METHOD("get_previous_tab"), &Tabs::get_previous_tab); ClassDB::bind_method(D_METHOD("set_tab_title", "tab_idx", "title"), &Tabs::set_tab_title); ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &Tabs::get_tab_title); ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &Tabs::set_tab_icon); @@ -970,6 +978,7 @@ void Tabs::_bind_methods() { Tabs::Tabs() { current = 0; + previous = 0; tab_align = ALIGN_CENTER; rb_hover = -1; rb_pressing = false; diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 8d7f1aa37d..b94c4a37a1 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -77,6 +77,7 @@ private: bool missing_right; Vector<Tab> tabs; int current; + int previous; int _get_top_margin() const; TabAlign tab_align; int rb_hover; @@ -138,6 +139,7 @@ public: int get_tab_count() const; void set_current_tab(int p_current); int get_current_tab() const; + int get_previous_tab() const; int get_hovered_tab() const; int get_tab_offset() const; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 5057f84192..f6636cf392 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2403,11 +2403,16 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { cache.hover_cell = col; if (it != old_it || col != old_col) { - // Only need to update if mouse enters/exits a button - bool was_over_button = old_it && old_it->cells[old_col].custom_button; - bool is_over_button = it && it->cells[col].custom_button; - if (was_over_button || is_over_button) { + if (old_it && old_col >= old_it->cells.size()) { + // Columns may have changed since last update(). update(); + } else { + // Only need to update if mouse enters/exits a button + bool was_over_button = old_it && old_it->cells[old_col].custom_button; + bool is_over_button = it && it->cells[col].custom_button; + if (was_over_button || is_over_button) { + update(); + } } } } diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 82ee4dde50..2b506b686b 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "http_request.h" +#include "core/io/compression.h" +#include "core/ustring.h" void HTTPRequest::_redirect_request(const String &p_new_url) { } @@ -82,7 +84,51 @@ Error HTTPRequest::_parse_url(const String &p_url) { return OK; } +bool HTTPRequest::has_header(const PackedStringArray &p_headers, const String &p_header_name) { + bool exists = false; + + String lower_case_header_name = p_header_name.to_lower(); + for (int i = 0; i < p_headers.size() && !exists; i++) { + String sanitized = p_headers[i].strip_edges().to_lower(); + if (sanitized.begins_with(lower_case_header_name)) { + exists = true; + } + } + + return exists; +} + +String HTTPRequest::get_header_value(const PackedStringArray &p_headers, const String &p_header_name) { + String value = ""; + + String lowwer_case_header_name = p_header_name.to_lower(); + for (int i = 0; i < p_headers.size(); i++) { + if (p_headers[i].find(":", 0) >= 0) { + Vector<String> parts = p_headers[i].split(":", false, 1); + if (parts[0].strip_edges().to_lower() == lowwer_case_header_name) { + value = parts[1].strip_edges(); + break; + } + } + } + + return value; +} + Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const String &p_request_data) { + // Copy the string into a raw buffer + Vector<uint8_t> raw_data; + + CharString charstr = p_request_data.utf8(); + size_t len = charstr.length(); + raw_data.resize(len); + uint8_t *w = raw_data.ptrw(); + copymem(w, charstr.ptr(), len); + + return request_raw(p_url, p_custom_headers, p_ssl_validate_domain, p_method, raw_data); +} + +Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const Vector<uint8_t> &p_request_data_raw) { ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED); ERR_FAIL_COND_V_MSG(requesting, ERR_BUSY, "HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one."); @@ -102,7 +148,14 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h headers = p_custom_headers; - request_data = p_request_data; + if (accept_gzip) { + // If the user has specified a different Accept-Encoding, don't overwrite it + if (!has_header(headers, "Accept-Encoding")) { + headers.push_back("Accept-Encoding: gzip, deflate"); + } + } + + request_data = p_request_data_raw; requesting = true; @@ -288,7 +341,7 @@ bool HTTPRequest::_update_connection() { } else { // Did not request yet, do request - Error err = client->request(method, request_string, headers, request_data); + Error err = client->request_raw(method, request_string, headers, request_data); if (err != OK) { call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; @@ -382,9 +435,47 @@ bool HTTPRequest::_update_connection() { ERR_FAIL_V(false); } -void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) { +void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data) { cancel_request(); - emit_signal("request_completed", p_status, p_code, headers, p_data); + + // Determine if the request body is compressed + bool is_compressed; + String content_encoding = get_header_value(p_headers, "Content-Encoding").to_lower(); + Compression::Mode mode; + if (content_encoding == "gzip") { + mode = Compression::Mode::MODE_GZIP; + is_compressed = true; + } else if (content_encoding == "deflate") { + mode = Compression::Mode::MODE_DEFLATE; + is_compressed = true; + } else { + is_compressed = false; + } + + const PackedByteArray *data = NULL; + + if (accept_gzip && is_compressed && p_data.size() > 0) { + // Decompress request body + PackedByteArray *decompressed = memnew(PackedByteArray); + int result = Compression::decompress_dynamic(decompressed, body_size_limit, p_data.ptr(), p_data.size(), mode); + if (result == OK) { + data = decompressed; + } else if (result == -5) { + WARN_PRINT("Decompressed size of HTTP response body exceeded body_size_limit"); + p_status = RESULT_BODY_SIZE_LIMIT_EXCEEDED; + // Just return the raw data if we failed to decompress it + data = &p_data; + } else { + WARN_PRINT("Failed to decompress HTTP response body"); + p_status = RESULT_BODY_DECOMPRESS_FAILED; + // Just return the raw data if we failed to decompress it + data = &p_data; + } + } else { + data = &p_data; + } + + emit_signal("request_completed", p_status, p_code, p_headers, *data); } void HTTPRequest::_notification(int p_what) { @@ -415,6 +506,14 @@ bool HTTPRequest::is_using_threads() const { return use_threads; } +void HTTPRequest::set_accept_gzip(bool p_gzip) { + accept_gzip = p_gzip; +} + +bool HTTPRequest::is_accepting_gzip() const { + return accept_gzip; +} + void HTTPRequest::set_body_size_limit(int p_bytes) { ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED); @@ -481,6 +580,7 @@ void HTTPRequest::_timeout() { void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("request_raw", "url", "custom_headers", "ssl_validate_domain", "method", "request_data_raw"), &HTTPRequest::request_raw, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(PackedByteArray())); ClassDB::bind_method(D_METHOD("cancel_request"), &HTTPRequest::cancel_request); ClassDB::bind_method(D_METHOD("get_http_client_status"), &HTTPRequest::get_http_client_status); @@ -488,6 +588,9 @@ void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_threads", "enable"), &HTTPRequest::set_use_threads); ClassDB::bind_method(D_METHOD("is_using_threads"), &HTTPRequest::is_using_threads); + ClassDB::bind_method(D_METHOD("set_accept_gzip", "enable"), &HTTPRequest::set_accept_gzip); + ClassDB::bind_method(D_METHOD("is_accepting_gzip"), &HTTPRequest::is_accepting_gzip); + ClassDB::bind_method(D_METHOD("set_body_size_limit", "bytes"), &HTTPRequest::set_body_size_limit); ClassDB::bind_method(D_METHOD("get_body_size_limit"), &HTTPRequest::get_body_size_limit); @@ -512,6 +615,7 @@ void HTTPRequest::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file"); ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216"), "set_download_chunk_size", "get_download_chunk_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accept_gzip"), "set_accept_gzip", "is_accepting_gzip"); ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000"), "set_body_size_limit", "get_body_size_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects"); ADD_PROPERTY(PropertyInfo(Variant::INT, "timeout", PROPERTY_HINT_RANGE, "0,86400"), "set_timeout", "get_timeout"); @@ -544,6 +648,7 @@ HTTPRequest::HTTPRequest() { got_response = false; validate_ssl = false; use_ssl = false; + accept_gzip = true; response_code = 0; request_sent = false; requesting = false; diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 1409965d45..2e8931120b 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -50,6 +50,7 @@ public: RESULT_SSL_HANDSHAKE_ERROR, RESULT_NO_RESPONSE, RESULT_BODY_SIZE_LIMIT_EXCEEDED, + RESULT_BODY_DECOMPRESS_FAILED, RESULT_REQUEST_FAILED, RESULT_DOWNLOAD_FILE_CANT_OPEN, RESULT_DOWNLOAD_FILE_WRITE_ERROR, @@ -68,12 +69,13 @@ private: bool validate_ssl; bool use_ssl; HTTPClient::Method method; - String request_data; + Vector<uint8_t> request_data; bool request_sent; Ref<HTTPClient> client; PackedByteArray body; volatile bool use_threads; + bool accept_gzip; bool got_response; int response_code; @@ -102,12 +104,15 @@ private: Error _parse_url(const String &p_url); Error _request(); + bool has_header(const PackedStringArray &p_headers, const String &p_header_name); + String get_header_value(const PackedStringArray &p_headers, const String &header_name); + volatile bool thread_done; volatile bool thread_request_quit; Thread *thread; - void _request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); + void _request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data); static void _thread_func(void *p_userdata); protected: @@ -116,12 +121,16 @@ protected: public: Error request(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const String &p_request_data = ""); //connects to a full url and perform request + Error request_raw(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const Vector<uint8_t> &p_request_data_raw = Vector<uint8_t>()); //connects to a full url and perform request void cancel_request(); HTTPClient::Status get_http_client_status() const; void set_use_threads(bool p_use); bool is_using_threads() const; + void set_accept_gzip(bool p_gzip); + bool is_accepting_gzip() const; + void set_download_file(const String &p_file); String get_download_file() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 0f6475cf0d..6069d6c808 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -230,6 +230,7 @@ static Ref<ResourceFormatLoaderDynamicFont> resource_loader_dynamic_font; static Ref<ResourceFormatLoaderStreamTexture2D> resource_loader_stream_texture; static Ref<ResourceFormatLoaderStreamTextureLayered> resource_loader_texture_layered; +static Ref<ResourceFormatLoaderStreamTexture3D> resource_loader_texture_3d; static Ref<ResourceFormatLoaderBMFont> resource_loader_bmfont; @@ -252,6 +253,9 @@ void register_scene_types() { resource_loader_texture_layered.instance(); ResourceLoader::add_resource_format_loader(resource_loader_texture_layered); + resource_loader_texture_3d.instance(); + ResourceLoader::add_resource_format_loader(resource_loader_texture_3d); + resource_saver_text.instance(); ResourceSaver::add_resource_format_saver(resource_saver_text, true); @@ -291,7 +295,7 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init - ClassDB::register_class<ShortCut>(); + ClassDB::register_class<Shortcut>(); ClassDB::register_class<Control>(); ClassDB::register_class<Button>(); ClassDB::register_class<Label>(); @@ -549,6 +553,7 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeTexture>(); ClassDB::register_virtual_class<VisualShaderNodeSample3D>(); ClassDB::register_class<VisualShaderNodeTexture2DArray>(); + ClassDB::register_class<VisualShaderNodeTexture3D>(); ClassDB::register_class<VisualShaderNodeCubemap>(); ClassDB::register_virtual_class<VisualShaderNodeUniform>(); ClassDB::register_class<VisualShaderNodeUniformRef>(); @@ -561,6 +566,7 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeTextureUniform>(); ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>(); ClassDB::register_class<VisualShaderNodeTexture2DArrayUniform>(); + ClassDB::register_class<VisualShaderNodeTexture3DUniform>(); ClassDB::register_class<VisualShaderNodeCubemapUniform>(); ClassDB::register_class<VisualShaderNodeIf>(); ClassDB::register_class<VisualShaderNodeSwitch>(); @@ -701,6 +707,9 @@ void register_scene_types() { ClassDB::register_class<CameraTexture>(); ClassDB::register_virtual_class<TextureLayered>(); ClassDB::register_virtual_class<ImageTextureLayered>(); + ClassDB::register_virtual_class<Texture3D>(); + ClassDB::register_class<ImageTexture3D>(); + ClassDB::register_class<StreamTexture3D>(); ClassDB::register_class<Cubemap>(); ClassDB::register_class<CubemapArray>(); ClassDB::register_class<Texture2DArray>(); @@ -864,6 +873,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("RemoteTransform", "RemoteTransform3D"); ClassDB::add_compatibility_class("RigidBody", "RigidBody3D"); ClassDB::add_compatibility_class("Shape", "Shape3D"); + ClassDB::add_compatibility_class("ShortCut", "Shortcut"); ClassDB::add_compatibility_class("Skeleton", "Skeleton3D"); ClassDB::add_compatibility_class("SkeletonIK", "SkeletonIK3D"); ClassDB::add_compatibility_class("SliderJoint", "SliderJoint3D"); @@ -946,6 +956,9 @@ void unregister_scene_types() { ResourceLoader::remove_resource_format_loader(resource_loader_texture_layered); resource_loader_texture_layered.unref(); + ResourceLoader::remove_resource_format_loader(resource_loader_texture_3d); + resource_loader_texture_3d.unref(); + ResourceLoader::remove_resource_format_loader(resource_loader_stream_texture); resource_loader_stream_texture.unref(); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index fd1fa1b48f..b0a30a5627 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -209,7 +209,6 @@ public: void surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data); int get_surface_count() const override; - void surface_remove(int p_idx); void clear_surfaces(); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 7b78398669..450e2c16e3 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GRID_THEME_H -#define GRID_THEME_H +#ifndef MESH_LIBRARY_H +#define MESH_LIBRARY_H #include "core/map.h" #include "core/resource.h" @@ -96,4 +96,4 @@ public: ~MeshLibrary(); }; -#endif // CUBE_GRID_THEME_H +#endif // MESH_LIBRARY_H diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 5681613c04..39237e1a33 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -791,8 +791,312 @@ String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_pa return ""; } +//////////////////////////////////// + +TypedArray<Image> Texture3D::_get_data() const { + Vector<Ref<Image>> data = get_data(); + + TypedArray<Image> ret; + ret.resize(data.size()); + for (int i = 0; i < data.size(); i++) { + ret[i] = data[i]; + } + return ret; +} + +void Texture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format); + ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width); + ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height); + ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth); + ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps); + ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_data); +} ////////////////////////////////////////// +Image::Format ImageTexture3D::get_format() const { + return format; +} +int ImageTexture3D::get_width() const { + return width; +} +int ImageTexture3D::get_height() const { + return height; +} +int ImageTexture3D::get_depth() const { + return depth; +} +bool ImageTexture3D::has_mipmaps() const { + return mipmaps; +} + +Error ImageTexture3D::_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data) { + Vector<Ref<Image>> images; + images.resize(p_data.size()); + for (int i = 0; i < images.size(); i++) { + images.write[i] = p_data[i]; + } + return create(p_format, p_width, p_height, p_depth, p_mipmaps, images); +} + +void ImageTexture3D::_update(const TypedArray<Image> &p_data) { + Vector<Ref<Image>> images; + images.resize(p_data.size()); + for (int i = 0; i < images.size(); i++) { + images.write[i] = p_data[i]; + } + return update(images); +} + +Error ImageTexture3D::create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { + RID tex = RenderingServer::get_singleton()->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); + ERR_FAIL_COND_V(tex.is_null(), ERR_CANT_CREATE); + + if (texture.is_valid()) { + RenderingServer::get_singleton()->texture_replace(texture, tex); + } + + return OK; +} + +void ImageTexture3D::update(const Vector<Ref<Image>> &p_data) { + ERR_FAIL_COND(!texture.is_valid()); + RenderingServer::get_singleton()->texture_3d_update(texture, p_data); +} + +Vector<Ref<Image>> ImageTexture3D::get_data() const { + ERR_FAIL_COND_V(!texture.is_valid(), Vector<Ref<Image>>()); + return RS::get_singleton()->texture_3d_get(texture); +} + +RID ImageTexture3D::get_rid() const { + if (!texture.is_valid()) { + texture = RS::get_singleton()->texture_3d_placeholder_create(); + } + return texture; +} +void ImageTexture3D::set_path(const String &p_path, bool p_take_over) { + if (texture.is_valid()) { + RenderingServer::get_singleton()->texture_set_path(texture, p_path); + } + + Resource::set_path(p_path, p_take_over); +} + +void ImageTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("create", "format", "width", "height", "depth", "use_mipmaps", "data"), &ImageTexture3D::_create); + ClassDB::bind_method(D_METHOD("update", "data"), &ImageTexture3D::_update); +} + +ImageTexture3D::ImageTexture3D() { +} + +ImageTexture3D::~ImageTexture3D() { + if (texture.is_valid()) { + RS::get_singleton()->free(texture); + } +} + +//////////////////////////////////////////// + +void StreamTexture3D::set_path(const String &p_path, bool p_take_over) { + if (texture.is_valid()) { + RenderingServer::get_singleton()->texture_set_path(texture, p_path); + } + + Resource::set_path(p_path, p_take_over); +} + +Image::Format StreamTexture3D::get_format() const { + return format; +} + +Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) { + FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + + uint8_t header[4]; + f->get_buffer(header, 4); + ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED); + + //stored as stream textures (used for lossless and lossy compression) + uint32_t version = f->get_32(); + + if (version > FORMAT_VERSION) { + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); + } + + r_depth = f->get_32(); //depth + f->get_32(); //ignored (mode) + f->get_32(); // ignored (data format) + + f->get_32(); //ignored + int mipmaps = f->get_32(); + f->get_32(); //ignored + f->get_32(); //ignored + + r_mipmaps = mipmaps != 0; + + r_data.clear(); + + for (int i = 0; i < (r_depth + mipmaps); i++) { + Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0); + ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN); + if (i == 0) { + r_format = image->get_format(); + r_width = image->get_width(); + r_height = image->get_height(); + } + r_data.push_back(image); + } + + return OK; +} + +Error StreamTexture3D::load(const String &p_path) { + Vector<Ref<Image>> data; + + int tw, th, td; + Image::Format tfmt; + bool tmm; + + Error err = _load_data(p_path, data, tfmt, tw, th, td, tmm); + if (err) { + return err; + } + + if (texture.is_valid()) { + RID new_texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data); + RS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data); + } + + w = tw; + h = th; + d = td; + mipmaps = tmm; + format = tfmt; + + path_to_file = p_path; + + if (get_path() == String()) { + //temporarily set path if no path set for resource, helps find errors + RenderingServer::get_singleton()->texture_set_path(texture, p_path); + } + + _change_notify(); + emit_changed(); + return OK; +} + +String StreamTexture3D::get_load_path() const { + return path_to_file; +} + +int StreamTexture3D::get_width() const { + return w; +} + +int StreamTexture3D::get_height() const { + return h; +} + +int StreamTexture3D::get_depth() const { + return d; +} + +bool StreamTexture3D::has_mipmaps() const { + return mipmaps; +} + +RID StreamTexture3D::get_rid() const { + if (!texture.is_valid()) { + texture = RS::get_singleton()->texture_3d_placeholder_create(); + } + return texture; +} + +Vector<Ref<Image>> StreamTexture3D::get_data() const { + if (texture.is_valid()) { + return RS::get_singleton()->texture_3d_get(texture); + } else { + return Vector<Ref<Image>>(); + } +} + +void StreamTexture3D::reload_from_file() { + String path = get_path(); + if (!path.is_resource_file()) { + return; + } + + path = ResourceLoader::path_remap(path); //remap for translation + path = ResourceLoader::import_remap(path); //remap for import + if (!path.is_resource_file()) { + return; + } + + load(path); +} + +void StreamTexture3D::_validate_property(PropertyInfo &property) const { +} + +void StreamTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture3D::load); + ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture3D::get_load_path); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); +} + +StreamTexture3D::StreamTexture3D() { + format = Image::FORMAT_MAX; + w = 0; + h = 0; + d = 0; + mipmaps = false; +} + +StreamTexture3D::~StreamTexture3D() { + if (texture.is_valid()) { + RS::get_singleton()->free(texture); + } +} + +///////////////////////////// + +RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { + Ref<StreamTexture3D> st; + st.instance(); + Error err = st->load(p_path); + if (r_error) { + *r_error = err; + } + if (err != OK) { + return RES(); + } + + return st; +} + +void ResourceFormatLoaderStreamTexture3D::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("stex3d"); +} + +bool ResourceFormatLoaderStreamTexture3D::handles_type(const String &p_type) const { + return p_type == "StreamTexture3D"; +} + +String ResourceFormatLoaderStreamTexture3D::get_resource_type(const String &p_path) const { + if (p_path.get_extension().to_lower() == "stex3d") { + return "StreamTexture3D"; + } + return ""; +} + +//////////////////////////////////////////// + int AtlasTexture::get_width() const { if (region.size.width == 0) { if (atlas.is_valid()) { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index fd213859b7..eebbf4f233 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -515,6 +515,122 @@ public: virtual String get_resource_type(const String &p_path) const; }; +class Texture3D : public Texture { + GDCLASS(Texture3D, Texture); + +protected: + static void _bind_methods(); + + TypedArray<Image> _get_data() const; + +public: + virtual Image::Format get_format() const = 0; + virtual int get_width() const = 0; + virtual int get_height() const = 0; + virtual int get_depth() const = 0; + virtual bool has_mipmaps() const = 0; + virtual Vector<Ref<Image>> get_data() const = 0; +}; + +class ImageTexture3D : public Texture3D { + GDCLASS(ImageTexture3D, Texture3D); + + mutable RID texture; + + Image::Format format = Image::FORMAT_MAX; + int width = 1; + int height = 1; + int depth = 1; + bool mipmaps = false; + +protected: + static void _bind_methods(); + + Error _create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data); + void _update(const TypedArray<Image> &p_data); + +public: + virtual Image::Format get_format() const override; + virtual int get_width() const override; + virtual int get_height() const override; + virtual int get_depth() const override; + virtual bool has_mipmaps() const override; + + Error create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); + void update(const Vector<Ref<Image>> &p_data); + virtual Vector<Ref<Image>> get_data() const override; + + virtual RID get_rid() const override; + virtual void set_path(const String &p_path, bool p_take_over = false) override; + + ImageTexture3D(); + ~ImageTexture3D(); +}; + +class StreamTexture3D : public Texture3D { + GDCLASS(StreamTexture3D, Texture3D); + +public: + enum DataFormat { + DATA_FORMAT_IMAGE, + DATA_FORMAT_LOSSLESS, + DATA_FORMAT_LOSSY, + DATA_FORMAT_BASIS_UNIVERSAL, + }; + + enum { + FORMAT_VERSION = 1 + }; + + enum FormatBits { + FORMAT_MASK_IMAGE_FORMAT = (1 << 20) - 1, + FORMAT_BIT_LOSSLESS = 1 << 20, + FORMAT_BIT_LOSSY = 1 << 21, + FORMAT_BIT_STREAM = 1 << 22, + FORMAT_BIT_HAS_MIPMAPS = 1 << 23, + }; + +private: + Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps); + String path_to_file; + mutable RID texture; + Image::Format format; + int w, h, d; + bool mipmaps; + + virtual void reload_from_file() override; + +protected: + static void _bind_methods(); + void _validate_property(PropertyInfo &property) const override; + +public: + Image::Format get_format() const override; + Error load(const String &p_path); + String get_load_path() const; + + int get_width() const override; + int get_height() const override; + int get_depth() const override; + virtual bool has_mipmaps() const override; + virtual RID get_rid() const override; + + virtual void set_path(const String &p_path, bool p_take_over) override; + + virtual Vector<Ref<Image>> get_data() const override; + + StreamTexture3D(); + ~StreamTexture3D(); +}; + +class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader { +public: + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; +}; + class CurveTexture : public Texture2D { GDCLASS(CurveTexture, Texture2D); RES_BASE_EXTENSION("curvetex") diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 1d5e4124d2..4ee9b22b25 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -40,6 +40,7 @@ bool VisualShaderNode::is_simple_decl() const { void VisualShaderNode::set_output_port_for_preview(int p_index) { port_preview = p_index; + emit_signal("show_port_preview", p_index); } int VisualShaderNode::get_output_port_for_preview() const { @@ -161,6 +162,7 @@ void VisualShaderNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_default_input_values", "get_default_input_values"); ADD_SIGNAL(MethodInfo("editor_refresh_request")); + ADD_SIGNAL(MethodInfo("show_port_preview", PropertyInfo(Variant::INT, "port_id"))); BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR); BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT); @@ -172,8 +174,6 @@ void VisualShaderNode::_bind_methods() { } VisualShaderNode::VisualShaderNode() { - port_preview = -1; - simple_decl = true; } ///////////////////////////////////////////////////////// @@ -319,6 +319,21 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() { ///////////////////////////////////////////////////////// +void VisualShader::set_graph_node(Type p_type, int p_id, GraphNode *p_graph_node) { + ERR_FAIL_INDEX(p_type, TYPE_MAX); + Graph *g = &graph[p_type]; + ERR_FAIL_COND(!g->nodes.has(p_id)); + g->nodes[p_id].graph_node = p_graph_node; +} + +void VisualShader::set_shader_type(Type p_type) { + current_type = p_type; +} + +VisualShader::Type VisualShader::get_shader_type() const { + return current_type; +} + void VisualShader::set_version(const String &p_version) { version = p_version; } @@ -402,6 +417,11 @@ void VisualShader::set_node_position(Type p_type, int p_id, const Vector2 &p_pos Graph *g = &graph[p_type]; ERR_FAIL_COND(!g->nodes.has(p_id)); g->nodes[p_id].position = p_position; + if (current_type == p_type) { + if (g->nodes[p_id].graph_node != nullptr) { + g->nodes[p_id].graph_node->set_offset(p_position); + } + } } Vector2 VisualShader::get_node_position(Type p_type, int p_id) const { @@ -921,8 +941,11 @@ static const char *type_string[VisualShader::TYPE_MAX] = { "vertex", "fragment", "light", - "compute" + "emit", + "process", + "end" }; + bool VisualShader::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name == "mode") { @@ -1345,6 +1368,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui return OK; } +bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const { + if (!ShaderTypes::get_singleton()->get_functions(p_mode).has(p_func_name)) { + if (p_mode == RenderingServer::ShaderMode::SHADER_PARTICLES) { + if (p_func_name == "emit" || p_func_name == "process" || p_func_name == "end") { + return true; + } + } + return false; + } + + return true; +} + void VisualShader::_update_shader() const { if (!dirty) { return; @@ -1416,14 +1452,14 @@ void VisualShader::_update_shader() const { global_code += "render_mode " + render_mode + ";\n\n"; } - static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "compute" }; + static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "emit", "process", "end" }; String global_expressions; Set<String> used_uniform_names; List<VisualShaderNodeUniform *> uniforms; for (int i = 0, index = 0; i < TYPE_MAX; i++) { - if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) { + if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { continue; } @@ -1458,8 +1494,10 @@ void VisualShader::_update_shader() const { } } + Map<int, String> code_map; + for (int i = 0; i < TYPE_MAX; i++) { - if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) { + if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { continue; } @@ -1467,6 +1505,8 @@ void VisualShader::_update_shader() const { VMap<ConnectionKey, const List<Connection>::Element *> input_connections; VMap<ConnectionKey, const List<Connection>::Element *> output_connections; + StringBuilder func_code; + for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) { ConnectionKey from_key; from_key.node = E->get().from_node; @@ -1480,14 +1520,30 @@ void VisualShader::_update_shader() const { input_connections.insert(to_key, E); } - - code += "\nvoid " + String(func_name[i]) + "() {\n"; + if (shader_mode != Shader::MODE_PARTICLES) { + func_code += "\nvoid " + String(func_name[i]) + "() {\n"; + } Set<int> processed; - Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); + Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); ERR_FAIL_COND(err != OK); insertion_pos.insert(i, code.get_string_length()); + if (shader_mode == Shader::MODE_PARTICLES) { + code_map.insert(i, func_code); + } else { + func_code += "}\n"; + code += func_code; + } + } + + if (shader_mode == Shader::MODE_PARTICLES) { + code += "\nvoid compute() {\n"; + code += "\tif (RESTART) {\n"; + code += code_map[TYPE_EMIT]; + code += "\t} else {\n"; + code += code_map[TYPE_PROCESS]; + code += "\t}\n"; code += "}\n"; } @@ -1498,7 +1554,7 @@ void VisualShader::_update_shader() const { final_code += global_expressions; String tcode = code; for (int i = 0; i < TYPE_MAX; i++) { - if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) { + if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { continue; } tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]); @@ -1582,7 +1638,6 @@ void VisualShader::_bind_methods() { BIND_ENUM_CONSTANT(TYPE_VERTEX); BIND_ENUM_CONSTANT(TYPE_FRAGMENT); BIND_ENUM_CONSTANT(TYPE_LIGHT); - BIND_ENUM_CONSTANT(TYPE_COMPUTE); BIND_ENUM_CONSTANT(TYPE_MAX); BIND_CONSTANT(NODE_ID_INVALID); @@ -1720,20 +1775,50 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, - // Particles, Compute - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + // Particles, Emit + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles, Process + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles, End + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Sky, Fragment { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_cubemap_pass", "AT_CUBEMAP_PASS" }, @@ -2284,13 +2369,30 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" }, - // Particles, Compute - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_COMPUTE, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + // Particles, Emit + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + // Particles, Process + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + // Particles, End + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, // Sky, Fragment { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR" }, { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" }, @@ -2951,6 +3053,7 @@ String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShade } VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() { + simple_decl = false; } ////////////// Expression diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index c51f09ba36..2b9115879e 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -33,6 +33,7 @@ #include "core/string_builder.h" #include "scene/gui/control.h" +#include "scene/gui/graph_edit.h" #include "scene/resources/shader.h" class VisualShaderNodeUniform; @@ -50,7 +51,9 @@ public: TYPE_VERTEX, TYPE_FRAGMENT, TYPE_LIGHT, - TYPE_COMPUTE, + TYPE_EMIT, + TYPE_PROCESS, + TYPE_END, TYPE_MAX }; @@ -67,10 +70,13 @@ public: }; private: + Type current_type; + struct Node { Ref<VisualShaderNode> node; Vector2 position; List<int> prev_connected_nodes; + GraphNode *graph_node; }; struct Graph { @@ -112,6 +118,7 @@ private: Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const; void _input_type_changed(Type p_type, int p_id); + bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const; protected: virtual void _update_shader() const override; @@ -121,6 +128,11 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; +public: // internal methods + void set_graph_node(Type p_type, int p_id, GraphNode *p_graph_node); + void set_shader_type(Type p_type); + Type get_shader_type() const; + public: void set_version(const String &p_version); String get_version() const; @@ -180,7 +192,7 @@ VARIANT_ENUM_CAST(VisualShader::Type) class VisualShaderNode : public Resource { GDCLASS(VisualShaderNode, Resource); - int port_preview; + int port_preview = -1; Map<int, Variant> default_input_values; Map<int, bool> connected_input_ports; @@ -188,7 +200,7 @@ class VisualShaderNode : public Resource { int connected_output_count = 0; protected: - bool simple_decl = false; + bool simple_decl = true; static void _bind_methods(); public: diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 5c63201991..dfc915c5b4 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -892,6 +892,7 @@ String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader:: } VisualShaderNodeSample3D::VisualShaderNodeSample3D() { + simple_decl = false; } ////////////// Texture2DArray @@ -950,6 +951,64 @@ void VisualShaderNodeTexture2DArray::_bind_methods() { VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() { } + +////////////// Texture3D + +String VisualShaderNodeTexture3D::get_caption() const { + return "Texture3D"; +} + +String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const { + if (p_port == 2) { + return "sampler3D"; + } + return VisualShaderNodeSample3D::get_input_port_name(p_port); +} + +Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { + VisualShader::DefaultTextureParam dtp; + dtp.name = make_unique_id(p_type, p_id, "tex3d"); + dtp.param = texture; + Vector<VisualShader::DefaultTextureParam> ret; + ret.push_back(dtp); + return ret; +} + +String VisualShaderNodeTexture3D::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + if (source == SOURCE_TEXTURE) { + return "uniform sampler3D " + make_unique_id(p_type, p_id, "tex3d") + ";\n"; + } + return String(); +} + +void VisualShaderNodeTexture3D::set_texture(Ref<Texture3D> p_value) { + texture = p_value; + emit_changed(); +} + +Ref<Texture3D> VisualShaderNodeTexture3D::get_texture() const { + return texture; +} + +Vector<StringName> VisualShaderNodeTexture3D::get_editable_properties() const { + Vector<StringName> props; + props.push_back("source"); + if (source == SOURCE_TEXTURE) { + props.push_back("texture"); + } + return props; +} + +void VisualShaderNodeTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture3D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture3D::get_texture); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture"); +} + +VisualShaderNodeTexture3D::VisualShaderNodeTexture3D() { +} + ////////////// Cubemap String VisualShaderNodeCubemap::get_caption() const { @@ -1135,6 +1194,7 @@ void VisualShaderNodeCubemap::_bind_methods() { } VisualShaderNodeCubemap::VisualShaderNodeCubemap() { + simple_decl = false; } ////////////// Float Op @@ -2236,6 +2296,7 @@ void VisualShaderNodeColorFunc::_bind_methods() { } VisualShaderNodeColorFunc::VisualShaderNodeColorFunc() { + simple_decl = false; set_input_port_default_value(0, Vector3()); } @@ -4226,6 +4287,7 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co } VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { + simple_decl = false; } ////////////// Texture Uniform (Triplanar) @@ -4393,6 +4455,74 @@ String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode, VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() { } +////////////// Texture3D Uniform + +String VisualShaderNodeTexture3DUniform::get_caption() const { + return "Texture3DUniform"; +} + +int VisualShaderNodeTexture3DUniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_output_port_type(int p_port) const { + return PORT_TYPE_SAMPLER; +} + +String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const { + return "sampler3D"; +} + +int VisualShaderNodeTexture3DUniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTexture3DUniform::get_input_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeTexture3DUniform::get_input_port_default_hint(int p_port) const { + return ""; +} + +String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name(); + + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black;\n"; + else + code += ";\n"; + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black_albedo;\n"; + else + code += " : hint_albedo;\n"; + break; + case TYPE_NORMALMAP: + code += " : hint_normal;\n"; + break; + case TYPE_ANISO: + code += " : hint_aniso;\n"; + break; + } + + return code; +} + +String VisualShaderNodeTexture3DUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return String(); +} + +VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() { +} + ////////////// Cubemap Uniform String VisualShaderNodeCubemapUniform::get_caption() const { @@ -4529,6 +4659,7 @@ String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type } VisualShaderNodeIf::VisualShaderNodeIf() { + simple_decl = false; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, CMP_EPSILON); @@ -4593,6 +4724,7 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader:: } VisualShaderNodeSwitch::VisualShaderNodeSwitch() { + simple_decl = false; set_input_port_default_value(0, false); set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 245435591b..06ad42adf5 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -343,6 +343,29 @@ public: VisualShaderNodeTexture2DArray(); }; +class VisualShaderNodeTexture3D : public VisualShaderNodeSample3D { + GDCLASS(VisualShaderNodeTexture3D, VisualShaderNodeSample3D); + Ref<Texture3D> texture; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual String get_input_port_name(int p_port) const override; + + virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + + void set_texture(Ref<Texture3D> p_value); + Ref<Texture3D> get_texture() const; + + virtual Vector<StringName> get_editable_properties() const override; + + VisualShaderNodeTexture3D(); +}; + class VisualShaderNodeCubemap : public VisualShaderNode { GDCLASS(VisualShaderNodeCubemap, VisualShaderNode); Ref<Cubemap> cube_map; @@ -1855,6 +1878,29 @@ public: /////////////////////////////////////// +class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String get_input_port_default_hint(int p_port) const override; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + VisualShaderNodeTexture3DUniform(); +}; + +/////////////////////////////////////// + class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform { GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform); diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index 989c9e2834..a24189bdd7 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -88,7 +88,7 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; @@ -331,12 +331,12 @@ public: virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) = 0; //all slices, then all the mipmaps, must be coherent + virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; - virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) = 0; + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0; virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; //these two APIs can be used together or in combination with the others. @@ -346,7 +346,7 @@ public: virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; - virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const = 0; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0; virtual void texture_replace(RID p_texture, RID p_by_texture) = 0; virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index eb49233b98..fe31d2f76b 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -1542,7 +1542,7 @@ public: float environment_get_fog_height(RID p_env) const; float environment_get_fog_height_density(RID p_env) const; - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter); + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter); virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth); virtual void environment_set_volumetric_fog_filter_active(bool p_enable); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index d751f474cd..9e3335b05b 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -715,8 +715,120 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) { - return RID(); +RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { + ERR_FAIL_COND_V(p_data.size() == 0, RID()); + Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); + if (verr != Image::VALIDATE_3D_OK) { + ERR_FAIL_V_MSG(RID(), Image::get_3d_image_validation_error_text(verr)); + } + + TextureToRDFormat ret_format; + Image::Format validated_format = Image::FORMAT_MAX; + Vector<uint8_t> all_data; + uint32_t mipmap_count = 0; + Vector<Texture::BufferSlice3D> slices; + { + Vector<Ref<Image>> images; + uint32_t all_data_size = 0; + images.resize(p_data.size()); + for (int i = 0; i < p_data.size(); i++) { + TextureToRDFormat f; + images.write[i] = _validate_texture_format(p_data[i], f); + if (i == 0) { + ret_format = f; + validated_format = images[0]->get_format(); + } + + all_data_size += images[i]->get_data().size(); + } + + all_data.resize(all_data_size); //consolidate all data here + uint32_t offset = 0; + Size2i prev_size; + for (int i = 0; i < p_data.size(); i++) { + uint32_t s = images[i]->get_data().size(); + + copymem(&all_data.write[offset], images[i]->get_data().ptr(), s); + { + Texture::BufferSlice3D slice; + slice.size.width = images[i]->get_width(); + slice.size.height = images[i]->get_height(); + slice.offset = offset; + slice.buffer_size = s; + slices.push_back(slice); + } + offset += s; + + Size2i img_size(images[i]->get_width(), images[i]->get_height()); + if (img_size != prev_size) { + mipmap_count++; + } + prev_size = img_size; + } + } + + Texture texture; + + texture.type = Texture::TYPE_3D; + texture.width = p_width; + texture.height = p_height; + texture.depth = p_depth; + texture.mipmaps = mipmap_count; + texture.format = p_data[0]->get_format(); + texture.validated_format = validated_format; + + texture.buffer_size_3d = all_data.size(); + texture.buffer_slices_3d = slices; + + texture.rd_type = RD::TEXTURE_TYPE_3D; + texture.rd_format = ret_format.format; + texture.rd_format_srgb = ret_format.format_srgb; + + RD::TextureFormat rd_format; + RD::TextureView rd_view; + { //attempt register + rd_format.format = texture.rd_format; + rd_format.width = texture.width; + rd_format.height = texture.height; + rd_format.depth = texture.depth; + rd_format.array_layers = 1; + rd_format.mipmaps = texture.mipmaps; + rd_format.type = texture.rd_type; + rd_format.samples = RD::TEXTURE_SAMPLES_1; + rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_format.shareable_formats.push_back(texture.rd_format); + rd_format.shareable_formats.push_back(texture.rd_format_srgb); + } + } + { + rd_view.swizzle_r = ret_format.swizzle_r; + rd_view.swizzle_g = ret_format.swizzle_g; + rd_view.swizzle_b = ret_format.swizzle_b; + rd_view.swizzle_a = ret_format.swizzle_a; + } + Vector<Vector<uint8_t>> data_slices; + data_slices.push_back(all_data); //one slice + + texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); + ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_view.format_override = texture.rd_format_srgb; + texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); + if (texture.rd_texture_srgb.is_null()) { + RD::get_singleton()->free(texture.rd_texture); + ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + } + } + + //used for 2D, overridable + texture.width_2d = texture.width; + texture.height_2d = texture.height; + texture.is_render_target = false; + texture.rd_view = rd_view; + texture.is_proxy = false; + + return texture_owner.make_rid(texture); } RID RasterizerStorageRD::texture_proxy_create(RID p_base) { @@ -772,7 +884,41 @@ void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_i _texture_2d_update(p_texture, p_image, p_layer, false); } -void RasterizerStorageRD::texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) { +void RasterizerStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { + Texture *tex = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(tex->type != Texture::TYPE_3D); + Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data); + if (verr != Image::VALIDATE_3D_OK) { + ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); + } + + Vector<uint8_t> all_data; + { + Vector<Ref<Image>> images; + uint32_t all_data_size = 0; + images.resize(p_data.size()); + for (int i = 0; i < p_data.size(); i++) { + Ref<Image> image = p_data[i]; + if (image->get_format() != tex->validated_format) { + image = image->duplicate(); + image->convert(tex->validated_format); + } + all_data_size += images[i]->get_data().size(); + images.push_back(image); + } + + all_data.resize(all_data_size); //consolidate all data here + uint32_t offset = 0; + + for (int i = 0; i < p_data.size(); i++) { + uint32_t s = images[i]->get_data().size(); + copymem(&all_data.write[offset], images[i]->get_data().ptr(), s); + offset += s; + } + } + + RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data, true); } void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { @@ -858,7 +1004,25 @@ RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayere } RID RasterizerStorageRD::texture_3d_placeholder_create() { - return RID(); + //this could be better optimized to reuse an existing image , done this way + //for now to get it working + Ref<Image> image; + image.instance(); + image->create(4, 4, false, Image::FORMAT_RGBA8); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + image->set_pixel(i, j, Color(1, 0, 1, 1)); + } + } + + Vector<Ref<Image>> images; + //cube + for (int i = 0; i < 4; i++) { + images.push_back(image); + } + + return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images); } Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { @@ -890,11 +1054,51 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { } Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { - return Ref<Image>(); + Texture *tex = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!tex, Ref<Image>()); + + Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer); + ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); + Ref<Image> image; + image.instance(); + image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); + ERR_FAIL_COND_V(image->empty(), Ref<Image>()); + if (tex->format != tex->validated_format) { + image->convert(tex->format); + } + + return image; } -Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const { - return Ref<Image>(); +Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const { + Texture *tex = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>()); + ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>()); + + Vector<uint8_t> all_data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); + + ERR_FAIL_COND_V(all_data.size() != (int)tex->buffer_size_3d, Vector<Ref<Image>>()); + + Vector<Ref<Image>> ret; + + for (int i = 0; i < tex->buffer_slices_3d.size(); i++) { + const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i]; + ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>()); + ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>()); + Vector<uint8_t> sub_region = all_data.subarray(bs.offset, bs.offset + bs.buffer_size - 1); + + Ref<Image> img; + img.instance(); + img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region); + ERR_FAIL_COND_V(img->empty(), Vector<Ref<Image>>()); + if (tex->format != tex->validated_format) { + img->convert(tex->format); + } + + ret.push_back(img); + } + + return ret; } void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { @@ -6986,15 +7190,18 @@ RasterizerStorageRD::RasterizerStorageRD() { case RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: { sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; + sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; } break; case RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED: { sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_REPEAT; sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_REPEAT; + sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_REPEAT; } break; case RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR: { sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; + sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; } break; default: { } diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h index cecae6bbb2..e14b9528cf 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h @@ -205,6 +205,14 @@ private: int height_2d; int width_2d; + struct BufferSlice3D { + Size2i size; + uint32_t offset = 0; + uint32_t buffer_size = 0; + }; + Vector<BufferSlice3D> buffer_slices_3d; + uint32_t buffer_size_3d = 0; + bool is_render_target; bool is_proxy; @@ -980,14 +988,14 @@ public: virtual RID texture_2d_create(const Ref<Image> &p_image); virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type); - virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices); //all slices, then all the mipmaps, must be coherent + virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent virtual RID texture_proxy_create(RID p_base); virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate); virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); //mostly used for video and streaming virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); - virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap); + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data); virtual void texture_proxy_update(RID p_texture, RID p_proxy_to); //these two APIs can be used together or in combination with the others. @@ -997,7 +1005,7 @@ public: virtual Ref<Image> texture_2d_get(RID p_texture) const; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const; - virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const; virtual void texture_replace(RID p_texture, RID p_by_texture); virtual void texture_set_size_override(RID p_texture, int p_width, int p_height); diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp index 5c0741bb3b..07eabfd430 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/rendering_server_canvas.cpp @@ -900,13 +900,12 @@ void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skelet void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); - if (bool(canvas_item->copy_back_buffer != nullptr) != p_enable) { - if (p_enable) { - canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer); - } else { - memdelete(canvas_item->copy_back_buffer); - canvas_item->copy_back_buffer = nullptr; - } + if (p_enable && (canvas_item->copy_back_buffer == nullptr)) { + canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer); + } + if (!p_enable && (canvas_item->copy_back_buffer != nullptr)) { + memdelete(canvas_item->copy_back_buffer); + canvas_item->copy_back_buffer = nullptr; } if (p_enable) { diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index ceefcfa1fc..b554425bef 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -114,6 +114,14 @@ public: m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } #define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } +#define BIND5R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } +#define BIND5RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } +#define BIND6R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } +#define BIND6RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } #define BIND0(m_name) \ void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); } @@ -160,14 +168,14 @@ public: //these go pass-through, as they can be called from any thread BIND1R(RID, texture_2d_create, const Ref<Image> &) BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image>> &, TextureLayeredType) - BIND1R(RID, texture_3d_create, const Vector<Ref<Image>> &) + BIND6R(RID, texture_3d_create, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &) BIND1R(RID, texture_proxy_create, RID) //goes pass-through BIND3(texture_2d_update_immediate, RID, const Ref<Image> &, int) //these go through command queue if they are in another thread BIND3(texture_2d_update, RID, const Ref<Image> &, int) - BIND4(texture_3d_update, RID, const Ref<Image> &, int, int) + BIND2(texture_3d_update, RID, const Vector<Ref<Image>> &) BIND2(texture_proxy_update, RID, RID) //these also go pass-through @@ -177,7 +185,7 @@ public: BIND1RC(Ref<Image>, texture_2d_get, RID) BIND2RC(Ref<Image>, texture_2d_layer_get, RID, int) - BIND3RC(Ref<Image>, texture_3d_slice_get, RID, int, int) + BIND1RC(Vector<Ref<Image>>, texture_3d_get, RID) BIND2(texture_replace, RID, RID) diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index a8a56e7d56..372a7269dc 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -79,14 +79,14 @@ public: //these go pass-through, as they can be called from any thread virtual RID texture_2d_create(const Ref<Image> &p_image) { return rendering_server->texture_2d_create(p_image); } virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) { return rendering_server->texture_2d_layered_create(p_layers, p_layered_type); } - virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) { return rendering_server->texture_3d_create(p_slices); } + virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { return rendering_server->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); } virtual RID texture_proxy_create(RID p_base) { return rendering_server->texture_proxy_create(p_base); } //goes pass-through virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) { rendering_server->texture_2d_update_immediate(p_texture, p_image, p_layer); } //these go through command queue if they are in another thread FUNC3(texture_2d_update, RID, const Ref<Image> &, int) - FUNC4(texture_3d_update, RID, const Ref<Image> &, int, int) + FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &) FUNC2(texture_proxy_update, RID, RID) //these also go pass-through @@ -96,7 +96,7 @@ public: FUNC1RC(Ref<Image>, texture_2d_get, RID) FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int) - FUNC3RC(Ref<Image>, texture_3d_slice_get, RID, int, int) + FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID) FUNC2(texture_replace, RID, RID) diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 6f844c67d8..49f840948f 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -97,12 +97,12 @@ public: virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) = 0; //all slices, then all the mipmaps, must be coherent + virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; //all slices, then all the mipmaps, must be coherent virtual RID texture_proxy_create(RID p_base) = 0; virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; - virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) = 0; + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0; virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0; //these two APIs can be used together or in combination with the others. @@ -112,7 +112,7 @@ public: virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; - virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const = 0; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0; virtual void texture_replace(RID p_texture, RID p_by_texture) = 0; virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0; @@ -884,7 +884,7 @@ public: ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH, }; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; diff --git a/thirdparty/README.md b/thirdparty/README.md index a63eca2a2a..58bdafa850 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -304,7 +304,7 @@ changes are marked with `// -- GODOT --` comments. ## mbedtls - Upstream: https://tls.mbed.org/ -- Version: 2.16.7 (2020) +- Version: 2.16.8 (2020) - License: Apache 2.0 File extracted from upstream release tarball: @@ -564,7 +564,7 @@ comments and a patch is provided in the squish/ folder. ## tinyexr - Upstream: https://github.com/syoyo/tinyexr -- Version: git (4dbd05a22f51a2d7462311569b8b0cba0bbe2ac5, 2020) +- Version: 1.0.0 (e4b7840d9448b7d57a88384ce26143004f3c0c71, 2020) - License: BSD-3-Clause Files extracted from upstream source: diff --git a/thirdparty/mbedtls/include/mbedtls/aes.h b/thirdparty/mbedtls/include/mbedtls/aes.h index d20cdbd6da..4468b6623a 100644 --- a/thirdparty/mbedtls/include/mbedtls/aes.h +++ b/thirdparty/mbedtls/include/mbedtls/aes.h @@ -21,7 +21,7 @@ */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -62,8 +62,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_AES_H diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h index 91a4e0f116..9b63a0010a 100644 --- a/thirdparty/mbedtls/include/mbedtls/aesni.h +++ b/thirdparty/mbedtls/include/mbedtls/aesni.h @@ -7,7 +7,7 @@ * functions; you must not call them directly. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -48,8 +48,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_AESNI_H #define MBEDTLS_AESNI_H diff --git a/thirdparty/mbedtls/include/mbedtls/arc4.h b/thirdparty/mbedtls/include/mbedtls/arc4.h index ecaf310122..6334a9cc1e 100644 --- a/thirdparty/mbedtls/include/mbedtls/arc4.h +++ b/thirdparty/mbedtls/include/mbedtls/arc4.h @@ -7,7 +7,7 @@ * security risk. We recommend considering stronger ciphers instead. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * * ********** * - * This file is part of mbed TLS (https://tls.mbed.org) - * */ #ifndef MBEDTLS_ARC4_H #define MBEDTLS_ARC4_H diff --git a/thirdparty/mbedtls/include/mbedtls/aria.h b/thirdparty/mbedtls/include/mbedtls/aria.h index 66f2668bf3..13763d4200 100644 --- a/thirdparty/mbedtls/include/mbedtls/aria.h +++ b/thirdparty/mbedtls/include/mbedtls/aria.h @@ -10,7 +10,7 @@ * and also described by the IETF in <em>RFC 5794</em>. */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -51,8 +51,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ARIA_H diff --git a/thirdparty/mbedtls/include/mbedtls/asn1.h b/thirdparty/mbedtls/include/mbedtls/asn1.h index c64038cdb5..0e596bca2c 100644 --- a/thirdparty/mbedtls/include/mbedtls/asn1.h +++ b/thirdparty/mbedtls/include/mbedtls/asn1.h @@ -4,7 +4,7 @@ * \brief Generic ASN.1 parsing */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ASN1_H #define MBEDTLS_ASN1_H diff --git a/thirdparty/mbedtls/include/mbedtls/asn1write.h b/thirdparty/mbedtls/include/mbedtls/asn1write.h index 4fed59371c..3c7cdd6b46 100644 --- a/thirdparty/mbedtls/include/mbedtls/asn1write.h +++ b/thirdparty/mbedtls/include/mbedtls/asn1write.h @@ -4,7 +4,7 @@ * \brief ASN.1 buffer writing functionality */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ASN1_WRITE_H #define MBEDTLS_ASN1_WRITE_H diff --git a/thirdparty/mbedtls/include/mbedtls/base64.h b/thirdparty/mbedtls/include/mbedtls/base64.h index 215255e628..cbed6887ee 100644 --- a/thirdparty/mbedtls/include/mbedtls/base64.h +++ b/thirdparty/mbedtls/include/mbedtls/base64.h @@ -4,7 +4,7 @@ * \brief RFC 1521 base64 encoding/decoding */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_BASE64_H #define MBEDTLS_BASE64_H diff --git a/thirdparty/mbedtls/include/mbedtls/bignum.h b/thirdparty/mbedtls/include/mbedtls/bignum.h index 590cde58da..4bb9fa3d43 100644 --- a/thirdparty/mbedtls/include/mbedtls/bignum.h +++ b/thirdparty/mbedtls/include/mbedtls/bignum.h @@ -4,7 +4,7 @@ * \brief Multi-precision integer library */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_BIGNUM_H #define MBEDTLS_BIGNUM_H diff --git a/thirdparty/mbedtls/include/mbedtls/blowfish.h b/thirdparty/mbedtls/include/mbedtls/blowfish.h index d2a1ebdbf4..945bd426a9 100644 --- a/thirdparty/mbedtls/include/mbedtls/blowfish.h +++ b/thirdparty/mbedtls/include/mbedtls/blowfish.h @@ -4,7 +4,7 @@ * \brief Blowfish block cipher */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_BLOWFISH_H #define MBEDTLS_BLOWFISH_H diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h index 42339b7b71..9615090f91 100644 --- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h +++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h @@ -4,7 +4,7 @@ * \brief Multi-precision integer library */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * Multiply source vector [s] with b, add result diff --git a/thirdparty/mbedtls/include/mbedtls/camellia.h b/thirdparty/mbedtls/include/mbedtls/camellia.h index 41d6f955ba..38871288e4 100644 --- a/thirdparty/mbedtls/include/mbedtls/camellia.h +++ b/thirdparty/mbedtls/include/mbedtls/camellia.h @@ -4,7 +4,7 @@ * \brief Camellia block cipher */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CAMELLIA_H #define MBEDTLS_CAMELLIA_H diff --git a/thirdparty/mbedtls/include/mbedtls/ccm.h b/thirdparty/mbedtls/include/mbedtls/ccm.h index 3647d5094f..3dcdc91894 100644 --- a/thirdparty/mbedtls/include/mbedtls/ccm.h +++ b/thirdparty/mbedtls/include/mbedtls/ccm.h @@ -28,7 +28,7 @@ * consistent with RFC 3610. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -69,8 +69,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CCM_H diff --git a/thirdparty/mbedtls/include/mbedtls/certs.h b/thirdparty/mbedtls/include/mbedtls/certs.h index 2a645ad0d0..8472a6f38c 100644 --- a/thirdparty/mbedtls/include/mbedtls/certs.h +++ b/thirdparty/mbedtls/include/mbedtls/certs.h @@ -4,7 +4,7 @@ * \brief Sample certificates and DHM parameters for testing */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CERTS_H #define MBEDTLS_CERTS_H diff --git a/thirdparty/mbedtls/include/mbedtls/chacha20.h b/thirdparty/mbedtls/include/mbedtls/chacha20.h index e2950e1a01..8c9c2af6ff 100644 --- a/thirdparty/mbedtls/include/mbedtls/chacha20.h +++ b/thirdparty/mbedtls/include/mbedtls/chacha20.h @@ -13,7 +13,7 @@ */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -54,8 +54,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CHACHA20_H diff --git a/thirdparty/mbedtls/include/mbedtls/chachapoly.h b/thirdparty/mbedtls/include/mbedtls/chachapoly.h index bee5a3ab03..5f6cb6e030 100644 --- a/thirdparty/mbedtls/include/mbedtls/chachapoly.h +++ b/thirdparty/mbedtls/include/mbedtls/chachapoly.h @@ -13,7 +13,7 @@ */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -54,8 +54,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CHACHAPOLY_H diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h index 8ce73ceff1..2bbd7a80ff 100644 --- a/thirdparty/mbedtls/include/mbedtls/check_config.h +++ b/thirdparty/mbedtls/include/mbedtls/check_config.h @@ -4,7 +4,7 @@ * \brief Consistency checks for configuration options */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* @@ -199,6 +197,16 @@ #error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" #endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define MBEDTLS_HAS_MEMSAN +#endif +#endif +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN) +#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer" +#endif +#undef MBEDTLS_HAS_MEMSAN + #if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) #error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" diff --git a/thirdparty/mbedtls/include/mbedtls/cipher.h b/thirdparty/mbedtls/include/mbedtls/cipher.h index 8672dd2b98..1f41b528c4 100644 --- a/thirdparty/mbedtls/include/mbedtls/cipher.h +++ b/thirdparty/mbedtls/include/mbedtls/cipher.h @@ -8,7 +8,7 @@ * \author Adriaan de Jong <dejong@fox-it.com> */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CIPHER_H diff --git a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h index 558be52a7e..88282ec9d2 100644 --- a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h @@ -6,7 +6,7 @@ * \author Adriaan de Jong <dejong@fox-it.com> */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -47,8 +47,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CIPHER_WRAP_H #define MBEDTLS_CIPHER_WRAP_H diff --git a/thirdparty/mbedtls/include/mbedtls/cmac.h b/thirdparty/mbedtls/include/mbedtls/cmac.h index 2074747567..5a7c9b246f 100644 --- a/thirdparty/mbedtls/include/mbedtls/cmac.h +++ b/thirdparty/mbedtls/include/mbedtls/cmac.h @@ -7,7 +7,7 @@ * Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>. */ /* - * Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -48,8 +48,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CMAC_H diff --git a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h index 71cc4f4d97..45e5a1cf77 100644 --- a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h +++ b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h @@ -7,7 +7,7 @@ * \deprecated Use the new names directly instead */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -48,8 +48,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h index 28b405ebca..217998a5eb 100644 --- a/thirdparty/mbedtls/include/mbedtls/config.h +++ b/thirdparty/mbedtls/include/mbedtls/config.h @@ -8,7 +8,7 @@ * memory footprint. */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CONFIG_H @@ -552,6 +550,42 @@ //#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT /** + * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + * + * Enable testing of the constant-flow nature of some sensitive functions with + * clang's MemorySanitizer. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires compiling with clang -fsanitize=memory. The test + * suites can then be run normally. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + * + * Enable testing of the constant-flow nature of some sensitive functions with + * valgrind's memcheck tool. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires valgrind headers for building, and is only useful for + * testing if the tests suites are run with valgrind's memcheck. This can be + * done for an individual test suite with 'valgrind ./test_suite_xxx', or when + * using CMake, this can be done for all test suites with 'make memcheck'. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + +/** * \def MBEDTLS_TEST_NULL_ENTROPY * * Enables testing and use of mbed TLS without any configured entropy sources. diff --git a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h index 894fa17130..7e5f2e5769 100644 --- a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h +++ b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h @@ -38,7 +38,7 @@ * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. */ /* - * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -79,8 +79,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_CTR_DRBG_H diff --git a/thirdparty/mbedtls/include/mbedtls/debug.h b/thirdparty/mbedtls/include/mbedtls/debug.h index 11928e9818..abc2d4f07c 100644 --- a/thirdparty/mbedtls/include/mbedtls/debug.h +++ b/thirdparty/mbedtls/include/mbedtls/debug.h @@ -4,7 +4,7 @@ * \brief Functions for controlling and providing debug output from the library. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_DEBUG_H #define MBEDTLS_DEBUG_H diff --git a/thirdparty/mbedtls/include/mbedtls/des.h b/thirdparty/mbedtls/include/mbedtls/des.h index 4c6441d7d9..ee24f65945 100644 --- a/thirdparty/mbedtls/include/mbedtls/des.h +++ b/thirdparty/mbedtls/include/mbedtls/des.h @@ -8,7 +8,7 @@ * instead. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -50,8 +50,6 @@ * * ********** * - * This file is part of mbed TLS (https://tls.mbed.org) - * */ #ifndef MBEDTLS_DES_H #define MBEDTLS_DES_H diff --git a/thirdparty/mbedtls/include/mbedtls/dhm.h b/thirdparty/mbedtls/include/mbedtls/dhm.h index 5c04ed19fb..11042efb55 100644 --- a/thirdparty/mbedtls/include/mbedtls/dhm.h +++ b/thirdparty/mbedtls/include/mbedtls/dhm.h @@ -44,7 +44,7 @@ * */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -85,8 +85,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_DHM_H diff --git a/thirdparty/mbedtls/include/mbedtls/ecdh.h b/thirdparty/mbedtls/include/mbedtls/ecdh.h index a0052df471..b9324bc496 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecdh.h +++ b/thirdparty/mbedtls/include/mbedtls/ecdh.h @@ -13,7 +13,7 @@ * Cryptography</em>. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -54,8 +54,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ECDH_H diff --git a/thirdparty/mbedtls/include/mbedtls/ecdsa.h b/thirdparty/mbedtls/include/mbedtls/ecdsa.h index bc219dcad7..da02b27864 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecdsa.h +++ b/thirdparty/mbedtls/include/mbedtls/ecdsa.h @@ -11,7 +11,7 @@ * */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -52,8 +52,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ECDSA_H diff --git a/thirdparty/mbedtls/include/mbedtls/ecjpake.h b/thirdparty/mbedtls/include/mbedtls/ecjpake.h index 1b6c6ac244..a9b68d00c6 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecjpake.h +++ b/thirdparty/mbedtls/include/mbedtls/ecjpake.h @@ -4,7 +4,7 @@ * \brief Elliptic curve J-PAKE */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ECJPAKE_H #define MBEDTLS_ECJPAKE_H diff --git a/thirdparty/mbedtls/include/mbedtls/ecp.h b/thirdparty/mbedtls/include/mbedtls/ecp.h index 8db206060b..bdc750eb24 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecp.h +++ b/thirdparty/mbedtls/include/mbedtls/ecp.h @@ -15,7 +15,7 @@ */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -56,8 +56,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ECP_H diff --git a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h index 4e9445ae44..0047bd4ef9 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h @@ -5,7 +5,7 @@ * point arithmetic. */ /* - * Copyright (C) 2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/include/mbedtls/entropy.h b/thirdparty/mbedtls/include/mbedtls/entropy.h index fd70cd7e9e..1e1d3f56ec 100644 --- a/thirdparty/mbedtls/include/mbedtls/entropy.h +++ b/thirdparty/mbedtls/include/mbedtls/entropy.h @@ -4,7 +4,7 @@ * \brief Entropy accumulator implementation */ /* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ENTROPY_H #define MBEDTLS_ENTROPY_H diff --git a/thirdparty/mbedtls/include/mbedtls/entropy_poll.h b/thirdparty/mbedtls/include/mbedtls/entropy_poll.h index 9843a9e460..c348fe52d4 100644 --- a/thirdparty/mbedtls/include/mbedtls/entropy_poll.h +++ b/thirdparty/mbedtls/include/mbedtls/entropy_poll.h @@ -4,7 +4,7 @@ * \brief Platform-specific and custom entropy polling functions */ /* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ENTROPY_POLL_H #define MBEDTLS_ENTROPY_POLL_H diff --git a/thirdparty/mbedtls/include/mbedtls/error.h b/thirdparty/mbedtls/include/mbedtls/error.h index 3ee7bbba89..fa8582a391 100644 --- a/thirdparty/mbedtls/include/mbedtls/error.h +++ b/thirdparty/mbedtls/include/mbedtls/error.h @@ -4,7 +4,7 @@ * \brief Error to string translation */ /* - * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_ERROR_H #define MBEDTLS_ERROR_H diff --git a/thirdparty/mbedtls/include/mbedtls/gcm.h b/thirdparty/mbedtls/include/mbedtls/gcm.h index 52d03b0ce8..4e4434ed4d 100644 --- a/thirdparty/mbedtls/include/mbedtls/gcm.h +++ b/thirdparty/mbedtls/include/mbedtls/gcm.h @@ -12,7 +12,7 @@ * */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -53,8 +53,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_GCM_H diff --git a/thirdparty/mbedtls/include/mbedtls/havege.h b/thirdparty/mbedtls/include/mbedtls/havege.h index 75ab3cb963..e90839ddeb 100644 --- a/thirdparty/mbedtls/include/mbedtls/havege.h +++ b/thirdparty/mbedtls/include/mbedtls/havege.h @@ -4,7 +4,7 @@ * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_HAVEGE_H #define MBEDTLS_HAVEGE_H diff --git a/thirdparty/mbedtls/include/mbedtls/hkdf.h b/thirdparty/mbedtls/include/mbedtls/hkdf.h index a8db554d9f..07ffe83b23 100644 --- a/thirdparty/mbedtls/include/mbedtls/hkdf.h +++ b/thirdparty/mbedtls/include/mbedtls/hkdf.h @@ -7,7 +7,7 @@ * specified by RFC 5869. */ /* - * Copyright (C) 2016-2019, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -48,8 +48,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_HKDF_H #define MBEDTLS_HKDF_H diff --git a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h index 231fb459bc..6883678204 100644 --- a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h +++ b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h @@ -8,7 +8,7 @@ * Deterministic Random Bit Generators</em>. */ /* - * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_HMAC_DRBG_H #define MBEDTLS_HMAC_DRBG_H diff --git a/thirdparty/mbedtls/include/mbedtls/md.h b/thirdparty/mbedtls/include/mbedtls/md.h index 6a21f05908..2ba8d9e7a9 100644 --- a/thirdparty/mbedtls/include/mbedtls/md.h +++ b/thirdparty/mbedtls/include/mbedtls/md.h @@ -6,7 +6,7 @@ * \author Adriaan de Jong <dejong@fox-it.com> */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -47,8 +47,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_MD_H diff --git a/thirdparty/mbedtls/include/mbedtls/md2.h b/thirdparty/mbedtls/include/mbedtls/md2.h index 6d563b41be..9607df66ba 100644 --- a/thirdparty/mbedtls/include/mbedtls/md2.h +++ b/thirdparty/mbedtls/include/mbedtls/md2.h @@ -8,7 +8,7 @@ * instead. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -50,8 +50,6 @@ * * ********** * - * This file is part of mbed TLS (https://tls.mbed.org) - * */ #ifndef MBEDTLS_MD2_H #define MBEDTLS_MD2_H diff --git a/thirdparty/mbedtls/include/mbedtls/md4.h b/thirdparty/mbedtls/include/mbedtls/md4.h index 3f4bcdc607..6ceaf7a2f6 100644 --- a/thirdparty/mbedtls/include/mbedtls/md4.h +++ b/thirdparty/mbedtls/include/mbedtls/md4.h @@ -8,7 +8,7 @@ * instead. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -50,8 +50,6 @@ * * ********** * - * This file is part of mbed TLS (https://tls.mbed.org) - * */ #ifndef MBEDTLS_MD4_H #define MBEDTLS_MD4_H diff --git a/thirdparty/mbedtls/include/mbedtls/md5.h b/thirdparty/mbedtls/include/mbedtls/md5.h index 34279c7212..b9d0ca929a 100644 --- a/thirdparty/mbedtls/include/mbedtls/md5.h +++ b/thirdparty/mbedtls/include/mbedtls/md5.h @@ -8,7 +8,7 @@ * digests instead. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_MD5_H #define MBEDTLS_MD5_H diff --git a/thirdparty/mbedtls/include/mbedtls/md_internal.h b/thirdparty/mbedtls/include/mbedtls/md_internal.h index 154b8bbc27..847f50aa0a 100644 --- a/thirdparty/mbedtls/include/mbedtls/md_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/md_internal.h @@ -8,7 +8,7 @@ * \author Adriaan de Jong <dejong@fox-it.com> */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_MD_WRAP_H #define MBEDTLS_MD_WRAP_H diff --git a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h index c1e0926b13..89c0617495 100644 --- a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h +++ b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h @@ -4,7 +4,7 @@ * \brief Buffer-based memory allocator */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H #define MBEDTLS_MEMORY_BUFFER_ALLOC_H diff --git a/thirdparty/mbedtls/include/mbedtls/net.h b/thirdparty/mbedtls/include/mbedtls/net.h index bba4a35940..6c7a49d3bd 100644 --- a/thirdparty/mbedtls/include/mbedtls/net.h +++ b/thirdparty/mbedtls/include/mbedtls/net.h @@ -6,7 +6,7 @@ * \deprecated Superseded by mbedtls/net_sockets.h */ /* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -47,8 +47,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) #include "config.h" diff --git a/thirdparty/mbedtls/include/mbedtls/net_sockets.h b/thirdparty/mbedtls/include/mbedtls/net_sockets.h index d4d23fe9d8..00fea7db19 100644 --- a/thirdparty/mbedtls/include/mbedtls/net_sockets.h +++ b/thirdparty/mbedtls/include/mbedtls/net_sockets.h @@ -20,7 +20,7 @@ * */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -61,8 +61,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_NET_SOCKETS_H #define MBEDTLS_NET_SOCKETS_H diff --git a/thirdparty/mbedtls/include/mbedtls/nist_kw.h b/thirdparty/mbedtls/include/mbedtls/nist_kw.h index f2b9cebf9c..9435656994 100644 --- a/thirdparty/mbedtls/include/mbedtls/nist_kw.h +++ b/thirdparty/mbedtls/include/mbedtls/nist_kw.h @@ -16,7 +16,7 @@ * */ /* - * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -57,8 +57,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_NIST_KW_H diff --git a/thirdparty/mbedtls/include/mbedtls/oid.h b/thirdparty/mbedtls/include/mbedtls/oid.h index 7fe4b38621..4a7e3b4b3f 100644 --- a/thirdparty/mbedtls/include/mbedtls/oid.h +++ b/thirdparty/mbedtls/include/mbedtls/oid.h @@ -4,7 +4,7 @@ * \brief Object Identifier (OID) database */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_OID_H #define MBEDTLS_OID_H diff --git a/thirdparty/mbedtls/include/mbedtls/padlock.h b/thirdparty/mbedtls/include/mbedtls/padlock.h index bd476f5f38..d8246e2cd0 100644 --- a/thirdparty/mbedtls/include/mbedtls/padlock.h +++ b/thirdparty/mbedtls/include/mbedtls/padlock.h @@ -8,7 +8,7 @@ * functions; you must not call them directly. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -49,8 +49,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PADLOCK_H #define MBEDTLS_PADLOCK_H diff --git a/thirdparty/mbedtls/include/mbedtls/pem.h b/thirdparty/mbedtls/include/mbedtls/pem.h index 16b6101415..c9df7ca6e8 100644 --- a/thirdparty/mbedtls/include/mbedtls/pem.h +++ b/thirdparty/mbedtls/include/mbedtls/pem.h @@ -4,7 +4,7 @@ * \brief Privacy Enhanced Mail (PEM) decoding */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PEM_H #define MBEDTLS_PEM_H @@ -139,17 +137,27 @@ void mbedtls_pem_free( mbedtls_pem_context *ctx ); * \brief Write a buffer of PEM information from a DER encoded * buffer. * - * \param header header string to write - * \param footer footer string to write - * \param der_data DER data to write - * \param der_len length of the DER data - * \param buf buffer to write to - * \param buf_len length of output buffer - * \param olen total length written / required (if buf_len is not enough) - * - * \return 0 on success, or a specific PEM or BASE64 error code. On - * MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required - * size. + * \param header The header string to write. + * \param footer The footer string to write. + * \param der_data The DER data to encode. + * \param der_len The length of the DER data \p der_data in Bytes. + * \param buf The buffer to write to. + * \param buf_len The length of the output buffer \p buf in Bytes. + * \param olen The address at which to store the total length written + * or required (if \p buf_len is not enough). + * + * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len + * to request the length of the resulting PEM buffer in + * `*olen`. + * + * \note This function may be called with overlapping \p der_data + * and \p buf buffers. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large + * enough to hold the PEM buffer. In this case, `*olen` holds + * the required minimum size of \p buf. + * \return Another PEM or BASE64 error code on other kinds of failure. */ int mbedtls_pem_write_buffer( const char *header, const char *footer, const unsigned char *der_data, size_t der_len, diff --git a/thirdparty/mbedtls/include/mbedtls/pk.h b/thirdparty/mbedtls/include/mbedtls/pk.h index 408f7baee7..20d51d4f38 100644 --- a/thirdparty/mbedtls/include/mbedtls/pk.h +++ b/thirdparty/mbedtls/include/mbedtls/pk.h @@ -4,7 +4,7 @@ * \brief Public Key abstraction layer */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PK_H diff --git a/thirdparty/mbedtls/include/mbedtls/pk_internal.h b/thirdparty/mbedtls/include/mbedtls/pk_internal.h index 1cd05943ba..3f84cdf748 100644 --- a/thirdparty/mbedtls/include/mbedtls/pk_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/pk_internal.h @@ -4,7 +4,7 @@ * \brief Public Key abstraction layer: wrapper functions */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PK_WRAP_H diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs11.h b/thirdparty/mbedtls/include/mbedtls/pkcs11.h index e1446120c8..3874d4a05e 100644 --- a/thirdparty/mbedtls/include/mbedtls/pkcs11.h +++ b/thirdparty/mbedtls/include/mbedtls/pkcs11.h @@ -6,7 +6,7 @@ * \author Adriaan de Jong <dejong@fox-it.com> */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -47,8 +47,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PKCS11_H #define MBEDTLS_PKCS11_H diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs12.h b/thirdparty/mbedtls/include/mbedtls/pkcs12.h index c418e8f243..9cbcb17305 100644 --- a/thirdparty/mbedtls/include/mbedtls/pkcs12.h +++ b/thirdparty/mbedtls/include/mbedtls/pkcs12.h @@ -4,7 +4,7 @@ * \brief PKCS#12 Personal Information Exchange Syntax */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PKCS12_H #define MBEDTLS_PKCS12_H diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs5.h b/thirdparty/mbedtls/include/mbedtls/pkcs5.h index c3f645aff1..328633c492 100644 --- a/thirdparty/mbedtls/include/mbedtls/pkcs5.h +++ b/thirdparty/mbedtls/include/mbedtls/pkcs5.h @@ -6,7 +6,7 @@ * \author Mathias Olsson <mathias@kompetensum.com> */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -47,8 +47,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PKCS5_H #define MBEDTLS_PKCS5_H diff --git a/thirdparty/mbedtls/include/mbedtls/platform.h b/thirdparty/mbedtls/include/mbedtls/platform.h index dcb5a88eeb..689cfc6ec7 100644 --- a/thirdparty/mbedtls/include/mbedtls/platform.h +++ b/thirdparty/mbedtls/include/mbedtls/platform.h @@ -13,7 +13,7 @@ * dynamically configured at runtime. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -54,8 +54,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PLATFORM_H #define MBEDTLS_PLATFORM_H diff --git a/thirdparty/mbedtls/include/mbedtls/platform_time.h b/thirdparty/mbedtls/include/mbedtls/platform_time.h index a45870c3a6..e132f6a688 100644 --- a/thirdparty/mbedtls/include/mbedtls/platform_time.h +++ b/thirdparty/mbedtls/include/mbedtls/platform_time.h @@ -4,7 +4,7 @@ * \brief mbed TLS Platform time abstraction */ /* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PLATFORM_TIME_H #define MBEDTLS_PLATFORM_TIME_H diff --git a/thirdparty/mbedtls/include/mbedtls/platform_util.h b/thirdparty/mbedtls/include/mbedtls/platform_util.h index f10574afe6..426afaf040 100644 --- a/thirdparty/mbedtls/include/mbedtls/platform_util.h +++ b/thirdparty/mbedtls/include/mbedtls/platform_util.h @@ -5,7 +5,7 @@ * library. */ /* - * Copyright (C) 2018, Arm Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_PLATFORM_UTIL_H #define MBEDTLS_PLATFORM_UTIL_H diff --git a/thirdparty/mbedtls/include/mbedtls/poly1305.h b/thirdparty/mbedtls/include/mbedtls/poly1305.h index 6e45b2c2ba..b337aa841c 100644 --- a/thirdparty/mbedtls/include/mbedtls/poly1305.h +++ b/thirdparty/mbedtls/include/mbedtls/poly1305.h @@ -13,7 +13,7 @@ */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -54,8 +54,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_POLY1305_H diff --git a/thirdparty/mbedtls/include/mbedtls/ripemd160.h b/thirdparty/mbedtls/include/mbedtls/ripemd160.h index 505c39252e..31c6637d6d 100644 --- a/thirdparty/mbedtls/include/mbedtls/ripemd160.h +++ b/thirdparty/mbedtls/include/mbedtls/ripemd160.h @@ -4,7 +4,7 @@ * \brief RIPE MD-160 message digest */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_RIPEMD160_H #define MBEDTLS_RIPEMD160_H diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h index cd22fc4c1f..188c37cf3a 100644 --- a/thirdparty/mbedtls/include/mbedtls/rsa.h +++ b/thirdparty/mbedtls/include/mbedtls/rsa.h @@ -10,7 +10,7 @@ * */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -51,8 +51,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_RSA_H #define MBEDTLS_RSA_H diff --git a/thirdparty/mbedtls/include/mbedtls/rsa_internal.h b/thirdparty/mbedtls/include/mbedtls/rsa_internal.h index 2464e6b082..953cb7b81d 100644 --- a/thirdparty/mbedtls/include/mbedtls/rsa_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/rsa_internal.h @@ -35,7 +35,7 @@ * */ /* - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -77,8 +77,6 @@ * * ********** * - * This file is part of mbed TLS (https://tls.mbed.org) - * */ #ifndef MBEDTLS_RSA_INTERNAL_H diff --git a/thirdparty/mbedtls/include/mbedtls/sha1.h b/thirdparty/mbedtls/include/mbedtls/sha1.h index e69db8a15a..60c514a49e 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha1.h +++ b/thirdparty/mbedtls/include/mbedtls/sha1.h @@ -11,7 +11,7 @@ * digests instead. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -52,8 +52,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SHA1_H #define MBEDTLS_SHA1_H diff --git a/thirdparty/mbedtls/include/mbedtls/sha256.h b/thirdparty/mbedtls/include/mbedtls/sha256.h index 5b03bc31dc..b1881e183c 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha256.h +++ b/thirdparty/mbedtls/include/mbedtls/sha256.h @@ -7,7 +7,7 @@ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -48,8 +48,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SHA256_H #define MBEDTLS_SHA256_H diff --git a/thirdparty/mbedtls/include/mbedtls/sha512.h b/thirdparty/mbedtls/include/mbedtls/sha512.h index 2fbc69f80e..9ff78ecf41 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha512.h +++ b/thirdparty/mbedtls/include/mbedtls/sha512.h @@ -6,7 +6,7 @@ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -47,8 +47,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SHA512_H #define MBEDTLS_SHA512_H diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h index 6f56983562..d3ee3c4e6f 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl.h @@ -4,7 +4,7 @@ * \brief SSL/TLS functions. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SSL_H #define MBEDTLS_SSL_H diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h index e987c29e11..612d81776e 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h @@ -4,7 +4,7 @@ * \brief SSL session cache implementation */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SSL_CACHE_H #define MBEDTLS_SSL_CACHE_H diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h index 8969141165..ab8e601db7 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h @@ -4,7 +4,7 @@ * \brief SSL Ciphersuites for mbed TLS */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SSL_CIPHERSUITES_H #define MBEDTLS_SSL_CIPHERSUITES_H diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h index 71e056781c..9c2d5b62a4 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h @@ -4,7 +4,7 @@ * \brief DTLS cookie callbacks implementation */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SSL_COOKIE_H #define MBEDTLS_SSL_COOKIE_H diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h index b371094f1e..6ba6c2af09 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h @@ -4,7 +4,7 @@ * \brief Internal functions shared by the SSL modules */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SSL_INTERNAL_H #define MBEDTLS_SSL_INTERNAL_H @@ -152,6 +150,24 @@ #define MBEDTLS_SSL_RETRANS_WAITING 2 #define MBEDTLS_SSL_RETRANS_FINISHED 3 +/* This macro determines whether CBC is supported. */ +#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_AES_C) || \ + defined(MBEDTLS_CAMELLIA_C) || \ + defined(MBEDTLS_ARIA_C) || \ + defined(MBEDTLS_DES_C) ) +#define MBEDTLS_SSL_SOME_SUITES_USE_CBC +#endif + +/* This macro determines whether the CBC construct used in TLS 1.0-1.2 (as + * opposed to the very different CBC construct used in SSLv3) is supported. */ +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ + ( defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) ) +#define MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC +#endif + /* * Allow extra bytes for record, authentication and encryption overhead: * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) @@ -843,6 +859,73 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) +/** \brief Compute the HMAC of variable-length data with constant flow. + * + * This function computes the HMAC of the concatenation of \p add_data and \p + * data, and does with a code flow and memory access pattern that does not + * depend on \p data_len_secret, but only on \p min_data_len and \p + * max_data_len. In particular, this function always reads exactly \p + * max_data_len bytes from \p data. + * + * \param ctx The HMAC context. It must have keys configured + * with mbedtls_md_hmac_starts() and use one of the + * following hashes: SHA-384, SHA-256, SHA-1 or MD-5. + * It is reset using mbedtls_md_hmac_reset() after + * the computation is complete to prepare for the + * next computation. + * \param add_data The additional data prepended to \p data. This + * must point to a readable buffer of \p add_data_len + * bytes. + * \param add_data_len The length of \p add_data in bytes. + * \param data The data appended to \p add_data. This must point + * to a readable buffer of \p max_data_len bytes. + * \param data_len_secret The length of the data to process in \p data. + * This must be no less than \p min_data_len and no + * greater than \p max_data_len. + * \param min_data_len The minimal length of \p data in bytes. + * \param max_data_len The maximal length of \p data in bytes. + * \param output The HMAC will be written here. This must point to + * a writable buffer of sufficient size to hold the + * HMAC value. + * + * \retval 0 + * Success. + * \retval MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED + * The hardware accelerator failed. + */ +int mbedtls_ssl_cf_hmac( + mbedtls_md_context_t *ctx, + const unsigned char *add_data, size_t add_data_len, + const unsigned char *data, size_t data_len_secret, + size_t min_data_len, size_t max_data_len, + unsigned char *output ); + +/** \brief Copy data from a secret position with constant flow. + * + * This function copies \p len bytes from \p src_base + \p offset_secret to \p + * dst, with a code flow and memory access pattern that does not depend on \p + * offset_secret, but only on \p offset_min, \p offset_max and \p len. + * + * \param dst The destination buffer. This must point to a writable + * buffer of at least \p len bytes. + * \param src_base The base of the source buffer. This must point to a + * readable buffer of at least \p offset_max + \p len + * bytes. + * \param offset_secret The offset in the source buffer from which to copy. + * This must be no less than \p offset_min and no greater + * than \p offset_max. + * \param offset_min The minimal value of \p offset_secret. + * \param offset_max The maximal value of \p offset_secret. + * \param len The number of bytes to copy. + */ +void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst, + const unsigned char *src_base, + size_t offset_secret, + size_t offset_min, size_t offset_max, + size_t len ); +#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h index ac3be04337..a10a434138 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h @@ -4,7 +4,7 @@ * \brief TLS server ticket callbacks implementation */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_SSL_TICKET_H #define MBEDTLS_SSL_TICKET_H diff --git a/thirdparty/mbedtls/include/mbedtls/threading.h b/thirdparty/mbedtls/include/mbedtls/threading.h index b6ec4df8e9..a8183a6ef4 100644 --- a/thirdparty/mbedtls/include/mbedtls/threading.h +++ b/thirdparty/mbedtls/include/mbedtls/threading.h @@ -4,7 +4,7 @@ * \brief Threading abstraction layer */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_THREADING_H #define MBEDTLS_THREADING_H diff --git a/thirdparty/mbedtls/include/mbedtls/timing.h b/thirdparty/mbedtls/include/mbedtls/timing.h index 149ccfb666..8611ba9a4e 100644 --- a/thirdparty/mbedtls/include/mbedtls/timing.h +++ b/thirdparty/mbedtls/include/mbedtls/timing.h @@ -4,7 +4,7 @@ * \brief Portable interface to timeouts and to the CPU cycle counter */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_TIMING_H #define MBEDTLS_TIMING_H diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 2bff31d51f..d09b45002d 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -4,7 +4,7 @@ * \brief Run-time version information */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * This set of compile-time defines and run-time variables can be used to @@ -67,16 +65,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 7 +#define MBEDTLS_VERSION_PATCH 8 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02100700 -#define MBEDTLS_VERSION_STRING "2.16.7" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.7" +#define MBEDTLS_VERSION_NUMBER 0x02100800 +#define MBEDTLS_VERSION_STRING "2.16.8" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.8" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/include/mbedtls/x509.h b/thirdparty/mbedtls/include/mbedtls/x509.h index e9f2fc6024..5bb9b00292 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509.h +++ b/thirdparty/mbedtls/include/mbedtls/x509.h @@ -4,7 +4,7 @@ * \brief X.509 generic defines and structures */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_X509_H #define MBEDTLS_X509_H diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crl.h b/thirdparty/mbedtls/include/mbedtls/x509_crl.h index 0e37f65e8f..2ade47c89d 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509_crl.h +++ b/thirdparty/mbedtls/include/mbedtls/x509_crl.h @@ -4,7 +4,7 @@ * \brief X.509 certificate revocation list parsing */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_X509_CRL_H #define MBEDTLS_X509_CRL_H diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crt.h b/thirdparty/mbedtls/include/mbedtls/x509_crt.h index 4aae923ea0..c38e0c0556 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509_crt.h +++ b/thirdparty/mbedtls/include/mbedtls/x509_crt.h @@ -4,7 +4,7 @@ * \brief X.509 certificate parsing and writing */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_X509_CRT_H #define MBEDTLS_X509_CRT_H diff --git a/thirdparty/mbedtls/include/mbedtls/x509_csr.h b/thirdparty/mbedtls/include/mbedtls/x509_csr.h index 8ba2cda0dc..5dfb4213e8 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509_csr.h +++ b/thirdparty/mbedtls/include/mbedtls/x509_csr.h @@ -4,7 +4,7 @@ * \brief X.509 certificate signing request parsing and writing */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_X509_CSR_H #define MBEDTLS_X509_CSR_H diff --git a/thirdparty/mbedtls/include/mbedtls/xtea.h b/thirdparty/mbedtls/include/mbedtls/xtea.h index d372110215..cd6d3753d1 100644 --- a/thirdparty/mbedtls/include/mbedtls/xtea.h +++ b/thirdparty/mbedtls/include/mbedtls/xtea.h @@ -4,7 +4,7 @@ * \brief XTEA block cipher (32-bit) */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -45,8 +45,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #ifndef MBEDTLS_XTEA_H #define MBEDTLS_XTEA_H diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c index 9ec28690b2..9b337505fd 100644 --- a/thirdparty/mbedtls/library/aes.c +++ b/thirdparty/mbedtls/library/aes.c @@ -1,7 +1,7 @@ /* * FIPS-197 compliant AES implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. diff --git a/thirdparty/mbedtls/library/aesni.c b/thirdparty/mbedtls/library/aesni.c index 44bd89cba9..358d4ad860 100644 --- a/thirdparty/mbedtls/library/aesni.c +++ b/thirdparty/mbedtls/library/aesni.c @@ -1,7 +1,7 @@ /* * AES-NI support functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/arc4.c b/thirdparty/mbedtls/library/arc4.c index c30facb671..6729bab002 100644 --- a/thirdparty/mbedtls/library/arc4.c +++ b/thirdparty/mbedtls/library/arc4.c @@ -1,7 +1,7 @@ /* * An implementation of the ARCFOUR algorithm * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The ARCFOUR algorithm was publicly disclosed on 94/09. diff --git a/thirdparty/mbedtls/library/aria.c b/thirdparty/mbedtls/library/aria.c index 0c9dd76f07..ef0392f658 100644 --- a/thirdparty/mbedtls/library/aria.c +++ b/thirdparty/mbedtls/library/aria.c @@ -1,7 +1,7 @@ /* * ARIA implementation * - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/asn1parse.c b/thirdparty/mbedtls/library/asn1parse.c index 8d59119ae0..10239fdd15 100644 --- a/thirdparty/mbedtls/library/asn1parse.c +++ b/thirdparty/mbedtls/library/asn1parse.c @@ -1,7 +1,7 @@ /* * Generic ASN.1 parsing * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c index bd0d6af4d8..d94d0a7605 100644 --- a/thirdparty/mbedtls/library/asn1write.c +++ b/thirdparty/mbedtls/library/asn1write.c @@ -1,7 +1,7 @@ /* * ASN.1 buffer writing functionality * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/base64.c b/thirdparty/mbedtls/library/base64.c index 75849d1214..bfafb05353 100644 --- a/thirdparty/mbedtls/library/base64.c +++ b/thirdparty/mbedtls/library/base64.c @@ -1,7 +1,7 @@ /* * RFC 1521 base64 encoding/decoding * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c index f42b97650f..dfe976d648 100644 --- a/thirdparty/mbedtls/library/bignum.c +++ b/thirdparty/mbedtls/library/bignum.c @@ -1,7 +1,7 @@ /* * Multi-precision integer library * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/blowfish.c b/thirdparty/mbedtls/library/blowfish.c index f11a9d6395..a3f9be959f 100644 --- a/thirdparty/mbedtls/library/blowfish.c +++ b/thirdparty/mbedtls/library/blowfish.c @@ -1,7 +1,7 @@ /* * Blowfish implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The Blowfish block cipher was designed by Bruce Schneier in 1993. diff --git a/thirdparty/mbedtls/library/camellia.c b/thirdparty/mbedtls/library/camellia.c index 9f5724917b..40d62121bf 100644 --- a/thirdparty/mbedtls/library/camellia.c +++ b/thirdparty/mbedtls/library/camellia.c @@ -1,7 +1,7 @@ /* * Camellia implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The Camellia block cipher was designed by NTT and Mitsubishi Electric diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c index 18a2343ac5..b2e5a4763d 100644 --- a/thirdparty/mbedtls/library/ccm.c +++ b/thirdparty/mbedtls/library/ccm.c @@ -1,7 +1,7 @@ /* * NIST SP800-38C compliant CCM implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/certs.c b/thirdparty/mbedtls/library/certs.c index 7423168b25..cb43f53368 100644 --- a/thirdparty/mbedtls/library/certs.c +++ b/thirdparty/mbedtls/library/certs.c @@ -1,7 +1,7 @@ /* * X.509 test certificates * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c index d851a25bd6..80fe50cc67 100644 --- a/thirdparty/mbedtls/library/chacha20.c +++ b/thirdparty/mbedtls/library/chacha20.c @@ -5,7 +5,7 @@ * * \author Daniel King <damaki.gh@gmail.com> * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/chachapoly.c b/thirdparty/mbedtls/library/chachapoly.c index f232190dfc..c8b5bba4b2 100644 --- a/thirdparty/mbedtls/library/chachapoly.c +++ b/thirdparty/mbedtls/library/chachapoly.c @@ -3,7 +3,7 @@ * * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -44,8 +44,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c index 896ec8ec66..57da0b9c44 100644 --- a/thirdparty/mbedtls/library/cipher.c +++ b/thirdparty/mbedtls/library/cipher.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong <dejong@fox-it.com> * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/cipher_wrap.c b/thirdparty/mbedtls/library/cipher_wrap.c index 09296c7f9b..1dcac21be1 100644 --- a/thirdparty/mbedtls/library/cipher_wrap.c +++ b/thirdparty/mbedtls/library/cipher_wrap.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong <dejong@fox-it.com> * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/cmac.c b/thirdparty/mbedtls/library/cmac.c index ce0cd4b055..1a1200b52b 100644 --- a/thirdparty/mbedtls/library/cmac.c +++ b/thirdparty/mbedtls/library/cmac.c @@ -3,7 +3,7 @@ * * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -44,8 +44,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c index e1900afc45..b98df29a9b 100644 --- a/thirdparty/mbedtls/library/ctr_drbg.c +++ b/thirdparty/mbedtls/library/ctr_drbg.c @@ -1,7 +1,7 @@ /* * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The NIST SP 800-90 DRBGs are described in the following publication. diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c index 3604cfb253..5f06d0da13 100644 --- a/thirdparty/mbedtls/library/debug.c +++ b/thirdparty/mbedtls/library/debug.c @@ -1,7 +1,7 @@ /* * Debugging routines * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/des.c b/thirdparty/mbedtls/library/des.c index a5f73330b0..623165d391 100644 --- a/thirdparty/mbedtls/library/des.c +++ b/thirdparty/mbedtls/library/des.c @@ -1,7 +1,7 @@ /* * FIPS-46-3 compliant Triple-DES implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * DES, on which TDES is based, was originally designed by Horst Feistel diff --git a/thirdparty/mbedtls/library/dhm.c b/thirdparty/mbedtls/library/dhm.c index f8d367ee89..d652cf0ac9 100644 --- a/thirdparty/mbedtls/library/dhm.c +++ b/thirdparty/mbedtls/library/dhm.c @@ -1,7 +1,7 @@ /* * Diffie-Hellman-Merkle key exchange * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The following sources were referenced in the design of this implementation @@ -351,6 +349,32 @@ cleanup: } /* + * Pick a random R in the range [2, M) for blinding purposes + */ +static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count; + + count = 0; + do + { + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) ); + + while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) ); + + if( count++ > 10 ) + return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + } + while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 ); + +cleanup: + return( ret ); +} + + +/* * Use the blinding method and optimisation suggested in section 10 of: * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer @@ -359,7 +383,10 @@ cleanup: static int dhm_update_blinding( mbedtls_dhm_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - int ret, count; + int ret; + mbedtls_mpi R; + + mbedtls_mpi_init( &R ); /* * Don't use any blinding the first time a particular X is used, @@ -394,24 +421,23 @@ static int dhm_update_blinding( mbedtls_dhm_context *ctx, */ /* Vi = random( 2, P-1 ) */ - count = 0; - do - { - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) ); - - while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) - MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) ); - - if( count++ > 10 ) - return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); - } - while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 ); + MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) ); + + /* Vf = Vi^-X mod P + * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod), + * then elevate to the Xth power. */ + MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); - /* Vf = Vi^-X mod P */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); cleanup: + mbedtls_mpi_free( &R ); + return( ret ); } diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c index 5ef205f36d..8c27e4e196 100644 --- a/thirdparty/mbedtls/library/ecdh.c +++ b/thirdparty/mbedtls/library/ecdh.c @@ -1,7 +1,7 @@ /* * Elliptic curve Diffie-Hellman * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/ecdsa.c b/thirdparty/mbedtls/library/ecdsa.c index 08fda3fa9b..da8df9cde2 100644 --- a/thirdparty/mbedtls/library/ecdsa.c +++ b/thirdparty/mbedtls/library/ecdsa.c @@ -1,7 +1,7 @@ /* * Elliptic curve DSA * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/ecjpake.c b/thirdparty/mbedtls/library/ecjpake.c index c89163c68a..f6e24580c7 100644 --- a/thirdparty/mbedtls/library/ecjpake.c +++ b/thirdparty/mbedtls/library/ecjpake.c @@ -1,7 +1,7 @@ /* * Elliptic curve J-PAKE * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c index 7ea8b1676a..fe41b4128a 100644 --- a/thirdparty/mbedtls/library/ecp.c +++ b/thirdparty/mbedtls/library/ecp.c @@ -1,7 +1,7 @@ /* * Elliptic curves over GF(p): generic functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c index 796e0d1250..cc4c5b71c0 100644 --- a/thirdparty/mbedtls/library/ecp_curves.c +++ b/thirdparty/mbedtls/library/ecp_curves.c @@ -1,7 +1,7 @@ /* * Elliptic curves over GF(p): curve-specific data and functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/entropy.c b/thirdparty/mbedtls/library/entropy.c index 1bd6ce54ee..666c55654c 100644 --- a/thirdparty/mbedtls/library/entropy.c +++ b/thirdparty/mbedtls/library/entropy.c @@ -1,7 +1,7 @@ /* * Entropy accumulator implementation * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index a5996a198d..26b7e4e2b9 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -1,7 +1,7 @@ /* * Platform-specific and custom entropy polling functions * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if defined(__linux__) diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c index 4ab8733e0c..eb52052b51 100644 --- a/thirdparty/mbedtls/library/error.c +++ b/thirdparty/mbedtls/library/error.c @@ -1,7 +1,7 @@ /* * Error message information * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/gcm.c b/thirdparty/mbedtls/library/gcm.c index 7edc6da366..2afe5025a0 100644 --- a/thirdparty/mbedtls/library/gcm.c +++ b/thirdparty/mbedtls/library/gcm.c @@ -1,7 +1,7 @@ /* * NIST SP800-38D compliant GCM implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/havege.c b/thirdparty/mbedtls/library/havege.c index 800a518a66..5e91f40d84 100644 --- a/thirdparty/mbedtls/library/havege.c +++ b/thirdparty/mbedtls/library/havege.c @@ -1,7 +1,7 @@ /** * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The HAVEGE RNG was designed by Andre Seznec in 2002. diff --git a/thirdparty/mbedtls/library/hkdf.c b/thirdparty/mbedtls/library/hkdf.c index 0dd4d05645..4a8bdfbe18 100644 --- a/thirdparty/mbedtls/library/hkdf.c +++ b/thirdparty/mbedtls/library/hkdf.c @@ -1,7 +1,7 @@ /* * HKDF implementation -- RFC 5869 * - * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" diff --git a/thirdparty/mbedtls/library/hmac_drbg.c b/thirdparty/mbedtls/library/hmac_drbg.c index 2cb108c406..9fbfc30660 100644 --- a/thirdparty/mbedtls/library/hmac_drbg.c +++ b/thirdparty/mbedtls/library/hmac_drbg.c @@ -1,7 +1,7 @@ /* * HMAC_DRBG implementation (NIST SP 800-90) * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/md.c b/thirdparty/mbedtls/library/md.c index bfada3c058..867b91462d 100644 --- a/thirdparty/mbedtls/library/md.c +++ b/thirdparty/mbedtls/library/md.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong <dejong@fox-it.com> * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/md2.c b/thirdparty/mbedtls/library/md2.c index d772039b79..cbdaaabdc7 100644 --- a/thirdparty/mbedtls/library/md2.c +++ b/thirdparty/mbedtls/library/md2.c @@ -1,7 +1,7 @@ /* * RFC 1115/1319 compliant MD2 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The MD2 algorithm was designed by Ron Rivest in 1989. diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c index 56b359ce34..cb16dce54a 100644 --- a/thirdparty/mbedtls/library/md4.c +++ b/thirdparty/mbedtls/library/md4.c @@ -1,7 +1,7 @@ /* * RFC 1186/1320 compliant MD4 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The MD4 algorithm was designed by Ron Rivest in 1990. diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c index 31879a9b14..fe25925214 100644 --- a/thirdparty/mbedtls/library/md5.c +++ b/thirdparty/mbedtls/library/md5.c @@ -1,7 +1,7 @@ /* * RFC 1321 compliant MD5 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The MD5 algorithm was designed by Ron Rivest in 1991. diff --git a/thirdparty/mbedtls/library/md_wrap.c b/thirdparty/mbedtls/library/md_wrap.c index 7c737d87e9..7459db2faf 100644 --- a/thirdparty/mbedtls/library/md_wrap.c +++ b/thirdparty/mbedtls/library/md_wrap.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong <dejong@fox-it.com> * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c index e854eea8ee..915ec3ae9d 100644 --- a/thirdparty/mbedtls/library/memory_buffer_alloc.c +++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c @@ -1,7 +1,7 @@ /* * Buffer-based memory allocator * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c index 9489576aae..1130408263 100644 --- a/thirdparty/mbedtls/library/net_sockets.c +++ b/thirdparty/mbedtls/library/net_sockets.c @@ -1,7 +1,7 @@ /* * TCP/IP or UDP/IP networking functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* Enable definition of getaddrinfo() even when compiling with -std=c99. Must @@ -51,6 +49,10 @@ * Harmless on other platforms. */ #define _POSIX_C_SOURCE 200112L +#if defined(__NetBSD__) +#define _XOPEN_SOURCE 600 /* sockaddr_storage */ +#endif + #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" #else @@ -345,8 +347,9 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, struct sockaddr_storage client_addr; -#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ - defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) +#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ + defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \ + ( defined(__NetBSD__) && defined(socklen_t) ) socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); #else diff --git a/thirdparty/mbedtls/library/nist_kw.c b/thirdparty/mbedtls/library/nist_kw.c index 35be530957..8341ff1303 100644 --- a/thirdparty/mbedtls/library/nist_kw.c +++ b/thirdparty/mbedtls/library/nist_kw.c @@ -2,7 +2,7 @@ * Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes * only * - * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -43,8 +43,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ /* * Definition of Key Wrapping: diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c index 0a1658f821..2414083f0c 100644 --- a/thirdparty/mbedtls/library/oid.c +++ b/thirdparty/mbedtls/library/oid.c @@ -3,7 +3,7 @@ * * \brief Object Identifier (OID) database * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -44,8 +44,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/padlock.c b/thirdparty/mbedtls/library/padlock.c index fe6e7f9cf3..afb7e0ad42 100644 --- a/thirdparty/mbedtls/library/padlock.c +++ b/thirdparty/mbedtls/library/padlock.c @@ -1,7 +1,7 @@ /* * VIA PadLock support functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * This implementation is based on the VIA PadLock Programming Guide: diff --git a/thirdparty/mbedtls/library/pem.c b/thirdparty/mbedtls/library/pem.c index 3bf4ca5b8c..a7a2f7f5cf 100644 --- a/thirdparty/mbedtls/library/pem.c +++ b/thirdparty/mbedtls/library/pem.c @@ -1,7 +1,7 @@ /* * Privacy Enhanced Mail (PEM) decoding * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/pk.c b/thirdparty/mbedtls/library/pk.c index e9e56c029b..81cfdbfe80 100644 --- a/thirdparty/mbedtls/library/pk.c +++ b/thirdparty/mbedtls/library/pk.c @@ -1,7 +1,7 @@ /* * Public Key abstraction layer * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/pk_wrap.c b/thirdparty/mbedtls/library/pk_wrap.c index 21a7a33d82..2c27552d9b 100644 --- a/thirdparty/mbedtls/library/pk_wrap.c +++ b/thirdparty/mbedtls/library/pk_wrap.c @@ -1,7 +1,7 @@ /* * Public Key abstraction layer: wrapper functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/pkcs11.c b/thirdparty/mbedtls/library/pkcs11.c index 30d045bf18..cf484b86eb 100644 --- a/thirdparty/mbedtls/library/pkcs11.c +++ b/thirdparty/mbedtls/library/pkcs11.c @@ -5,7 +5,7 @@ * * \author Adriaan de Jong <dejong@fox-it.com> * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #include "mbedtls/pkcs11.h" diff --git a/thirdparty/mbedtls/library/pkcs12.c b/thirdparty/mbedtls/library/pkcs12.c index 3c34128682..3d23d5e354 100644 --- a/thirdparty/mbedtls/library/pkcs12.c +++ b/thirdparty/mbedtls/library/pkcs12.c @@ -1,7 +1,7 @@ /* * PKCS#12 Personal Information Exchange Syntax * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c index 7ac67093c0..8a80aa5d05 100644 --- a/thirdparty/mbedtls/library/pkcs5.c +++ b/thirdparty/mbedtls/library/pkcs5.c @@ -5,7 +5,7 @@ * * \author Mathias Olsson <mathias@kompetensum.com> * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -46,8 +46,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * PKCS#5 includes PBKDF2 and more diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c index 624ca4c671..086807d836 100644 --- a/thirdparty/mbedtls/library/pkparse.c +++ b/thirdparty/mbedtls/library/pkparse.c @@ -1,7 +1,7 @@ /* * Public Key layer for parsing key files and structures * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/pkwrite.c b/thirdparty/mbedtls/library/pkwrite.c index 76159e5a80..150626c147 100644 --- a/thirdparty/mbedtls/library/pkwrite.c +++ b/thirdparty/mbedtls/library/pkwrite.c @@ -1,7 +1,7 @@ /* * Public Key layer for writing key files and structures * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/platform.c b/thirdparty/mbedtls/library/platform.c index 7fe5e56b71..c4c3fd332d 100644 --- a/thirdparty/mbedtls/library/platform.c +++ b/thirdparty/mbedtls/library/platform.c @@ -1,7 +1,7 @@ /* * Platform abstraction layer * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/platform_util.c b/thirdparty/mbedtls/library/platform_util.c index c31c173c89..3ba2aead12 100644 --- a/thirdparty/mbedtls/library/platform_util.c +++ b/thirdparty/mbedtls/library/platform_util.c @@ -2,7 +2,7 @@ * Common and shared functions used by multiple modules in the Mbed TLS * library. * - * Copyright (C) 2018, Arm Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -43,8 +43,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of Mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c index 295997f2bc..5b023f04e4 100644 --- a/thirdparty/mbedtls/library/poly1305.c +++ b/thirdparty/mbedtls/library/poly1305.c @@ -3,7 +3,7 @@ * * \brief Poly1305 authentication algorithm. * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -44,8 +44,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c index 721db1efe4..0b6efcb574 100644 --- a/thirdparty/mbedtls/library/ripemd160.c +++ b/thirdparty/mbedtls/library/ripemd160.c @@ -1,7 +1,7 @@ /* * RIPE MD-160 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c index af1cef6515..42becbf17b 100644 --- a/thirdparty/mbedtls/library/rsa.c +++ b/thirdparty/mbedtls/library/rsa.c @@ -1,7 +1,7 @@ /* * The RSA public-key cryptosystem * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* @@ -83,7 +81,7 @@ #include "mbedtls/md.h" #endif -#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) +#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__) #include <stdlib.h> #endif @@ -808,6 +806,9 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret, count = 0; + mbedtls_mpi R; + + mbedtls_mpi_init( &R ); if( ctx->Vf.p != NULL ) { @@ -823,18 +824,41 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, /* Unblinding value: Vf = random number, invertible mod N */ do { if( count++ > 10 ) - return( MBEDTLS_ERR_RSA_RNG_FAILED ); + { + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); - } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); - /* Blinding value: Vi = Vf^(-e) mod N */ - MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); + + /* At this point, Vi is invertible mod N if and only if both Vf and R + * are invertible mod N. If one of them isn't, we don't need to know + * which one, we just loop and choose new values for both of them. + * (Each iteration succeeds with overwhelming probability.) */ + ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N ); + if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) + continue; + if( ret != 0 ) + goto cleanup; + + /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); + } while( 0 ); + + /* Blinding value: Vi = Vf^(-e) mod N + * (Vi already contains Vf^-1 at this point) */ MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); cleanup: + mbedtls_mpi_free( &R ); + return( ret ); } @@ -2590,7 +2614,7 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) #if defined(MBEDTLS_PKCS1_V15) static int myrand( void *rng_state, unsigned char *output, size_t len ) { -#if !defined(__OpenBSD__) +#if !defined(__OpenBSD__) && !defined(__NetBSD__) size_t i; if( rng_state != NULL ) @@ -2603,7 +2627,7 @@ static int myrand( void *rng_state, unsigned char *output, size_t len ) rng_state = NULL; arc4random_buf( output, len ); -#endif /* !OpenBSD */ +#endif /* !OpenBSD && !NetBSD */ return( 0 ); } diff --git a/thirdparty/mbedtls/library/rsa_internal.c b/thirdparty/mbedtls/library/rsa_internal.c index 4db49aa578..4d94ca685a 100644 --- a/thirdparty/mbedtls/library/rsa_internal.c +++ b/thirdparty/mbedtls/library/rsa_internal.c @@ -1,7 +1,7 @@ /* * Helper functions for the RSA module * - * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -43,8 +43,6 @@ * * ********** * - * This file is part of mbed TLS (https://tls.mbed.org) - * */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c index 1cffc75f8c..8682abd740 100644 --- a/thirdparty/mbedtls/library/sha1.c +++ b/thirdparty/mbedtls/library/sha1.c @@ -1,7 +1,7 @@ /* * FIPS-180-1 compliant SHA-1 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The SHA-1 standard was published by NIST in 1993. diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c index d4dd4859a6..5169584b68 100644 --- a/thirdparty/mbedtls/library/sha256.c +++ b/thirdparty/mbedtls/library/sha256.c @@ -1,7 +1,7 @@ /* * FIPS-180-2 compliant SHA-256 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The SHA-256 Secure Hash Standard was published by NIST in 2002. diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c index fdcf360d3f..36d5d96146 100644 --- a/thirdparty/mbedtls/library/sha512.c +++ b/thirdparty/mbedtls/library/sha512.c @@ -1,7 +1,7 @@ /* * FIPS-180-2 compliant SHA-384/512 implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The SHA-512 Secure Hash Standard was published by NIST in 2002. diff --git a/thirdparty/mbedtls/library/ssl_cache.c b/thirdparty/mbedtls/library/ssl_cache.c index 3cbfeb740a..1d2558a189 100644 --- a/thirdparty/mbedtls/library/ssl_cache.c +++ b/thirdparty/mbedtls/library/ssl_cache.c @@ -1,7 +1,7 @@ /* * SSL session cache implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * These session callbacks use a simple chained list diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c index de566ebca9..090040e9ab 100644 --- a/thirdparty/mbedtls/library/ssl_ciphersuites.c +++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c @@ -3,7 +3,7 @@ * * \brief SSL ciphersuites for mbed TLS * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -44,8 +44,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index 9fb2eceb22..bd7f28134d 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -1,7 +1,7 @@ /* * SSLv3/TLSv1 client-side functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/ssl_cookie.c b/thirdparty/mbedtls/library/ssl_cookie.c index 15a3173773..04565e0b79 100644 --- a/thirdparty/mbedtls/library/ssl_cookie.c +++ b/thirdparty/mbedtls/library/ssl_cookie.c @@ -1,7 +1,7 @@ /* * DTLS cookie callbacks implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * These session callbacks use a simple chained list diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c index 2c31a8ac54..97b778452c 100644 --- a/thirdparty/mbedtls/library/ssl_srv.c +++ b/thirdparty/mbedtls/library/ssl_srv.c @@ -1,7 +1,7 @@ /* * SSLv3/TLSv1 server-side functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/ssl_ticket.c b/thirdparty/mbedtls/library/ssl_ticket.c index 4a091bb640..bbde8e4ceb 100644 --- a/thirdparty/mbedtls/library/ssl_ticket.c +++ b/thirdparty/mbedtls/library/ssl_ticket.c @@ -1,7 +1,7 @@ /* * TLS server tickets callbacks implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index a40b46a1c0..2471600c9a 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -1,7 +1,7 @@ /* * SSLv3/TLSv1 shared functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The SSL 3.0 specification was drafted by Netscape in 1996, @@ -1433,32 +1431,10 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, #endif /* MBEDTLS_SSL_PROTO_SSL3 */ #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - ( defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) ) + defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) #define SSL_SOME_MODES_USE_MAC #endif -/* The function below is only used in the Lucky 13 counter-measure in - * ssl_decrypt_buf(). These are the defines that guard the call site. */ -#if defined(SSL_SOME_MODES_USE_MAC) && \ - ( defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) ) -/* This function makes sure every byte in the memory region is accessed - * (in ascending addresses order) */ -static void ssl_read_memory( unsigned char *p, size_t len ) -{ - unsigned char acc = 0; - volatile unsigned char force; - - for( ; len != 0; p++, len-- ) - acc ^= *p; - - force = acc; - (void) force; -} -#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */ - /* * Encryption/decryption functions */ @@ -1669,8 +1645,7 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) } else #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) if( mode == MBEDTLS_MODE_CBC ) { int ret; @@ -1789,8 +1764,7 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ } else -#endif /* MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ +#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -1808,6 +1782,156 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) return( 0 ); } +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) +/* + * Constant-flow conditional memcpy: + * - if c1 == c2, equivalent to memcpy(dst, src, len), + * - otherwise, a no-op, + * but with execution flow independent of the values of c1 and c2. + * + * Use only bit operations to avoid branches that could be used by some + * compilers on some platforms to translate comparison operators. + */ +static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst, + const unsigned char *src, + size_t len, + size_t c1, size_t c2 ) +{ + /* diff = 0 if c1 == c2, non-zero otherwise */ + const size_t diff = c1 ^ c2; + + /* MSVC has a warning about unary minus on unsigned integer types, + * but this is well-defined and precisely what we want to do here. */ +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + + /* diff_msb's most significant bit is equal to c1 != c2 */ + const size_t diff_msb = ( diff | -diff ); + + /* diff1 = c1 != c2 */ + const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 ); + + /* mask = c1 != c2 ? 0xff : 0x00 */ + const unsigned char mask = (unsigned char) -diff1; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + + /* dst[i] = c1 != c2 ? dst[i] : src[i] */ + size_t i; + for( i = 0; i < len; i++ ) + dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask ); +} + +/* + * Compute HMAC of variable-length data with constant flow. + * + * Only works with MD-5, SHA-1, SHA-256 and SHA-384. + * (Otherwise, computation of block_size needs to be adapted.) + */ +int mbedtls_ssl_cf_hmac( + mbedtls_md_context_t *ctx, + const unsigned char *add_data, size_t add_data_len, + const unsigned char *data, size_t data_len_secret, + size_t min_data_len, size_t max_data_len, + unsigned char *output ) +{ + /* + * This function breaks the HMAC abstraction and uses the md_clone() + * extension to the MD API in order to get constant-flow behaviour. + * + * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means + * concatenation, and okey/ikey are the XOR of the key with some fixed bit + * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx. + * + * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to + * minlen, then cloning the context, and for each byte up to maxlen + * finishing up the hash computation, keeping only the correct result. + * + * Then we only need to compute HASH(okey + inner_hash) and we're done. + */ + const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info ); + /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5, + * all of which have the same block size except SHA-384. */ + const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64; + const unsigned char * const ikey = ctx->hmac_ctx; + const unsigned char * const okey = ikey + block_size; + const size_t hash_size = mbedtls_md_get_size( ctx->md_info ); + + unsigned char aux_out[MBEDTLS_MD_MAX_SIZE]; + mbedtls_md_context_t aux; + size_t offset; + int ret; + + mbedtls_md_init( &aux ); + +#define MD_CHK( func_call ) \ + do { \ + ret = (func_call); \ + if( ret != 0 ) \ + goto cleanup; \ + } while( 0 ) + + MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) ); + + /* After hmac_start() of hmac_reset(), ikey has already been hashed, + * so we can start directly with the message */ + MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) ); + MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) ); + + /* For each possible length, compute the hash up to that point */ + for( offset = min_data_len; offset <= max_data_len; offset++ ) + { + MD_CHK( mbedtls_md_clone( &aux, ctx ) ); + MD_CHK( mbedtls_md_finish( &aux, aux_out ) ); + /* Keep only the correct inner_hash in the output buffer */ + mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size, + offset, data_len_secret ); + + if( offset < max_data_len ) + MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) ); + } + + /* Now compute HASH(okey + inner_hash) */ + MD_CHK( mbedtls_md_starts( ctx ) ); + MD_CHK( mbedtls_md_update( ctx, okey, block_size ) ); + MD_CHK( mbedtls_md_update( ctx, output, hash_size ) ); + MD_CHK( mbedtls_md_finish( ctx, output ) ); + + /* Done, get ready for next time */ + MD_CHK( mbedtls_md_hmac_reset( ctx ) ); + +#undef MD_CHK + +cleanup: + mbedtls_md_free( &aux ); + return( ret ); +} + +/* + * Constant-flow memcpy from variable position in buffer. + * - functionally equivalent to memcpy(dst, src + offset_secret, len) + * - but with execution flow independent from the value of offset_secret. + */ +void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst, + const unsigned char *src_base, + size_t offset_secret, + size_t offset_min, size_t offset_max, + size_t len ) +{ + size_t offset; + + for( offset = offset_min; offset <= offset_max; offset++ ) + { + mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len, + offset, offset_secret ); + } +} +#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ + static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) { mbedtls_cipher_mode_t mode; @@ -1962,8 +2086,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) } else #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) if( mode == MBEDTLS_MODE_CBC ) { /* @@ -2176,8 +2299,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ssl->in_msglen -= padlen; } else -#endif /* MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ +#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); @@ -2196,6 +2318,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) if( auth_done == 0 ) { unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; + unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD]; ssl->in_msglen -= ssl->transform_in->maclen; @@ -2210,6 +2333,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) ssl->in_msg, ssl->in_msglen, ssl->in_ctr, ssl->in_msgtype, mac_expect ); + memcpy( mac_peer, ssl->in_msg + ssl->in_msglen, + ssl->transform_in->maclen ); } else #endif /* MBEDTLS_SSL_PROTO_SSL3 */ @@ -2217,34 +2342,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) { - /* - * Process MAC and always update for padlen afterwards to make - * total time independent of padlen. - * - * Known timing attacks: - * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) - * - * To compensate for different timings for the MAC calculation - * depending on how much padding was removed (which is determined - * by padlen), process extra_run more blocks through the hash - * function. - * - * The formula in the paper is - * extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 ) - * where L1 is the size of the header plus the decrypted message - * plus CBC padding and L2 is the size of the header plus the - * decrypted message. This is for an underlying hash function - * with 64-byte blocks. - * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values - * correctly. We round down instead of up, so -56 is the correct - * value for our calculations instead of -55. - * - * Repeat the formula rather than defining a block_size variable. - * This avoids requiring division by a variable at runtime - * (which would be marginally less efficient and would require - * linking an extra division function in some builds). - */ - size_t j, extra_run = 0; + int ret; + unsigned char add_data[13]; /* * The next two sizes are the minimum and maximum values of @@ -2259,66 +2358,25 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) const size_t max_len = ssl->in_msglen + padlen; const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; - switch( ssl->transform_in->ciphersuite_info->mac ) - { -#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \ - defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_MD5: - case MBEDTLS_MD_SHA1: - case MBEDTLS_MD_SHA256: - /* 8 bytes of message size, 64-byte compression blocks */ - extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - - ( 13 + ssl->in_msglen + 8 ) / 64; - break; -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA384: - /* 16 bytes of message size, 128-byte compression blocks */ - extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 - - ( 13 + ssl->in_msglen + 16 ) / 128; - break; -#endif - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - extra_run &= correct * 0xFF; - - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, - ssl->in_msglen ); - /* Make sure we access everything even when padlen > 0. This - * makes the synchronisation requirements for just-in-time - * Prime+Probe attacks much tighter and hopefully impractical. */ - ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen ); - mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); + memcpy( add_data + 0, ssl->in_ctr, 8 ); + memcpy( add_data + 8, ssl->in_hdr, 3 ); + memcpy( add_data + 11, ssl->in_len, 2 ); - /* Dummy calls to compression function. - * Call mbedtls_md_process at least once due to cache attacks - * that observe whether md_process() was called of not. - * Respect the usual start-(process|update)-finish sequence for - * the sake of hardware accelerators that might require it. */ - mbedtls_md_starts( &ssl->transform_in->md_ctx_dec ); - for( j = 0; j < extra_run + 1; j++ ) - mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); + ret = mbedtls_ssl_cf_hmac( &ssl->transform_in->md_ctx_dec, + add_data, sizeof( add_data ), + ssl->in_msg, ssl->in_msglen, + min_len, max_len, + mac_expect ); + if( ret != 0 ) { - /* The switch statement above already checks that we're using - * one of MD-5, SHA-1, SHA-256 or SHA-384. */ - unsigned char tmp[384 / 8]; - mbedtls_md_finish( &ssl->transform_in->md_ctx_dec, tmp ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret ); + return( ret ); } - mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); - - /* Make sure we access all the memory that could contain the MAC, - * before we check it in the next code block. This makes the - * synchronisation requirements for just-in-time Prime+Probe - * attacks much tighter and hopefully impractical. */ - ssl_read_memory( ssl->in_msg + min_len, - max_len - min_len + ssl->transform_in->maclen ); + mbedtls_ssl_cf_memcpy_offset( mac_peer, ssl->in_msg, + ssl->in_msglen, + min_len, max_len, + ssl->transform_in->maclen ); } else #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ @@ -2330,11 +2388,10 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_DEBUG_ALL) MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen, - ssl->transform_in->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, ssl->transform_in->maclen ); #endif - if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect, + if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect, ssl->transform_in->maclen ) != 0 ) { #if defined(MBEDTLS_SSL_DEBUG_ALL) @@ -2762,7 +2819,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) if( ret < 0 ) return( ret ); - if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) ) + if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "f_recv returned %d bytes but only %lu were requested", @@ -2816,7 +2873,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) if( ret <= 0 ) return( ret ); - if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) ) + if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "f_send returned %d bytes but only %lu bytes were sent", @@ -8596,6 +8653,10 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) memcpy( buf, ssl->in_offt, n ); ssl->in_msglen -= n; + /* Zeroising the plaintext buffer to erase unused application data + from the memory. */ + mbedtls_platform_zeroize( ssl->in_offt, n ); + if( ssl->in_msglen == 0 ) { /* all bytes consumed */ diff --git a/thirdparty/mbedtls/library/threading.c b/thirdparty/mbedtls/library/threading.c index 144fe5d46c..61c4b94041 100644 --- a/thirdparty/mbedtls/library/threading.c +++ b/thirdparty/mbedtls/library/threading.c @@ -1,7 +1,7 @@ /* * Threading abstraction layer * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c index a4beff35a9..50a22165a6 100644 --- a/thirdparty/mbedtls/library/timing.c +++ b/thirdparty/mbedtls/library/timing.c @@ -1,7 +1,7 @@ /* * Portable interface to the CPU cycle counter * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/version.c b/thirdparty/mbedtls/library/version.c index bdba12f613..5733288f62 100644 --- a/thirdparty/mbedtls/library/version.c +++ b/thirdparty/mbedtls/library/version.c @@ -1,7 +1,7 @@ /* * Version information * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c index 51662bfd21..cbf38dc2c2 100644 --- a/thirdparty/mbedtls/library/version_features.c +++ b/thirdparty/mbedtls/library/version_features.c @@ -1,7 +1,7 @@ /* * Version feature information * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) @@ -279,6 +277,12 @@ static const char *features[] = { #if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) "MBEDTLS_ECP_NORMALIZE_MXZ_ALT", #endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN", +#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */ +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) + "MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND", +#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */ #if defined(MBEDTLS_TEST_NULL_ENTROPY) "MBEDTLS_TEST_NULL_ENTROPY", #endif /* MBEDTLS_TEST_NULL_ENTROPY */ diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c index 63ceaf9f4d..0c820eca90 100644 --- a/thirdparty/mbedtls/library/x509.c +++ b/thirdparty/mbedtls/library/x509.c @@ -1,7 +1,7 @@ /* * X.509 common functions for parsing and verification * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The ITU-T X.509 standard defines a certificate format for PKI. diff --git a/thirdparty/mbedtls/library/x509_create.c b/thirdparty/mbedtls/library/x509_create.c index 75de91f6c8..0dbd679a93 100644 --- a/thirdparty/mbedtls/library/x509_create.c +++ b/thirdparty/mbedtls/library/x509_create.c @@ -1,7 +1,7 @@ /* * X.509 base functions for creating certificates / CSRs * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c index 94c0c01afe..dba71fad58 100644 --- a/thirdparty/mbedtls/library/x509_crl.c +++ b/thirdparty/mbedtls/library/x509_crl.c @@ -1,7 +1,7 @@ /* * X.509 Certidicate Revocation List (CRL) parsing * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The ITU-T X.509 standard defines a certificate format for PKI. @@ -285,13 +283,13 @@ static int x509_get_entries( unsigned char **p, size_t len2; const unsigned char *end2; + cur_entry->raw.tag = **p; if( ( ret = mbedtls_asn1_get_tag( p, end, &len2, MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) { return( ret ); } - cur_entry->raw.tag = **p; cur_entry->raw.p = *p; cur_entry->raw.len = len2; end2 = *p + len2; diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c index 7d01585472..de40eaaf58 100644 --- a/thirdparty/mbedtls/library/x509_crt.c +++ b/thirdparty/mbedtls/library/x509_crt.c @@ -1,7 +1,7 @@ /* * X.509 certificate parsing and verification * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The ITU-T X.509 standard defines a certificate format for PKI. @@ -1846,8 +1844,7 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509 if( crt->serial.len == cur->serial.len && memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) { - if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) - return( 1 ); + return( 1 ); } cur = cur->next; diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c index 5045c10830..663047d516 100644 --- a/thirdparty/mbedtls/library/x509_csr.c +++ b/thirdparty/mbedtls/library/x509_csr.c @@ -1,7 +1,7 @@ /* * X.509 Certificate Signing Request (CSR) parsing * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * The ITU-T X.509 standard defines a certificate format for PKI. diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c index 0fc94fed2e..5462e83fe0 100644 --- a/thirdparty/mbedtls/library/x509write_crt.c +++ b/thirdparty/mbedtls/library/x509write_crt.c @@ -1,7 +1,7 @@ /* * X.509 certificate writing * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * References: @@ -101,39 +99,44 @@ void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) ); } -void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ) +void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, + int version ) { ctx->version = version; } -void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ) +void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, + mbedtls_md_type_t md_alg ) { ctx->md_alg = md_alg; } -void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ) +void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, + mbedtls_pk_context *key ) { ctx->subject_key = key; } -void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ) +void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, + mbedtls_pk_context *key ) { ctx->issuer_key = key; } int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, - const char *subject_name ) + const char *subject_name ) { return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); } int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, - const char *issuer_name ) + const char *issuer_name ) { return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); } -int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ) +int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, + const mbedtls_mpi *serial ) { int ret; @@ -143,8 +146,9 @@ int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls return( 0 ); } -int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, - const char *not_after ) +int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, + const char *not_before, + const char *not_after ) { if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ) @@ -164,12 +168,12 @@ int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, int critical, const unsigned char *val, size_t val_len ) { - return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, - critical, val, val_len ); + return( mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, + critical, val, val_len ) ); } int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, - int is_ca, int max_pathlen ) + int is_ca, int max_pathlen ) { int ret; unsigned char buf[9]; @@ -185,18 +189,21 @@ int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, { if( max_pathlen >= 0 ) { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, + max_pathlen ) ); } MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); } MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); - return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, - MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), - 0, buf + sizeof(buf) - len, len ); + return( + mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, + MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), + 0, buf + sizeof(buf) - len, len ) ); } #if defined(MBEDTLS_SHA1_C) @@ -208,7 +215,8 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct size_t len = 0; memset( buf, 0, sizeof(buf) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, buf + sizeof( buf ) - 20 ); @@ -218,11 +226,13 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct len = 20; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); - return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), - 0, buf + sizeof(buf) - len, len ); + return mbedtls_x509write_crt_set_extension( ctx, + MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, + MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), + 0, buf + sizeof(buf) - len, len ); } int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) @@ -233,7 +243,8 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert * size_t len = 0; memset( buf, 0, sizeof(buf) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, buf + sizeof( buf ) - 20 ); @@ -243,15 +254,19 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert * len = 20; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), - 0, buf + sizeof( buf ) - len, len ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return mbedtls_x509write_crt_set_extension( + ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, + MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), + 0, buf + sizeof( buf ) - len, len ); } #endif /* MBEDTLS_SHA1_C */ @@ -298,8 +313,8 @@ int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, return( MBEDTLS_ERR_X509_INVALID_FORMAT ); ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, - MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), - 1, c, (size_t)ret ); + MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), + 1, c, (size_t)ret ); if( ret != 0 ) return( ret ); @@ -325,8 +340,8 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, return( ret ); ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, - MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), - 0, c, (size_t)ret ); + MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), + 0, c, (size_t)ret ); if( ret != 0 ) return( ret ); @@ -348,7 +363,8 @@ static int x509_write_time( unsigned char **p, unsigned char *start, (const unsigned char *) t + 2, size - 2 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, + MBEDTLS_ASN1_UTC_TIME ) ); } else { @@ -356,15 +372,17 @@ static int x509_write_time( unsigned char **p, unsigned char *start, (const unsigned char *) t, size ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, + MBEDTLS_ASN1_GENERALIZED_TIME ) ); } return( (int) len ); } -int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, + unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; const char *sig_oid; @@ -372,15 +390,14 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, unsigned char *c, *c2; unsigned char hash[64]; unsigned char sig[SIGNATURE_MAX_SIZE]; - unsigned char tmp_buf[2048]; size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; mbedtls_pk_type_t pk_alg; /* - * Prepare data to be signed in tmp_buf + * Prepare data to be signed at the end of the target buffer */ - c = tmp_buf + sizeof( tmp_buf ); + c = buf + size; /* Signature algorithm needed in TBS, and later for actual signature */ @@ -406,27 +423,36 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, /* Only for v3 */ if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 ) { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_x509_write_extensions( &c, + buf, ctx->extensions ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); } /* * SubjectPublicKeyInfo */ - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key, - tmp_buf, c - tmp_buf ) ); + MBEDTLS_ASN1_CHK_ADD( pub_len, + mbedtls_pk_write_pubkey_der( ctx->subject_key, + buf, c - buf ) ); c -= pub_len; len += pub_len; /* * Subject ::= Name */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_x509_write_names( &c, buf, + ctx->subject ) ); /* * Validity ::= SEQUENCE { @@ -435,32 +461,39 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, */ sub_len = 0; - MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); + MBEDTLS_ASN1_CHK_ADD( sub_len, + x509_write_time( &c, buf, ctx->not_after, + MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); - MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); + MBEDTLS_ASN1_CHK_ADD( sub_len, + x509_write_time( &c, buf, ctx->not_before, + MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); len += sub_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); /* * Issuer ::= Name */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, + ctx->issuer ) ); /* * Signature ::= AlgorithmIdentifier */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf, - sig_oid, strlen( sig_oid ), 0 ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_algorithm_identifier( &c, buf, + sig_oid, strlen( sig_oid ), 0 ) ); /* * Serial ::= INTEGER */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, + &ctx->serial ) ); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } @@ -470,48 +503,67 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 ) { sub_len = 0; - MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) ); + MBEDTLS_ASN1_CHK_ADD( sub_len, + mbedtls_asn1_write_int( &c, buf, ctx->version ) ); len += sub_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_len( &c, buf, sub_len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); } - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); /* * Make signature */ + + /* Compute hash of CRT. */ if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ) ) != 0 ) { return( ret ); } - if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, - f_rng, p_rng ) ) != 0 ) + if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, + hash, 0, sig, &sig_len, + f_rng, p_rng ) ) != 0 ) { return( ret ); } - /* - * Write data to output buffer - */ + /* Move CRT to the front of the buffer to have space + * for the signature. */ + memmove( buf, c, len ); + c = buf + len; + + /* Add signature at the end of the buffer, + * making sure that it doesn't underflow + * into the CRT buffer. */ c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, + MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c, sig_oid, sig_oid_len, sig, sig_len ) ); - if( len > (size_t)( c2 - buf ) ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + /* + * Memory layout after this step: + * + * buf c=buf+len c2 buf+size + * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] + */ - c2 -= len; - memcpy( c2, c, len ); + /* Move raw CRT to just before the signature. */ + c = c2 - len; + memmove( c, buf, len ); len += sig_and_oid_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); return( (int) len ); @@ -521,23 +573,23 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, #define PEM_END_CRT "-----END CERTIFICATE-----\n" #if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, + unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; - unsigned char output_buf[4096]; - size_t olen = 0; + size_t olen; - if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf), + if( ( ret = mbedtls_x509write_crt_der( crt, buf, size, f_rng, p_rng ) ) < 0 ) { return( ret ); } if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) + buf + size - ret, ret, + buf, size, &olen ) ) != 0 ) { return( ret ); } diff --git a/thirdparty/mbedtls/library/x509write_csr.c b/thirdparty/mbedtls/library/x509write_csr.c index d1b0716c96..60cf12379f 100644 --- a/thirdparty/mbedtls/library/x509write_csr.c +++ b/thirdparty/mbedtls/library/x509write_csr.c @@ -1,7 +1,7 @@ /* * X.509 Certificate Signing Request writing * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ /* * References: @@ -81,6 +79,14 @@ #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE #endif +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdlib.h> +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) { memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); @@ -187,71 +193,85 @@ int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, return( 0 ); } -int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx, + unsigned char *buf, + size_t size, + unsigned char *sig, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret; const char *sig_oid; size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; - unsigned char sig[SIGNATURE_MAX_SIZE]; - unsigned char tmp_buf[2048]; size_t pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; mbedtls_pk_type_t pk_alg; - /* - * Prepare data to be signed in tmp_buf - */ - c = tmp_buf + sizeof( tmp_buf ); + /* Write the CSR backwards starting from the end of buf */ + c = buf + size; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, buf, + ctx->extensions ) ); if( len ) { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SET ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, - MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( + &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( + &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ); + + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_oid( + &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, + MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( + &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); } - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( + &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, - tmp_buf, c - tmp_buf ) ); + buf, c - buf ) ); c -= pub_len; len += pub_len; /* * Subject ::= Name */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, + ctx->subject ) ); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( + &c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); /* - * Prepare signature + * Sign the written CSR data into the sig buffer + * Note: hash errors can happen only after an internal error */ ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); if( ret != 0 ) @@ -271,32 +291,68 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s return( MBEDTLS_ERR_X509_INVALID_ALG ); if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, - &sig_oid, &sig_oid_len ) ) != 0 ) + &sig_oid, &sig_oid_len ) ) != 0 ) { return( ret ); } /* - * Write data to output buffer + * Move the written CSR data to the start of buf to create space for + * writing the signature into buf. */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, - sig_oid, sig_oid_len, sig, sig_len ) ); + memmove( buf, c, len ); - if( len > (size_t)( c2 - buf ) ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + /* + * Write sig and its OID into buf backwards from the end of buf. + * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len + * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed. + */ + c2 = buf + size; + MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, + mbedtls_x509_write_sig( &c2, buf + len, sig_oid, sig_oid_len, + sig, sig_len ) ); + /* + * Compact the space between the CSR data and signature by moving the + * CSR data to the start of the signature. + */ c2 -= len; - memcpy( c2, c, len ); + memmove( c2, buf, len ); + /* ASN encode the total size and tag the CSR data with it. */ len += sig_and_oid_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, + mbedtls_asn1_write_tag( + &c2, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); + + /* Zero the unused bytes at the start of buf */ + memset( buf, 0, c2 - buf); return( (int) len ); } +int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, + size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char *sig; + + if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL ) + { + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + } + + ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng ); + + mbedtls_free( sig ); + + return( ret ); +} + #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" diff --git a/thirdparty/mbedtls/library/xtea.c b/thirdparty/mbedtls/library/xtea.c index 26ec5de5a9..4e62817579 100644 --- a/thirdparty/mbedtls/library/xtea.c +++ b/thirdparty/mbedtls/library/xtea.c @@ -1,7 +1,7 @@ /* * An 32-bit implementation of the XTEA algorithm * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later * * This file is provided under the Apache License 2.0, or the @@ -42,8 +42,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * ********** - * - * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) diff --git a/thirdparty/tinyexr/tinyexr.cc b/thirdparty/tinyexr/tinyexr.cc index 969a6d505d..fef8f66c98 100644 --- a/thirdparty/tinyexr/tinyexr.cc +++ b/thirdparty/tinyexr/tinyexr.cc @@ -1,2 +1,8 @@ +#if defined(_WIN32) +#ifndef NOMINMAX +#define NOMINMAX +#endif +#endif + #define TINYEXR_IMPLEMENTATION #include "tinyexr.h" diff --git a/thirdparty/tinyexr/tinyexr.h b/thirdparty/tinyexr/tinyexr.h index 7e8956f7d3..a3e7b23161 100644 --- a/thirdparty/tinyexr/tinyexr.h +++ b/thirdparty/tinyexr/tinyexr.h @@ -1,5 +1,7 @@ +#ifndef TINYEXR_H_ +#define TINYEXR_H_ /* -Copyright (c) 2014 - 2019, Syoyo Fujita and many contributors. +Copyright (c) 2014 - 2020, Syoyo Fujita and many contributors. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -63,9 +65,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // End of OpenEXR license ------------------------------------------------- -#ifndef TINYEXR_H_ -#define TINYEXR_H_ - // // // Do this: @@ -198,11 +197,18 @@ typedef struct _EXRTile { unsigned char **images; // image[channels][pixels] } EXRTile; +typedef struct _EXRBox2i { + int min_x; + int min_y; + int max_x; + int max_y; +} EXRBox2i; + typedef struct _EXRHeader { float pixel_aspect_ratio; int line_order; - int data_window[4]; - int display_window[4]; + EXRBox2i data_window; + EXRBox2i display_window; float screen_window_center[2]; float screen_window_width; @@ -287,26 +293,29 @@ typedef struct _DeepImage { extern int LoadEXR(float **out_rgba, int *width, int *height, const char *filename, const char **err); -// Loads single-frame OpenEXR image by specifing layer name. Assume EXR image contains A(single channel -// alpha) or RGB(A) channels. -// Application must free image data as returned by `out_rgba` -// Result image format is: float x RGBA x width x hight -// Returns negative value and may set error string in `err` when there's an -// error -// When the specified layer name is not found in the EXR file, the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`. +// Loads single-frame OpenEXR image by specifying layer name. Assume EXR image +// contains A(single channel alpha) or RGB(A) channels. Application must free +// image data as returned by `out_rgba` Result image format is: float x RGBA x +// width x hight Returns negative value and may set error string in `err` when +// there's an error When the specified layer name is not found in the EXR file, +// the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`. extern int LoadEXRWithLayer(float **out_rgba, int *width, int *height, - const char *filename, const char *layer_name, const char **err); + const char *filename, const char *layer_name, + const char **err); // // Get layer infos from EXR file. // -// @param[out] layer_names List of layer names. Application must free memory after using this. +// @param[out] layer_names List of layer names. Application must free memory +// after using this. // @param[out] num_layers The number of layers -// @param[out] err Error string(wll be filled when the function returns error code). Free it using FreeEXRErrorMessage after using this value. +// @param[out] err Error string(will be filled when the function returns error +// code). Free it using FreeEXRErrorMessage after using this value. // // @return TINYEXR_SUCCEES upon success. // -extern int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err); +extern int EXRLayers(const char *filename, const char **layer_names[], + int *num_layers, const char **err); // @deprecated { to be removed. } // Simple wrapper API for ParseEXRHeaderFromFile. @@ -336,13 +345,13 @@ extern void InitEXRHeader(EXRHeader *exr_header); // Initialize EXRImage struct extern void InitEXRImage(EXRImage *exr_image); -// Free's internal data of EXRHeader struct +// Frees internal data of EXRHeader struct extern int FreeEXRHeader(EXRHeader *exr_header); -// Free's internal data of EXRImage struct +// Frees internal data of EXRImage struct extern int FreeEXRImage(EXRImage *exr_image); -// Free's error message +// Frees error message extern void FreeEXRErrorMessage(const char *msg); // Parse EXR version header of a file. @@ -497,8 +506,17 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height, #endif // TINYEXR_H_ #ifdef TINYEXR_IMPLEMENTATION -#ifndef TINYEXR_IMPLEMENTATION_DEIFNED -#define TINYEXR_IMPLEMENTATION_DEIFNED +#ifndef TINYEXR_IMPLEMENTATION_DEFINED +#define TINYEXR_IMPLEMENTATION_DEFINED + +#ifdef _WIN32 + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> // for UTF-8 + +#endif #include <algorithm> #include <cassert> @@ -536,7 +554,18 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height, #endif #if TINYEXR_USE_ZFP + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Weverything" +#endif + #include "zfp.h" + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #endif namespace tinyexr { @@ -619,7 +648,7 @@ namespace miniz { - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug - would only have occured in earlier versions if you explicitly used this + would only have occurred in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place() (which used this flag). If you can't switch to v1.15 but want to fix @@ -7002,6 +7031,13 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, // Reuse MINIZ_LITTE_ENDIAN macro +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ + defined(__i386) || defined(__i486__) || defined(__i486) || \ + defined(i386) || defined(__ia64__) || defined(__x86_64__) +// MINIZ_X86_OR_X64_CPU is only used to help set the below macros. +#define MINIZ_X86_OR_X64_CPU 1 +#endif + #if defined(__sparcv9) // Big endian #else @@ -7116,6 +7152,36 @@ static void swap4(unsigned int *val) { #endif } +static void swap4(int *val) { +#ifdef MINIZ_LITTLE_ENDIAN + (void)val; +#else + int tmp = *val; + unsigned char *dst = reinterpret_cast<unsigned char *>(val); + unsigned char *src = reinterpret_cast<unsigned char *>(&tmp); + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; +#endif +} + +static void swap4(float *val) { +#ifdef MINIZ_LITTLE_ENDIAN + (void)val; +#else + float tmp = *val; + unsigned char *dst = reinterpret_cast<unsigned char *>(val); + unsigned char *src = reinterpret_cast<unsigned char *>(&tmp); + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; +#endif +} + #if 0 static void cpy8(tinyexr::tinyexr_uint64 *dst_val, const tinyexr::tinyexr_uint64 *src_val) { unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val); @@ -7363,7 +7429,7 @@ static void WriteAttributeToMemory(std::vector<unsigned char> *out, out->insert(out->end(), type, type + strlen(type) + 1); int outLen = len; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&outLen)); + tinyexr::swap4(&outLen); out->insert(out->end(), reinterpret_cast<unsigned char *>(&outLen), reinterpret_cast<unsigned char *>(&outLen) + sizeof(int)); out->insert(out->end(), data, data + len); @@ -7379,12 +7445,19 @@ typedef struct { } ChannelInfo; typedef struct { + int min_x; + int min_y; + int max_x; + int max_y; +} Box2iInfo; + +struct HeaderInfo { std::vector<tinyexr::ChannelInfo> channels; std::vector<EXRAttribute> attributes; - int data_window[4]; + Box2iInfo data_window; int line_order; - int display_window[4]; + Box2iInfo display_window; float screen_window_center[2]; float screen_window_width; float pixel_aspect_ratio; @@ -7405,15 +7478,15 @@ typedef struct { channels.clear(); attributes.clear(); - data_window[0] = 0; - data_window[1] = 0; - data_window[2] = 0; - data_window[3] = 0; + data_window.min_x = 0; + data_window.min_y = 0; + data_window.max_x = 0; + data_window.max_y = 0; line_order = 0; - display_window[0] = 0; - display_window[1] = 0; - display_window[2] = 0; - display_window[3] = 0; + display_window.min_x = 0; + display_window.min_y = 0; + display_window.max_x = 0; + display_window.max_y = 0; screen_window_center[0] = 0.0f; screen_window_center[1] = 0.0f; screen_window_width = 0.0f; @@ -7430,7 +7503,7 @@ typedef struct { header_len = 0; compression_type = 0; } -} HeaderInfo; +}; static bool ReadChannelInfo(std::vector<ChannelInfo> &channels, const std::vector<unsigned char> &data) { @@ -7469,9 +7542,9 @@ static bool ReadChannelInfo(std::vector<ChannelInfo> &channels, memcpy(&info.y_sampling, p, sizeof(int)); // int p += 4; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.pixel_type)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.x_sampling)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.y_sampling)); + tinyexr::swap4(&info.pixel_type); + tinyexr::swap4(&info.x_sampling); + tinyexr::swap4(&info.y_sampling); channels.push_back(info); } @@ -7501,9 +7574,9 @@ static void WriteChannelInfo(std::vector<unsigned char> &data, int pixel_type = channels[c].pixel_type; int x_sampling = channels[c].x_sampling; int y_sampling = channels[c].y_sampling; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&pixel_type)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&x_sampling)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&y_sampling)); + tinyexr::swap4(&pixel_type); + tinyexr::swap4(&x_sampling); + tinyexr::swap4(&y_sampling); memcpy(p, &pixel_type, sizeof(int)); p += sizeof(int); @@ -7712,7 +7785,7 @@ static int rleCompress(int inLength, const char in[], signed char out[]) { if (runEnd - runStart >= MIN_RUN_LENGTH) { // - // Compressable run + // Compressible run // *outWrite++ = static_cast<char>(runEnd - runStart) - 1; @@ -8056,7 +8129,7 @@ static void wav2Encode( int p2 = 2; // == 1 << (level+1) // - // Hierachical loop on smaller dimension n + // Hierarchical loop on smaller dimension n // while (p2 <= n) { @@ -8287,9 +8360,9 @@ const int HUF_DECMASK = HUF_DECSIZE - 1; struct HufDec { // short code long code //------------------------------- - int len : 8; // code length 0 - int lit : 24; // lit p size - int *p; // 0 lits + unsigned int len : 8; // code length 0 + unsigned int lit : 24; // lit p size + unsigned int *p; // 0 lits }; inline long long hufLength(long long code) { return code & 63; } @@ -8745,14 +8818,14 @@ static bool hufBuildDecTable(const long long *hcode, // i : encoding table pl->lit++; if (pl->p) { - int *p = pl->p; - pl->p = new int[pl->lit]; + unsigned int *p = pl->p; + pl->p = new unsigned int[pl->lit]; for (int i = 0; i < pl->lit - 1; ++i) pl->p[i] = p[i]; delete[] p; } else { - pl->p = new int[1]; + pl->p = new unsigned int[1]; } pl->p[pl->lit - 1] = im; @@ -9491,35 +9564,48 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr, #endif // TINYEXR_USE_PIZ #if TINYEXR_USE_ZFP + struct ZFPCompressionParam { double rate; - int precision; + unsigned int precision; + unsigned int __pad0; double tolerance; int type; // TINYEXR_ZFP_COMPRESSIONTYPE_* + unsigned int __pad1; ZFPCompressionParam() { type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE; rate = 2.0; precision = 0; - tolerance = 0.0f; + tolerance = 0.0; } }; -bool FindZFPCompressionParam(ZFPCompressionParam *param, - const EXRAttribute *attributes, - int num_attributes) { +static bool FindZFPCompressionParam(ZFPCompressionParam *param, + const EXRAttribute *attributes, + int num_attributes, std::string *err) { bool foundType = false; for (int i = 0; i < num_attributes; i++) { - if ((strcmp(attributes[i].name, "zfpCompressionType") == 0) && - (attributes[i].size == 1)) { - param->type = static_cast<int>(attributes[i].value[0]); - - foundType = true; + if ((strcmp(attributes[i].name, "zfpCompressionType") == 0)) { + if (attributes[i].size == 1) { + param->type = static_cast<int>(attributes[i].value[0]); + foundType = true; + break; + } else { + if (err) { + (*err) += + "zfpCompressionType attribute must be uchar(1 byte) type.\n"; + } + return false; + } } } if (!foundType) { + if (err) { + (*err) += "`zfpCompressionType` attribute not found.\n"; + } return false; } @@ -9531,6 +9617,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param, return true; } } + + if (err) { + (*err) += "`zfpCompressionRate` attribute not found.\n"; + } + } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) { for (int i = 0; i < num_attributes; i++) { if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) && @@ -9539,6 +9630,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param, return true; } } + + if (err) { + (*err) += "`zfpCompressionPrecision` attribute not found.\n"; + } + } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) { for (int i = 0; i < num_attributes; i++) { if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) && @@ -9547,8 +9643,14 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param, return true; } } + + if (err) { + (*err) += "`zfpCompressionTolerance` attribute not found.\n"; + } } else { - assert(0); + if (err) { + (*err) += "Unknown value specified for `zfpCompressionType`.\n"; + } } return false; @@ -9556,10 +9658,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param, // Assume pixel format is FLOAT for all channels. static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines, - int num_channels, const unsigned char *src, + size_t num_channels, const unsigned char *src, unsigned long src_size, const ZFPCompressionParam ¶m) { - size_t uncompressed_size = dst_width * dst_num_lines * num_channels; + size_t uncompressed_size = + size_t(dst_width) * size_t(dst_num_lines) * num_channels; if (uncompressed_size == src_size) { // Data is not compressed(Issue 40). @@ -9572,22 +9675,24 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines, assert((dst_width % 4) == 0); assert((dst_num_lines % 4) == 0); - if ((dst_width & 3U) || (dst_num_lines & 3U)) { + if ((size_t(dst_width) & 3U) || (size_t(dst_num_lines) & 3U)) { return false; } field = zfp_field_2d(reinterpret_cast<void *>(const_cast<unsigned char *>(src)), - zfp_type_float, dst_width, dst_num_lines * num_channels); + zfp_type_float, static_cast<unsigned int>(dst_width), + static_cast<unsigned int>(dst_num_lines) * + static_cast<unsigned int>(num_channels)); zfp = zfp_stream_open(NULL); if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) { - zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimention */ 2, + zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimension */ 2, /* write random access */ 0); } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) { - zfp_stream_set_precision(zfp, param.precision, zfp_type_float); + zfp_stream_set_precision(zfp, param.precision); } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) { - zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float); + zfp_stream_set_accuracy(zfp, param.tolerance); } else { assert(0); } @@ -9600,17 +9705,17 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines, zfp_stream_set_bit_stream(zfp, stream); zfp_stream_rewind(zfp); - size_t image_size = dst_width * dst_num_lines; + size_t image_size = size_t(dst_width) * size_t(dst_num_lines); - for (int c = 0; c < num_channels; c++) { + for (size_t c = 0; c < size_t(num_channels); c++) { // decompress 4x4 pixel block. - for (int y = 0; y < dst_num_lines; y += 4) { - for (int x = 0; x < dst_width; x += 4) { + for (size_t y = 0; y < size_t(dst_num_lines); y += 4) { + for (size_t x = 0; x < size_t(dst_width); x += 4) { float fblock[16]; zfp_decode_block_float_2(zfp, fblock); - for (int j = 0; j < 4; j++) { - for (int i = 0; i < 4; i++) { - dst[c * image_size + ((y + j) * dst_width + (x + i))] = + for (size_t j = 0; j < 4; j++) { + for (size_t i = 0; i < 4; i++) { + dst[c * image_size + ((y + j) * size_t(dst_width) + (x + i))] = fblock[j * 4 + i]; } } @@ -9626,31 +9731,33 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines, } // Assume pixel format is FLOAT for all channels. -bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize, - const float *inPtr, int width, int num_lines, int num_channels, - const ZFPCompressionParam ¶m) { +static bool CompressZfp(std::vector<unsigned char> *outBuf, + unsigned int *outSize, const float *inPtr, int width, + int num_lines, int num_channels, + const ZFPCompressionParam ¶m) { zfp_stream *zfp = NULL; zfp_field *field = NULL; assert((width % 4) == 0); assert((num_lines % 4) == 0); - if ((width & 3U) || (num_lines & 3U)) { + if ((size_t(width) & 3U) || (size_t(num_lines) & 3U)) { return false; } // create input array. field = zfp_field_2d(reinterpret_cast<void *>(const_cast<float *>(inPtr)), - zfp_type_float, width, num_lines * num_channels); + zfp_type_float, static_cast<unsigned int>(width), + static_cast<unsigned int>(num_lines * num_channels)); zfp = zfp_stream_open(NULL); if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) { zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0); } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) { - zfp_stream_set_precision(zfp, param.precision, zfp_type_float); + zfp_stream_set_precision(zfp, param.precision); } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) { - zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float); + zfp_stream_set_accuracy(zfp, param.tolerance); } else { assert(0); } @@ -9663,17 +9770,17 @@ bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize, zfp_stream_set_bit_stream(zfp, stream); zfp_field_free(field); - size_t image_size = width * num_lines; + size_t image_size = size_t(width) * size_t(num_lines); - for (int c = 0; c < num_channels; c++) { + for (size_t c = 0; c < size_t(num_channels); c++) { // compress 4x4 pixel block. - for (int y = 0; y < num_lines; y += 4) { - for (int x = 0; x < width; x += 4) { + for (size_t y = 0; y < size_t(num_lines); y += 4) { + for (size_t x = 0; x < size_t(width); x += 4) { float fblock[16]; - for (int j = 0; j < 4; j++) { - for (int i = 0; i < 4; i++) { + for (size_t j = 0; j < 4; j++) { + for (size_t i = 0; i < 4; i++) { fblock[j * 4 + i] = - inPtr[c * image_size + ((y + j) * width + (x + i))]; + inPtr[c * image_size + ((y + j) * size_t(width) + (x + i))]; } } zfp_encode_block_float_2(zfp, fblock); @@ -9682,7 +9789,7 @@ bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize, } zfp_stream_flush(zfp); - (*outSize) = zfp_stream_compressed_size(zfp); + (*outSize) = static_cast<unsigned int>(zfp_stream_compressed_size(zfp)); zfp_stream_close(zfp); @@ -10122,8 +10229,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images, } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { #if TINYEXR_USE_ZFP tinyexr::ZFPCompressionParam zfp_compression_param; - if (!FindZFPCompressionParam(&zfp_compression_param, attributes, - num_attributes)) { + std::string e; + if (!tinyexr::FindZFPCompressionParam(&zfp_compression_param, attributes, + int(num_attributes), &e)) { + // This code path should not be reachable. assert(0); return false; } @@ -10323,8 +10432,11 @@ static bool DecodeTiledPixelData( const EXRAttribute *attributes, size_t num_channels, const EXRChannelInfo *channels, const std::vector<size_t> &channel_offset_list) { - assert(tile_offset_x * tile_size_x < data_width); - assert(tile_offset_y * tile_size_y < data_height); + if (tile_size_x > data_width || tile_size_y > data_height || + tile_size_x * tile_offset_x > data_width || + tile_size_y * tile_offset_y > data_height) { + return false; + } // Compute actual image size in a tile. if ((tile_offset_x + 1) * tile_size_x >= data_width) { @@ -10418,6 +10530,17 @@ static unsigned char **AllocateImage(int num_channels, return images; } +#ifdef _WIN32 +static inline std::wstring UTF8ToWchar(const std::string &str) { + int wstr_size = + MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0); + std::wstring wstr(wstr_size, 0); + MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0], + (int)wstr.size()); + return wstr; +} +#endif + static int ParseEXRHeader(HeaderInfo *info, bool *empty_header, const EXRVersion *version, std::string *err, const unsigned char *buf, size_t size) { @@ -10457,15 +10580,15 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header, bool has_screen_window_center = false; bool has_screen_window_width = false; - info->data_window[0] = 0; - info->data_window[1] = 0; - info->data_window[2] = 0; - info->data_window[3] = 0; + info->data_window.min_x = 0; + info->data_window.min_y = 0; + info->data_window.max_x = 0; + info->data_window.max_y = 0; info->line_order = 0; // @fixme - info->display_window[0] = 0; - info->display_window[1] = 0; - info->display_window[2] = 0; - info->display_window[3] = 0; + info->display_window.min_x = 0; + info->display_window.min_y = 0; + info->display_window.max_x = 0; + info->display_window.max_y = 0; info->screen_window_center[0] = 0.0f; info->screen_window_center[1] = 0.0f; info->screen_window_width = -1.0f; @@ -10515,6 +10638,14 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header, tinyexr::swap4(&x_size); tinyexr::swap4(&y_size); + if (x_size > static_cast<unsigned int>(std::numeric_limits<int>::max()) || + y_size > static_cast<unsigned int>(std::numeric_limits<int>::max())) { + if (err) { + (*err) = "Tile sizes were invalid."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; + } + info->tile_size_x = static_cast<int>(x_size); info->tile_size_y = static_cast<int>(y_size); @@ -10586,30 +10717,26 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header, } else if (attr_name.compare("dataWindow") == 0) { if (data.size() >= 16) { - memcpy(&info->data_window[0], &data.at(0), sizeof(int)); - memcpy(&info->data_window[1], &data.at(4), sizeof(int)); - memcpy(&info->data_window[2], &data.at(8), sizeof(int)); - memcpy(&info->data_window[3], &data.at(12), sizeof(int)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[0])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[1])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[2])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[3])); + memcpy(&info->data_window.min_x, &data.at(0), sizeof(int)); + memcpy(&info->data_window.min_y, &data.at(4), sizeof(int)); + memcpy(&info->data_window.max_x, &data.at(8), sizeof(int)); + memcpy(&info->data_window.max_y, &data.at(12), sizeof(int)); + tinyexr::swap4(&info->data_window.min_x); + tinyexr::swap4(&info->data_window.min_y); + tinyexr::swap4(&info->data_window.max_x); + tinyexr::swap4(&info->data_window.max_y); has_data_window = true; } } else if (attr_name.compare("displayWindow") == 0) { if (data.size() >= 16) { - memcpy(&info->display_window[0], &data.at(0), sizeof(int)); - memcpy(&info->display_window[1], &data.at(4), sizeof(int)); - memcpy(&info->display_window[2], &data.at(8), sizeof(int)); - memcpy(&info->display_window[3], &data.at(12), sizeof(int)); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->display_window[0])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->display_window[1])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->display_window[2])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->display_window[3])); + memcpy(&info->display_window.min_x, &data.at(0), sizeof(int)); + memcpy(&info->display_window.min_y, &data.at(4), sizeof(int)); + memcpy(&info->display_window.max_x, &data.at(8), sizeof(int)); + memcpy(&info->display_window.max_y, &data.at(12), sizeof(int)); + tinyexr::swap4(&info->display_window.min_x); + tinyexr::swap4(&info->display_window.min_y); + tinyexr::swap4(&info->display_window.max_x); + tinyexr::swap4(&info->display_window.max_y); has_display_window = true; } @@ -10621,32 +10748,28 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header, } else if (attr_name.compare("pixelAspectRatio") == 0) { if (data.size() >= sizeof(float)) { memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float)); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->pixel_aspect_ratio)); + tinyexr::swap4(&info->pixel_aspect_ratio); has_pixel_aspect_ratio = true; } } else if (attr_name.compare("screenWindowCenter") == 0) { if (data.size() >= 8) { memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float)); memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float)); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->screen_window_center[0])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->screen_window_center[1])); + tinyexr::swap4(&info->screen_window_center[0]); + tinyexr::swap4(&info->screen_window_center[1]); has_screen_window_center = true; } } else if (attr_name.compare("screenWindowWidth") == 0) { if (data.size() >= sizeof(float)) { memcpy(&info->screen_window_width, &data.at(0), sizeof(float)); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&info->screen_window_width)); + tinyexr::swap4(&info->screen_window_width); has_screen_window_width = true; } } else if (attr_name.compare("chunkCount") == 0) { if (data.size() >= sizeof(int)) { memcpy(&info->chunk_count, &data.at(0), sizeof(int)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->chunk_count)); + tinyexr::swap4(&info->chunk_count); } } else { // Custom attribute(up to TINYEXR_MAX_CUSTOM_ATTRIBUTES) @@ -10732,14 +10855,14 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) { exr_header->screen_window_center[1] = info.screen_window_center[1]; exr_header->screen_window_width = info.screen_window_width; exr_header->chunk_count = info.chunk_count; - exr_header->display_window[0] = info.display_window[0]; - exr_header->display_window[1] = info.display_window[1]; - exr_header->display_window[2] = info.display_window[2]; - exr_header->display_window[3] = info.display_window[3]; - exr_header->data_window[0] = info.data_window[0]; - exr_header->data_window[1] = info.data_window[1]; - exr_header->data_window[2] = info.data_window[2]; - exr_header->data_window[3] = info.data_window[3]; + exr_header->display_window.min_x = info.display_window.min_x; + exr_header->display_window.min_y = info.display_window.min_y; + exr_header->display_window.max_x = info.display_window.max_x; + exr_header->display_window.max_y = info.display_window.max_y; + exr_header->data_window.min_x = info.data_window.min_x; + exr_header->data_window.min_y = info.data_window.min_y; + exr_header->data_window.max_x = info.data_window.max_x; + exr_header->data_window.max_y = info.data_window.max_y; exr_header->line_order = info.line_order; exr_header->compression_type = info.compression_type; @@ -10798,7 +10921,7 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) { memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, 256); exr_header->custom_attributes[i].size = info.attributes[i].size; - // Just copy poiner + // Just copy pointer exr_header->custom_attributes[i].value = info.attributes[i].value; } @@ -10822,21 +10945,30 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, num_scanline_blocks = 32; } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { num_scanline_blocks = 16; - } - int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1; - int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1; +#if TINYEXR_USE_ZFP + tinyexr::ZFPCompressionParam zfp_compression_param; + if (!FindZFPCompressionParam(&zfp_compression_param, + exr_header->custom_attributes, + int(exr_header->num_custom_attributes), err)) { + return TINYEXR_ERROR_INVALID_HEADER; + } +#endif + } - if ((data_width < 0) || (data_height < 0)) { + if (exr_header->data_window.max_x < exr_header->data_window.min_x || + exr_header->data_window.max_y < exr_header->data_window.min_y) { if (err) { - std::stringstream ss; - ss << "Invalid data width or data height: " << data_width << ", " - << data_height << std::endl; - (*err) += ss.str(); + (*err) += "Invalid data window.\n"; } return TINYEXR_ERROR_INVALID_DATA; } + int data_width = + exr_header->data_window.max_x - exr_header->data_window.min_x + 1; + int data_height = + exr_header->data_window.max_y - exr_header->data_window.min_y + 1; + // Do not allow too large data_width and data_height. header invalid? { const int threshold = 1024 * 8192; // heuristics @@ -10938,14 +11070,10 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, int tile_coordinates[4]; memcpy(tile_coordinates, data_ptr, sizeof(int) * 4); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&tile_coordinates[0])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&tile_coordinates[1])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&tile_coordinates[2])); - tinyexr::swap4( - reinterpret_cast<unsigned int *>(&tile_coordinates[3])); + tinyexr::swap4(&tile_coordinates[0]); + tinyexr::swap4(&tile_coordinates[1]); + tinyexr::swap4(&tile_coordinates[2]); + tinyexr::swap4(&tile_coordinates[3]); // @todo{ LoD } if (tile_coordinates[2] != 0) { @@ -10960,7 +11088,7 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, int data_len; memcpy(&data_len, data_ptr + 16, sizeof(int)); // 16 = sizeof(tile_coordinates) - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len)); + tinyexr::swap4(&data_len); if (data_len < 4 || size_t(data_len) > data_size) { // TODO(LTE): atomic @@ -11081,8 +11209,8 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, memcpy(&line_no, data_ptr, sizeof(int)); int data_len; memcpy(&data_len, data_ptr + 4, sizeof(int)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len)); + tinyexr::swap4(&line_no); + tinyexr::swap4(&data_len); if (size_t(data_len) > data_size) { invalid_data = true; @@ -11098,7 +11226,7 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, } else { // line_no may be negative. int end_line_no = (std::min)(line_no + num_scanline_blocks, - (exr_header->data_window[3] + 1)); + (exr_header->data_window.max_y + 1)); int num_lines = end_line_no - line_no; @@ -11113,13 +11241,13 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, // overflow check tinyexr_int64 lno = static_cast<tinyexr_int64>(line_no) - - static_cast<tinyexr_int64>(exr_header->data_window[1]); + static_cast<tinyexr_int64>(exr_header->data_window.min_y); if (lno > std::numeric_limits<int>::max()) { line_no = -1; // invalid } else if (lno < -std::numeric_limits<int>::max()) { line_no = -1; // invalid } else { - line_no -= exr_header->data_window[1]; + line_no -= exr_header->data_window.min_y; } if (line_no < 0) { @@ -11204,8 +11332,8 @@ static bool ReconstructLineOffsets( return false; } - tinyexr::swap4(reinterpret_cast<unsigned int *>(&y)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len)); + tinyexr::swap4(&y); + tinyexr::swap4(&data_len); (*offsets)[i] = offset; @@ -11234,25 +11362,24 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header, num_scanline_blocks = 16; } - int data_width = exr_header->data_window[2] - exr_header->data_window[0]; - if (data_width >= std::numeric_limits<int>::max()) { + if (exr_header->data_window.max_x < exr_header->data_window.min_x || + exr_header->data_window.max_x - exr_header->data_window.min_x == + std::numeric_limits<int>::max()) { // Issue 63 tinyexr::SetErrorMessage("Invalid data width value", err); return TINYEXR_ERROR_INVALID_DATA; } - data_width++; + int data_width = + exr_header->data_window.max_x - exr_header->data_window.min_x + 1; - int data_height = exr_header->data_window[3] - exr_header->data_window[1]; - if (data_height >= std::numeric_limits<int>::max()) { + if (exr_header->data_window.max_y < exr_header->data_window.min_y || + exr_header->data_window.max_y - exr_header->data_window.min_y == + std::numeric_limits<int>::max()) { tinyexr::SetErrorMessage("Invalid data height value", err); return TINYEXR_ERROR_INVALID_DATA; } - data_height++; - - if ((data_width < 0) || (data_height < 0)) { - tinyexr::SetErrorMessage("data width or data height is negative.", err); - return TINYEXR_ERROR_INVALID_DATA; - } + int data_height = + exr_header->data_window.max_y - exr_header->data_window.min_y + 1; // Do not allow too large data_width and data_height. header invalid? { @@ -11275,6 +11402,12 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header, num_blocks = static_cast<size_t>(exr_header->chunk_count); } else if (exr_header->tiled) { // @todo { LoD } + if (exr_header->tile_size_x > data_width || exr_header->tile_size_x < 1 || + exr_header->tile_size_y > data_height || exr_header->tile_size_y < 1) { + tinyexr::SetErrorMessage("tile sizes are invalid.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + size_t num_x_tiles = static_cast<size_t>(data_width) / static_cast<size_t>(exr_header->tile_size_x); if (num_x_tiles * static_cast<size_t>(exr_header->tile_size_x) < @@ -11371,7 +11504,8 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header, } } -static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& layer_names) { +static void GetLayers(const EXRHeader &exr_header, + std::vector<std::string> &layer_names) { // Naive implementation // Group channels by layers // go over all channel names, split by periods @@ -11382,22 +11516,22 @@ static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& lay const size_t pos = full_name.find_last_of('.'); if (pos != std::string::npos && pos != 0 && pos + 1 < full_name.size()) { full_name.erase(pos); - if (std::find(layer_names.begin(), layer_names.end(), full_name) == layer_names.end()) + if (std::find(layer_names.begin(), layer_names.end(), full_name) == + layer_names.end()) layer_names.push_back(full_name); } } } struct LayerChannel { - explicit LayerChannel (size_t i, std::string n) - : index(i) - , name(n) - {} + explicit LayerChannel(size_t i, std::string n) : index(i), name(n) {} size_t index; std::string name; }; -static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer_name, std::vector<LayerChannel>& channels) { +static void ChannelsInLayer(const EXRHeader &exr_header, + const std::string layer_name, + std::vector<LayerChannel> &channels) { channels.clear(); for (int c = 0; c < exr_header.num_channels; c++) { std::string ch_name(exr_header.channels[c].name); @@ -11408,8 +11542,7 @@ static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer } } else { const size_t pos = ch_name.find(layer_name + '.'); - if (pos == std::string::npos) - continue; + if (pos == std::string::npos) continue; if (pos == 0) { ch_name = ch_name.substr(layer_name.size() + 1); } @@ -11421,7 +11554,8 @@ static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer } // namespace tinyexr -int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err) { +int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, + const char **err) { EXRVersion exr_version; EXRHeader exr_header; InitEXRHeader(&exr_header); @@ -11435,8 +11569,8 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, if (exr_version.multipart || exr_version.non_image) { tinyexr::SetErrorMessage( - "Loading multipart or DeepImage is not supported in LoadEXR() API", - err); + "Loading multipart or DeepImage is not supported in LoadEXR() API", + err); return TINYEXR_ERROR_INVALID_DATA; // @fixme. } } @@ -11452,7 +11586,7 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, (*num_layers) = int(layer_vec.size()); (*layer_names) = static_cast<const char **>( - malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size()))); + malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size()))); for (size_t c = 0; c < static_cast<size_t>(layer_vec.size()); c++) { #ifdef _MSC_VER (*layer_names)[c] = _strdup(layer_vec[c].c_str()); @@ -11467,11 +11601,13 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, int LoadEXR(float **out_rgba, int *width, int *height, const char *filename, const char **err) { - return LoadEXRWithLayer(out_rgba, width, height, filename, /* layername */NULL, err); + return LoadEXRWithLayer(out_rgba, width, height, filename, + /* layername */ NULL, err); } -int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *filename, const char *layername, - const char **err) { +int LoadEXRWithLayer(float **out_rgba, int *width, int *height, + const char *filename, const char *layername, + const char **err) { if (out_rgba == NULL) { tinyexr::SetErrorMessage("Invalid argument for LoadEXR()", err); return TINYEXR_ERROR_INVALID_ARGUMENT; @@ -11487,7 +11623,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file int ret = ParseEXRVersionFromFile(&exr_version, filename); if (ret != TINYEXR_SUCCESS) { std::stringstream ss; - ss << "Failed to open EXR file or read version info from EXR file. code(" << ret << ")"; + ss << "Failed to open EXR file or read version info from EXR file. code(" + << ret << ")"; tinyexr::SetErrorMessage(ss.str(), err); return ret; } @@ -11534,7 +11671,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file tinyexr::GetLayers(exr_header, layer_names); std::vector<tinyexr::LayerChannel> channels; - tinyexr::ChannelsInLayer(exr_header, layername == NULL ? "" : std::string(layername), channels); + tinyexr::ChannelsInLayer( + exr_header, layername == NULL ? "" : std::string(layername), channels); if (channels.size() < 1) { tinyexr::SetErrorMessage("Layer Not Found", err); @@ -11549,14 +11687,11 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file if (ch.name == "R") { idxR = int(ch.index); - } - else if (ch.name == "G") { + } else if (ch.name == "G") { idxG = int(ch.index); - } - else if (ch.name == "B") { + } else if (ch.name == "B") { idxB = int(ch.index); - } - else if (ch.name == "A") { + } else if (ch.name == "A") { idxA = int(ch.index); } } @@ -11573,11 +11708,13 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file for (int it = 0; it < exr_image.num_tiles; it++) { for (int j = 0; j < exr_header.tile_size_y; j++) { for (int i = 0; i < exr_header.tile_size_x; i++) { - const int ii = - exr_image.tiles[it].offset_x * exr_header.tile_size_x + i; - const int jj = - exr_image.tiles[it].offset_y * exr_header.tile_size_y + j; - const int idx = ii + jj * exr_image.width; + const int ii = exr_image.tiles[it].offset_x * + static_cast<int>(exr_header.tile_size_x) + + i; + const int jj = exr_image.tiles[it].offset_y * + static_cast<int>(exr_header.tile_size_y) + + j; + const int idx = ii + jj * static_cast<int>(exr_image.width); // out of region check. if (ii >= exr_image.width) { @@ -11601,7 +11738,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file } } else { for (int i = 0; i < exr_image.width * exr_image.height; i++) { - const float val = reinterpret_cast<float **>(exr_image.images)[chIdx][i]; + const float val = + reinterpret_cast<float **>(exr_image.images)[chIdx][i]; (*out_rgba)[4 * i + 0] = val; (*out_rgba)[4 * i + 1] = val; (*out_rgba)[4 * i + 2] = val; @@ -11947,11 +12085,22 @@ int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header, return TINYEXR_ERROR_INVALID_ARGUMENT; } -#ifdef _WIN32 FILE *fp = NULL; - fopen_s(&fp, filename, "rb"); +#ifdef _WIN32 +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t errcode = + _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb"); + if (errcode != 0) { + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); + // TODO(syoyo): return wfopen_s erro code + return TINYEXR_ERROR_CANT_OPEN_FILE; + } #else - FILE *fp = fopen(filename, "rb"); + // Unknown compiler + fp = fopen(filename, "rb"); +#endif +#else + fp = fopen(filename, "rb"); #endif if (!fp) { tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); @@ -12101,7 +12250,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, { int comp = exr_header->compression_type; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&comp)); + tinyexr::swap4(&comp); tinyexr::WriteAttributeToMemory( &memory, "compression", "compression", reinterpret_cast<const unsigned char *>(&comp), 1); @@ -12109,10 +12258,10 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, { int data[4] = {0, 0, exr_image->width - 1, exr_image->height - 1}; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[0])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[1])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[2])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[3])); + tinyexr::swap4(&data[0]); + tinyexr::swap4(&data[1]); + tinyexr::swap4(&data[2]); + tinyexr::swap4(&data[3]); tinyexr::WriteAttributeToMemory( &memory, "dataWindow", "box2i", reinterpret_cast<const unsigned char *>(data), sizeof(int) * 4); @@ -12129,7 +12278,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, { float aspectRatio = 1.0f; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&aspectRatio)); + tinyexr::swap4(&aspectRatio); tinyexr::WriteAttributeToMemory( &memory, "pixelAspectRatio", "float", reinterpret_cast<const unsigned char *>(&aspectRatio), sizeof(float)); @@ -12137,8 +12286,8 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, { float center[2] = {0.0f, 0.0f}; - tinyexr::swap4(reinterpret_cast<unsigned int *>(¢er[0])); - tinyexr::swap4(reinterpret_cast<unsigned int *>(¢er[1])); + tinyexr::swap4(¢er[0]); + tinyexr::swap4(¢er[1]); tinyexr::WriteAttributeToMemory( &memory, "screenWindowCenter", "v2f", reinterpret_cast<const unsigned char *>(center), 2 * sizeof(float)); @@ -12146,7 +12295,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, { float w = static_cast<float>(exr_image->width); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&w)); + tinyexr::swap4(&w); tinyexr::WriteAttributeToMemory(&memory, "screenWindowWidth", "float", reinterpret_cast<const unsigned char *>(&w), sizeof(float)); @@ -12213,9 +12362,10 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, // Use ZFP compression parameter from custom attributes(if such a parameter // exists) { + std::string e; bool ret = tinyexr::FindZFPCompressionParam( &zfp_compression_param, exr_header->custom_attributes, - exr_header->num_custom_attributes); + exr_header->num_custom_attributes, &e); if (!ret) { // Use predefined compression parameter. @@ -12225,7 +12375,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, } #endif - // TOOD(LTE): C++11 thread + // TODO(LTE): C++11 thread // Use signed int since some OpenMP compiler doesn't allow unsigned type for // `parallel for` @@ -12257,7 +12407,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, tinyexr::FP32 f32 = half_to_float(h16); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&f32.f)); + tinyexr::swap4(&f32.f); // line_ptr[x] = f32.f; tinyexr::cpy4(line_ptr + x, &(f32.f)); @@ -12321,7 +12471,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, float val = reinterpret_cast<float **>( exr_image->images)[c][(y + start_y) * exr_image->width + x]; - tinyexr::swap4(reinterpret_cast<unsigned int *>(&val)); + tinyexr::swap4(&val); // line_ptr[x] = val; tinyexr::cpy4(line_ptr + x, &val); @@ -12538,14 +12688,26 @@ int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header, } #endif -#ifdef _WIN32 FILE *fp = NULL; - fopen_s(&fp, filename, "wb"); +#ifdef _WIN32 +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t errcode = + _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"wb"); + if (errcode != 0) { + tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename), + err); + return TINYEXR_ERROR_CANT_WRITE_FILE; + } +#else + // Unknown compiler + fp = fopen(filename, "wb"); +#endif #else - FILE *fp = fopen(filename, "wb"); + fp = fopen(filename, "wb"); #endif if (!fp) { - tinyexr::SetErrorMessage("Cannot write a file", err); + tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename), + err); return TINYEXR_ERROR_CANT_WRITE_FILE; } @@ -12577,10 +12739,21 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { return TINYEXR_ERROR_INVALID_ARGUMENT; } -#ifdef _MSC_VER +#ifdef _WIN32 FILE *fp = NULL; - errno_t errcode = fopen_s(&fp, filename, "rb"); - if ((0 != errcode) || (!fp)) { +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t errcode = + _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb"); + if (errcode != 0) { + tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename), + err); + return TINYEXR_ERROR_CANT_OPEN_FILE; + } +#else + // Unknown compiler + fp = fopen(filename, "rb"); +#endif + if (!fp) { tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename), err); return TINYEXR_ERROR_CANT_OPEN_FILE; @@ -12714,10 +12887,10 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { memcpy(&dy, &data.at(4), sizeof(int)); memcpy(&dw, &data.at(8), sizeof(int)); memcpy(&dh, &data.at(12), sizeof(int)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&dx)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&dy)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&dw)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&dh)); + tinyexr::swap4(&dx); + tinyexr::swap4(&dy); + tinyexr::swap4(&dw); + tinyexr::swap4(&dh); } else if (attr_name.compare("displayWindow") == 0) { int x; @@ -12728,10 +12901,10 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { memcpy(&y, &data.at(4), sizeof(int)); memcpy(&w, &data.at(8), sizeof(int)); memcpy(&h, &data.at(12), sizeof(int)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&x)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&y)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&w)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&h)); + tinyexr::swap4(&x); + tinyexr::swap4(&y); + tinyexr::swap4(&w); + tinyexr::swap4(&h); } } @@ -12819,7 +12992,7 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { memcpy(&unpackedSampleDataSize, data_ptr + 20, sizeof(tinyexr::tinyexr_int64)); - tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no)); + tinyexr::swap4(&line_no); tinyexr::swap8( reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedOffsetTableSize)); tinyexr::swap8( @@ -13054,11 +13227,21 @@ int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version, return TINYEXR_ERROR_INVALID_ARGUMENT; } -#ifdef _WIN32 FILE *fp = NULL; - fopen_s(&fp, filename, "rb"); +#ifdef _WIN32 +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t errcode = + _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb"); + if (errcode != 0) { + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); + return TINYEXR_ERROR_INVALID_FILE; + } #else - FILE *fp = fopen(filename, "rb"); + // Unknown compiler + fp = fopen(filename, "rb"); +#endif +#else + fp = fopen(filename, "rb"); #endif if (!fp) { tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); @@ -13174,11 +13357,21 @@ int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers, return TINYEXR_ERROR_INVALID_ARGUMENT; } -#ifdef _WIN32 FILE *fp = NULL; - fopen_s(&fp, filename, "rb"); +#ifdef _WIN32 +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t errcode = + _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb"); + if (errcode != 0) { + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); + return TINYEXR_ERROR_INVALID_FILE; + } #else - FILE *fp = fopen(filename, "rb"); + // Unknown compiler + fp = fopen(filename, "rb"); +#endif +#else + fp = fopen(filename, "rb"); #endif if (!fp) { tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); @@ -13270,11 +13463,20 @@ int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) { return TINYEXR_ERROR_INVALID_ARGUMENT; } -#ifdef _WIN32 FILE *fp = NULL; - fopen_s(&fp, filename, "rb"); +#ifdef _WIN32 +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t err = _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb"); + if (err != 0) { + // TODO(syoyo): return wfopen_s erro code + return TINYEXR_ERROR_CANT_OPEN_FILE; + } #else - FILE *fp = fopen(filename, "rb"); + // Unknown compiler + fp = fopen(filename, "rb"); +#endif +#else + fp = fopen(filename, "rb"); #endif if (!fp) { return TINYEXR_ERROR_CANT_OPEN_FILE; @@ -13408,11 +13610,21 @@ int LoadEXRMultipartImageFromFile(EXRImage *exr_images, return TINYEXR_ERROR_INVALID_ARGUMENT; } -#ifdef _WIN32 FILE *fp = NULL; - fopen_s(&fp, filename, "rb"); +#ifdef _WIN32 +#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang + errno_t errcode = + _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb"); + if (errcode != 0) { + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); + return TINYEXR_ERROR_CANT_OPEN_FILE; + } #else - FILE *fp = fopen(filename, "rb"); + // Unknown compiler + fp = fopen(filename, "rb"); +#endif +#else + fp = fopen(filename, "rb"); #endif if (!fp) { tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); @@ -13582,5 +13794,5 @@ int SaveEXR(const float *data, int width, int height, int components, #pragma clang diagnostic pop #endif -#endif // TINYEXR_IMPLEMENTATION_DEIFNED +#endif // TINYEXR_IMPLEMENTATION_DEFINED #endif // TINYEXR_IMPLEMENTATION |