diff options
366 files changed, 8312 insertions, 12888 deletions
diff --git a/.clang-tidy b/.clang-tidy index 366781cc82..1eb974f3f8 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,14 +1,12 @@ ---- -Checks: >- - -*, - cppcoreguidelines-pro-type-member-init, - modernize-redundant-void-arg, - modernize-use-bool-literals, - modernize-use-default-member-init, - modernize-use-nullptr, - readability-braces-around-statements, - readability-redundant-member-init -WarningsAsErrors: '' +Checks: + - -* + - cppcoreguidelines-pro-type-member-init + - modernize-redundant-void-arg + - modernize-use-bool-literals + - modernize-use-default-member-init + - modernize-use-nullptr + - readability-braces-around-statements + - readability-redundant-member-init HeaderFileExtensions: ['', h, hh, hpp, hxx, inc, glsl] ImplementationFileExtensions: [c, cc, cpp, cxx, m, mm, java] HeaderFilterRegex: (core|doc|drivers|editor|main|modules|platform|scene|servers|tests)/ @@ -19,4 +17,3 @@ CheckOptions: modernize-use-bool-literals.IgnoreMacros: false modernize-use-default-member-init.IgnoreMacros: false modernize-use-default-member-init.UseAssignment: true -... diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index df5fd1beed..f149078d5d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -60,3 +60,6 @@ b37fc1014abf7adda70dc30b0822d775b3a4433f # Set clang-format `RemoveSemicolon` rule to `true` 0d350e71086fffce0553811739aae9f6ad66136c + +# Style: Apply clang-tidy fixes (superficial) +bb5f390fb9b466be35a5df7651323d7e66afca31 diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 348e2bb317..dc3d9f3786 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -106,7 +106,7 @@ jobs: # TODO: Figure out somehow how to embed this one. - name: wayland-scanner dependency run: | - sudo apt-get install libwayland-bin libegl-dev + sudo apt-get install libwayland-bin - name: Free disk space on runner run: | diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml index 8e30c99fbc..ec57fa2f0d 100644 --- a/.github/workflows/web_builds.yml +++ b/.github/workflows/web_builds.yml @@ -8,7 +8,6 @@ env: GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no use_closure_compiler=yes strict_checks=yes EM_VERSION: 3.1.64 - EM_CACHE_FOLDER: emsdk-cache concurrency: group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-web @@ -46,8 +45,7 @@ jobs: uses: mymindstorm/setup-emsdk@v14 with: version: ${{ env.EM_VERSION }} - actions-cache-folder: ${{ env.EM_CACHE_FOLDER }} - cache-key: emsdk-${{ matrix.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }} + no-cache: true - name: Verify Emscripten setup run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 29263f07ee..d81c1043a7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ exclude: | repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v19.1.0 + rev: v19.1.3 hooks: - id: clang-format files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java)$ @@ -22,7 +22,7 @@ repos: ) - id: clang-format name: clang-format-glsl - files: \.(glsl)$ + files: \.glsl$ types_or: [text] exclude: | (?x)^( @@ -30,7 +30,7 @@ repos: platform/android/java/editor/src/main/java/com/android/.*| platform/android/java/lib/src/com/.* ) - args: ["-style=file:misc/utility/.clang-format-glsl"] + args: ['-style=file:misc/utility/.clang-format-glsl'] - repo: https://github.com/pocc/pre-commit-hooks rev: v1.3.5 @@ -45,7 +45,7 @@ repos: platform/android/java/editor/src/main/java/com/android/.*| platform/android/java/lib/src/com/.* ) - additional_dependencies: [clang-tidy==18.1.1] + additional_dependencies: [clang-tidy==19.1.0] require_serial: true stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy` diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 5555e86541..2ece06eebb 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -432,7 +432,7 @@ License: BSD-3-clause Files: ./thirdparty/misc/smolv.cpp ./thirdparty/misc/smolv.h Comment: SMOL-V -Copyright: 2016-2020, Aras Pranckevicius +Copyright: 2016-2024, Aras Pranckevicius License: public-domain or Unlicense or Expat Files: ./thirdparty/misc/stb_rect_pack.h diff --git a/SConstruct b/SConstruct index 49278070ae..ee34d421e0 100644 --- a/SConstruct +++ b/SConstruct @@ -851,6 +851,7 @@ if env.msvc and not methods.using_clang(env): # MSVC "/wd4245", "/wd4267", "/wd4305", # C4305 (truncation): double to float or real_t, too hard to avoid. + "/wd4324", # C4820 (structure was padded due to alignment specifier) "/wd4514", # C4514 (unreferenced inline function has been removed) "/wd4714", # C4714 (function marked as __forceinline not inlined) "/wd4820", # C4820 (padding added after construct) diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp index f4283e0ea9..cc36ca4816 100644 --- a/core/debugger/debugger_marshalls.cpp +++ b/core/debugger/debugger_marshalls.cpp @@ -147,3 +147,37 @@ bool DebuggerMarshalls::OutputError::deserialize(const Array &p_arr) { CHECK_END(p_arr, idx, "OutputError"); return true; } + +Array DebuggerMarshalls::serialize_key_shortcut(const Ref<Shortcut> &p_shortcut) { + ERR_FAIL_COND_V(p_shortcut.is_null(), Array()); + Array keys; + for (const Ref<InputEvent> ev : p_shortcut->get_events()) { + const Ref<InputEventKey> kev = ev; + ERR_CONTINUE(kev.is_null()); + if (kev->get_physical_keycode() != Key::NONE) { + keys.push_back(true); + keys.push_back(kev->get_physical_keycode_with_modifiers()); + } else { + keys.push_back(false); + keys.push_back(kev->get_keycode_with_modifiers()); + } + } + return keys; +} + +Ref<Shortcut> DebuggerMarshalls::deserialize_key_shortcut(const Array &p_keys) { + Array key_events; + ERR_FAIL_COND_V(p_keys.size() % 2 != 0, Ref<Shortcut>()); + for (int i = 0; i < p_keys.size(); i += 2) { + ERR_CONTINUE(p_keys[i].get_type() != Variant::BOOL); + ERR_CONTINUE(p_keys[i + 1].get_type() != Variant::INT); + key_events.push_back(InputEventKey::create_reference((Key)p_keys[i + 1].operator int(), p_keys[i].operator bool())); + } + if (key_events.is_empty()) { + return Ref<Shortcut>(); + } + Ref<Shortcut> shortcut; + shortcut.instantiate(); + shortcut->set_events(key_events); + return shortcut; +} diff --git a/core/debugger/debugger_marshalls.h b/core/debugger/debugger_marshalls.h index 1b81623688..1072ddaeb7 100644 --- a/core/debugger/debugger_marshalls.h +++ b/core/debugger/debugger_marshalls.h @@ -31,6 +31,7 @@ #ifndef DEBUGGER_MARSHALLS_H #define DEBUGGER_MARSHALLS_H +#include "core/input/shortcut.h" #include "core/object/script_language.h" struct DebuggerMarshalls { @@ -68,6 +69,9 @@ struct DebuggerMarshalls { Array serialize(); bool deserialize(const Array &p_arr); }; + + static Array serialize_key_shortcut(const Ref<Shortcut> &p_shortcut); + static Ref<Shortcut> deserialize_key_shortcut(const Array &p_keys); }; #endif // DEBUGGER_MARSHALLS_H diff --git a/core/input/input.cpp b/core/input/input.cpp index 4117193c8b..7e2227c729 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -1034,7 +1034,7 @@ void Input::action_release(const StringName &p_action) { // Create or retrieve existing action. ActionState &action_state = action_states[p_action]; - action_state.cache.pressed = 0; + action_state.cache.pressed = false; action_state.cache.strength = 0.0; action_state.cache.raw_strength = 0.0; // As input may come in part way through a physics tick, the earliest we can react to it is the next physics tick. diff --git a/core/io/missing_resource.cpp b/core/io/missing_resource.cpp index c78195bc46..1c15cc7dd3 100644 --- a/core/io/missing_resource.cpp +++ b/core/io/missing_resource.cpp @@ -74,6 +74,10 @@ bool MissingResource::is_recording_properties() const { return recording_properties; } +String MissingResource::get_save_class() const { + return original_class; +} + void MissingResource::_bind_methods() { ClassDB::bind_method(D_METHOD("set_original_class", "name"), &MissingResource::set_original_class); ClassDB::bind_method(D_METHOD("get_original_class"), &MissingResource::get_original_class); diff --git a/core/io/missing_resource.h b/core/io/missing_resource.h index f32d818ccb..4cded5ca24 100644 --- a/core/io/missing_resource.h +++ b/core/io/missing_resource.h @@ -57,6 +57,8 @@ public: void set_recording_properties(bool p_enable); bool is_recording_properties() const; + virtual String get_save_class() const override; + MissingResource(); }; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 8bfa91a220..e6136603d4 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -833,7 +833,7 @@ Error ResourceLoaderBinary::load() { } bool set_valid = true; - if (value.get_type() == Variant::OBJECT && missing_resource != nullptr) { + if (value.get_type() == Variant::OBJECT && missing_resource == nullptr && ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) { // If the property being set is a missing resource (and the parent is not), // then setting it will most likely not work. // Instead, save it as metadata. @@ -2225,10 +2225,10 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re List<ResourceData> resources; - Dictionary missing_resource_properties = p_resource->get_meta(META_MISSING_RESOURCES, Dictionary()); - { for (const Ref<Resource> &E : saved_resources) { + Dictionary missing_resource_properties = E->get_meta(META_MISSING_RESOURCES, Dictionary()); + ResourceData &rd = resources.push_back(ResourceData())->get(); rd.type = _resource_get_class(E); @@ -2243,7 +2243,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re continue; } - if ((F.usage & PROPERTY_USAGE_STORAGE)) { + if ((F.usage & PROPERTY_USAGE_STORAGE) || missing_resource_properties.has(F.name)) { Property p; p.name_idx = get_string_index(F.name); @@ -2258,7 +2258,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re p.value = E->get(F.name); } - if (p.pi.type == Variant::OBJECT && missing_resource_properties.has(F.name)) { + if (F.type == Variant::OBJECT && missing_resource_properties.has(F.name)) { // Was this missing resource overridden? If so do not save the old value. Ref<Resource> res = p.value; if (res.is_null()) { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 221f38494b..3ca8f7c05d 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -148,7 +148,7 @@ public: virtual String get_option_group_file() const { return String(); } virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0; - virtual bool can_import_threaded() const { return true; } + virtual bool can_import_threaded() const { return false; } virtual void import_threaded_begin() {} virtual void import_threaded_end() {} diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index c8c7d430cc..59de2879e2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -282,13 +282,13 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin load_paths_stack.push_back(original_path); // Try all loaders and pick the first match for the type hint - bool found = false; + bool loader_found = false; Ref<Resource> res; for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(p_path, p_type_hint)) { continue; } - found = true; + loader_found = true; res = loader[i]->load(p_path, original_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); if (!res.is_null()) { break; @@ -303,15 +303,24 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin return res; } - ERR_FAIL_COND_V_MSG(found, Ref<Resource>(), - vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path)); + if (!loader_found) { + if (r_error) { + *r_error = ERR_FILE_UNRECOGNIZED; + } + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("No loader found for resource: %s (expected type: %s)", p_path, p_type_hint)); + } #ifdef TOOLS_ENABLED Ref<FileAccess> file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES); - ERR_FAIL_COND_V_MSG(!file_check->file_exists(p_path), Ref<Resource>(), vformat("Resource file not found: %s (expected type: %s)", p_path, p_type_hint)); + if (!file_check->file_exists(p_path)) { + if (r_error) { + *r_error = ERR_FILE_NOT_FOUND; + } + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Resource file not found: %s (expected type: %s)", p_path, p_type_hint)); + } #endif - ERR_FAIL_V_MSG(Ref<Resource>(), vformat("No loader found for resource: %s (expected type: %s)", p_path, p_type_hint)); + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path)); } // This implementation must allow re-entrancy for a task that started awaiting in a deeper stack frame. diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index bad224eff4..d48e1a3622 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -750,69 +750,87 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & } bool ClassDB::can_instantiate(const StringName &p_class) { - OBJTYPE_RLOCK; + String script_path; + { + OBJTYPE_RLOCK; - ClassInfo *ti = classes.getptr(p_class); - if (!ti) { - if (!ScriptServer::is_global_class(p_class)) { - ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); + ClassInfo *ti = classes.getptr(p_class); + if (!ti) { + if (!ScriptServer::is_global_class(p_class)) { + ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); + } + script_path = ScriptServer::get_global_class_path(p_class); + goto use_script; // Open the lock for resource loading. } - String path = ScriptServer::get_global_class_path(p_class); - Ref<Script> scr = ResourceLoader::load(path); - return scr.is_valid() && scr->is_valid() && !scr->is_abstract(); - } #ifdef TOOLS_ENABLED - if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) { - return false; - } + if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) { + return false; + } #endif - return _can_instantiate(ti); + return _can_instantiate(ti); + } + +use_script: + Ref<Script> scr = ResourceLoader::load(script_path); + return scr.is_valid() && scr->is_valid() && !scr->is_abstract(); } bool ClassDB::is_abstract(const StringName &p_class) { - OBJTYPE_RLOCK; + String script_path; + { + OBJTYPE_RLOCK; - ClassInfo *ti = classes.getptr(p_class); - if (!ti) { - if (!ScriptServer::is_global_class(p_class)) { - ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); + ClassInfo *ti = classes.getptr(p_class); + if (!ti) { + if (!ScriptServer::is_global_class(p_class)) { + ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); + } + script_path = ScriptServer::get_global_class_path(p_class); + goto use_script; // Open the lock for resource loading. } - String path = ScriptServer::get_global_class_path(p_class); - Ref<Script> scr = ResourceLoader::load(path); - return scr.is_valid() && scr->is_valid() && scr->is_abstract(); - } - if (ti->creation_func != nullptr) { - return false; - } - if (!ti->gdextension) { - return true; - } + if (ti->creation_func != nullptr) { + return false; + } + if (!ti->gdextension) { + return true; + } #ifndef DISABLE_DEPRECATED - return ti->gdextension->create_instance2 == nullptr && ti->gdextension->create_instance == nullptr; + return ti->gdextension->create_instance2 == nullptr && ti->gdextension->create_instance == nullptr; #else - return ti->gdextension->create_instance2 == nullptr; + return ti->gdextension->create_instance2 == nullptr; #endif // DISABLE_DEPRECATED + } + +use_script: + Ref<Script> scr = ResourceLoader::load(script_path); + return scr.is_valid() && scr->is_valid() && scr->is_abstract(); } bool ClassDB::is_virtual(const StringName &p_class) { - OBJTYPE_RLOCK; + String script_path; + { + OBJTYPE_RLOCK; - ClassInfo *ti = classes.getptr(p_class); - if (!ti) { - if (!ScriptServer::is_global_class(p_class)) { - ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); + ClassInfo *ti = classes.getptr(p_class); + if (!ti) { + if (!ScriptServer::is_global_class(p_class)) { + ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); + } + script_path = ScriptServer::get_global_class_path(p_class); + goto use_script; // Open the lock for resource loading. } - String path = ScriptServer::get_global_class_path(p_class); - Ref<Script> scr = ResourceLoader::load(path); - return scr.is_valid() && scr->is_valid() && scr->is_abstract(); - } #ifdef TOOLS_ENABLED - if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) { - return false; - } + if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) { + return false; + } #endif - return (_can_instantiate(ti) && ti->is_virtual); + return (_can_instantiate(ti) && ti->is_virtual); + } + +use_script: + Ref<Script> scr = ResourceLoader::load(script_path); + return scr.is_valid() && scr->is_valid() && scr->is_abstract(); } void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { diff --git a/core/object/message_queue.h b/core/object/message_queue.h index 673eb3845b..64e244bda8 100644 --- a/core/object/message_queue.h +++ b/core/object/message_queue.h @@ -153,7 +153,7 @@ public: bool is_flushing() const; int get_max_buffer_usage() const; - CallQueue(Allocator *p_custom_allocator = 0, uint32_t p_max_pages = 8192, const String &p_error_text = String()); + CallQueue(Allocator *p_custom_allocator = nullptr, uint32_t p_max_pages = 8192, const String &p_error_text = String()); virtual ~CallQueue(); }; diff --git a/core/os/spin_lock.h b/core/os/spin_lock.h index d386cd5890..8c2d5667ff 100644 --- a/core/os/spin_lock.h +++ b/core/os/spin_lock.h @@ -33,6 +33,10 @@ #include "core/typedefs.h" +#ifdef _MSC_VER +#include <intrin.h> +#endif + #if defined(__APPLE__) #include <os/lock.h> @@ -52,19 +56,52 @@ public: #else +#include "core/os/thread.h" + #include <atomic> -class SpinLock { - mutable std::atomic_flag locked = ATOMIC_FLAG_INIT; +_ALWAYS_INLINE_ static void _cpu_pause() { +#if defined(_MSC_VER) +// ----- MSVC. +#if defined(_M_ARM) || defined(_M_ARM64) // ARM. + __yield(); +#elif defined(_M_IX86) || defined(_M_X64) // x86. + _mm_pause(); +#endif +#elif defined(__GNUC__) || defined(__clang__) +// ----- GCC/Clang. +#if defined(__i386__) || defined(__x86_64__) // x86. + __builtin_ia32_pause(); +#elif defined(__arm__) || defined(__aarch64__) // ARM. + asm volatile("yield"); +#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) // PowerPC. + asm volatile("or 27,27,27"); +#elif defined(__riscv) // RISC-V. + asm volatile(".insn i 0x0F, 0, x0, x0, 0x010"); +#endif +#endif +} + +static_assert(std::atomic_bool::is_always_lock_free); + +class alignas(Thread::CACHE_LINE_BYTES) SpinLock { + mutable std::atomic<bool> locked = ATOMIC_VAR_INIT(false); public: _ALWAYS_INLINE_ void lock() const { - while (locked.test_and_set(std::memory_order_acquire)) { - // Continue. + while (true) { + bool expected = false; + if (locked.compare_exchange_weak(expected, true, std::memory_order_acquire, std::memory_order_relaxed)) { + break; + } + do { + _cpu_pause(); + } while (locked.load(std::memory_order_relaxed)); } } + _ALWAYS_INLINE_ void unlock() const { - locked.clear(std::memory_order_release); + locked.store(false, std::memory_order_release); } }; diff --git a/core/os/thread.h b/core/os/thread.h index a0ecc24c91..1c442b41f6 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -42,6 +42,8 @@ #include "core/templates/safe_refcount.h" #include "core/typedefs.h" +#include <new> + #ifdef MINGW_ENABLED #define MINGW_STDTHREAD_REDUNDANCY_WARNING #include "thirdparty/mingw-std-threads/mingw.thread.h" @@ -85,6 +87,20 @@ public: void (*term)() = nullptr; }; +#if defined(__cpp_lib_hardware_interference_size) && !defined(ANDROID_ENABLED) // This would be OK with NDK >= 26. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winterference-size" +#endif + static constexpr size_t CACHE_LINE_BYTES = std::hardware_destructive_interference_size; +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif +#else + // At a negligible memory cost, we use a conservatively high value. + static constexpr size_t CACHE_LINE_BYTES = 128; +#endif + private: friend class Main; @@ -135,6 +151,8 @@ public: typedef uint64_t ID; + static constexpr size_t CACHE_LINE_BYTES = sizeof(void *); + enum : ID { UNASSIGNED_ID = 0, MAIN_ID = 1 diff --git a/core/string/fuzzy_search.cpp b/core/string/fuzzy_search.cpp new file mode 100644 index 0000000000..2fd0d3995e --- /dev/null +++ b/core/string/fuzzy_search.cpp @@ -0,0 +1,349 @@ +/**************************************************************************/ +/* fuzzy_search.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "fuzzy_search.h" + +constexpr float cull_factor = 0.1f; +constexpr float cull_cutoff = 30.0f; +const String boundary_chars = "/\\-_."; + +static bool _is_valid_interval(const Vector2i &p_interval) { + // Empty intervals are represented as (-1, -1). + return p_interval.x >= 0 && p_interval.y >= p_interval.x; +} + +static Vector2i _extend_interval(const Vector2i &p_a, const Vector2i &p_b) { + if (!_is_valid_interval(p_a)) { + return p_b; + } + if (!_is_valid_interval(p_b)) { + return p_a; + } + return Vector2i(MIN(p_a.x, p_b.x), MAX(p_a.y, p_b.y)); +} + +static bool _is_word_boundary(const String &p_str, int p_index) { + if (p_index == -1 || p_index == p_str.size()) { + return true; + } + return boundary_chars.find_char(p_str[p_index]) != -1; +} + +bool FuzzySearchToken::try_exact_match(FuzzyTokenMatch &p_match, const String &p_target, int p_offset) const { + p_match.token_idx = idx; + p_match.token_length = string.length(); + int match_idx = p_target.find(string, p_offset); + if (match_idx == -1) { + return false; + } + p_match.add_substring(match_idx, string.length()); + return true; +} + +bool FuzzySearchToken::try_fuzzy_match(FuzzyTokenMatch &p_match, const String &p_target, int p_offset, int p_miss_budget) const { + p_match.token_idx = idx; + p_match.token_length = string.length(); + int run_start = -1; + int run_len = 0; + + // Search for the subsequence p_token in p_target starting from p_offset, recording each substring for + // later scoring and display. + for (int i = 0; i < string.length(); i++) { + int new_offset = p_target.find_char(string[i], p_offset); + if (new_offset < 0) { + p_miss_budget--; + if (p_miss_budget < 0) { + return false; + } + } else { + if (run_start == -1 || p_offset != new_offset) { + if (run_start != -1) { + p_match.add_substring(run_start, run_len); + } + run_start = new_offset; + run_len = 1; + } else { + run_len += 1; + } + p_offset = new_offset + 1; + } + } + + if (run_start != -1) { + p_match.add_substring(run_start, run_len); + } + + return true; +} + +void FuzzyTokenMatch::add_substring(int p_substring_start, int p_substring_length) { + substrings.append(Vector2i(p_substring_start, p_substring_length)); + matched_length += p_substring_length; + Vector2i substring_interval = { p_substring_start, p_substring_start + p_substring_length - 1 }; + interval = _extend_interval(interval, substring_interval); +} + +bool FuzzyTokenMatch::intersects(const Vector2i &p_other_interval) const { + if (!_is_valid_interval(interval) || !_is_valid_interval(p_other_interval)) { + return false; + } + return interval.y >= p_other_interval.x && interval.x <= p_other_interval.y; +} + +bool FuzzySearchResult::can_add_token_match(const FuzzyTokenMatch &p_match) const { + if (p_match.get_miss_count() > miss_budget) { + return false; + } + + if (p_match.intersects(match_interval)) { + if (token_matches.size() == 1) { + return false; + } + for (const FuzzyTokenMatch &existing_match : token_matches) { + if (existing_match.intersects(p_match.interval)) { + return false; + } + } + } + + return true; +} + +bool FuzzyTokenMatch::is_case_insensitive(const String &p_original, const String &p_adjusted) const { + for (const Vector2i &substr : substrings) { + const int end = substr.x + substr.y; + for (int i = substr.x; i < end; i++) { + if (p_original[i] != p_adjusted[i]) { + return true; + } + } + } + return false; +} + +void FuzzySearchResult::score_token_match(FuzzyTokenMatch &p_match, bool p_case_insensitive) const { + // This can always be tweaked more. The intuition is that exact matches should almost always + // be prioritized over broken up matches, and other criteria more or less act as tie breakers. + + p_match.score = -20 * p_match.get_miss_count() - (p_case_insensitive ? 3 : 0); + + for (const Vector2i &substring : p_match.substrings) { + // Score longer substrings higher than short substrings. + int substring_score = substring.y * substring.y; + // Score matches deeper in path higher than shallower matches + if (substring.x > dir_index) { + substring_score *= 2; + } + // Score matches on a word boundary higher than matches within a word + if (_is_word_boundary(target, substring.x - 1) || _is_word_boundary(target, substring.x + substring.y)) { + substring_score += 4; + } + // Score exact query matches higher than non-compact subsequence matches + if (substring.y == p_match.token_length) { + substring_score += 100; + } + p_match.score += substring_score; + } +} + +void FuzzySearchResult::maybe_apply_score_bonus() { + // This adds a small bonus to results which match tokens in the same order they appear in the query. + int *token_range_starts = (int *)alloca(sizeof(int) * token_matches.size()); + + for (const FuzzyTokenMatch &match : token_matches) { + token_range_starts[match.token_idx] = match.interval.x; + } + + int last = token_range_starts[0]; + for (int i = 1; i < token_matches.size(); i++) { + if (last > token_range_starts[i]) { + return; + } + last = token_range_starts[i]; + } + + score += 1; +} + +void FuzzySearchResult::add_token_match(const FuzzyTokenMatch &p_match) { + score += p_match.score; + match_interval = _extend_interval(match_interval, p_match.interval); + miss_budget -= p_match.get_miss_count(); + token_matches.append(p_match); +} + +void remove_low_scores(Vector<FuzzySearchResult> &p_results, float p_cull_score) { + // Removes all results with score < p_cull_score in-place. + int i = 0; + int j = p_results.size() - 1; + FuzzySearchResult *results = p_results.ptrw(); + + while (true) { + // Advances i to an element to remove and j to an element to keep. + while (j >= i && results[j].score < p_cull_score) { + j--; + } + while (i < j && results[i].score >= p_cull_score) { + i++; + } + if (i >= j) { + break; + } + results[i++] = results[j--]; + } + + p_results.resize(j + 1); +} + +void FuzzySearch::sort_and_filter(Vector<FuzzySearchResult> &p_results) const { + if (p_results.is_empty()) { + return; + } + + float avg_score = 0; + float max_score = 0; + + for (const FuzzySearchResult &result : p_results) { + avg_score += result.score; + max_score = MAX(max_score, result.score); + } + + // TODO: Tune scoring and culling here to display fewer subsequence soup matches when good matches + // are available. + avg_score /= p_results.size(); + float cull_score = MIN(cull_cutoff, Math::lerp(avg_score, max_score, cull_factor)); + remove_low_scores(p_results, cull_score); + + struct FuzzySearchResultComparator { + bool operator()(const FuzzySearchResult &p_lhs, const FuzzySearchResult &p_rhs) const { + // Sort on (score, length, alphanumeric) to ensure consistent ordering. + if (p_lhs.score == p_rhs.score) { + if (p_lhs.target.length() == p_rhs.target.length()) { + return p_lhs.target < p_rhs.target; + } + return p_lhs.target.length() < p_rhs.target.length(); + } + return p_lhs.score > p_rhs.score; + } + }; + + SortArray<FuzzySearchResult, FuzzySearchResultComparator> sorter; + + if (p_results.size() > max_results) { + sorter.partial_sort(0, p_results.size(), max_results, p_results.ptrw()); + p_results.resize(max_results); + } else { + sorter.sort(p_results.ptrw(), p_results.size()); + } +} + +void FuzzySearch::set_query(const String &p_query) { + tokens.clear(); + for (const String &string : p_query.split(" ", false)) { + tokens.append({ static_cast<int>(tokens.size()), string }); + } + + case_sensitive = !p_query.is_lowercase(); + + struct TokenComparator { + bool operator()(const FuzzySearchToken &A, const FuzzySearchToken &B) const { + if (A.string.length() == B.string.length()) { + return A.idx < B.idx; + } + return A.string.length() > B.string.length(); + } + }; + + // Prioritize matching longer tokens before shorter ones since match overlaps are not accepted. + tokens.sort_custom<TokenComparator>(); +} + +bool FuzzySearch::search(const String &p_target, FuzzySearchResult &p_result) const { + p_result.target = p_target; + p_result.dir_index = p_target.rfind_char('/'); + p_result.miss_budget = max_misses; + + String adjusted_target = case_sensitive ? p_target : p_target.to_lower(); + + // For each token, eagerly generate subsequences starting from index 0 and keep the best scoring one + // which does not conflict with prior token matches. This is not ensured to find the highest scoring + // combination of matches, or necessarily the highest scoring single subsequence, as it only considers + // eager subsequences for a given index, and likewise eagerly finds matches for each token in sequence. + for (const FuzzySearchToken &token : tokens) { + FuzzyTokenMatch best_match; + int offset = start_offset; + + while (true) { + FuzzyTokenMatch match; + if (allow_subsequences) { + if (!token.try_fuzzy_match(match, adjusted_target, offset, p_result.miss_budget)) { + break; + } + } else { + if (!token.try_exact_match(match, adjusted_target, offset)) { + break; + } + } + if (p_result.can_add_token_match(match)) { + p_result.score_token_match(match, match.is_case_insensitive(p_target, adjusted_target)); + if (best_match.token_idx == -1 || best_match.score < match.score) { + best_match = match; + } + } + if (_is_valid_interval(match.interval)) { + offset = match.interval.x + 1; + } else { + break; + } + } + + if (best_match.token_idx == -1) { + return false; + } + + p_result.add_token_match(best_match); + } + + p_result.maybe_apply_score_bonus(); + return true; +} + +void FuzzySearch::search_all(const PackedStringArray &p_targets, Vector<FuzzySearchResult> &p_results) const { + p_results.clear(); + + for (const String &target : p_targets) { + FuzzySearchResult result; + if (search(target, result)) { + p_results.append(result); + } + } + + sort_and_filter(p_results); +} diff --git a/core/string/fuzzy_search.h b/core/string/fuzzy_search.h new file mode 100644 index 0000000000..5d8ed813c7 --- /dev/null +++ b/core/string/fuzzy_search.h @@ -0,0 +1,101 @@ +/**************************************************************************/ +/* fuzzy_search.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 FUZZY_SEARCH_H +#define FUZZY_SEARCH_H + +#include "core/variant/variant.h" + +class FuzzyTokenMatch; + +struct FuzzySearchToken { + int idx = -1; + String string; + + bool try_exact_match(FuzzyTokenMatch &p_match, const String &p_target, int p_offset) const; + bool try_fuzzy_match(FuzzyTokenMatch &p_match, const String &p_target, int p_offset, int p_miss_budget) const; +}; + +class FuzzyTokenMatch { + friend struct FuzzySearchToken; + friend class FuzzySearchResult; + friend class FuzzySearch; + + int matched_length = 0; + int token_length = 0; + int token_idx = -1; + Vector2i interval = Vector2i(-1, -1); // x and y are both inclusive indices. + + void add_substring(int p_substring_start, int p_substring_length); + bool intersects(const Vector2i &p_other_interval) const; + bool is_case_insensitive(const String &p_original, const String &p_adjusted) const; + int get_miss_count() const { return token_length - matched_length; } + +public: + int score = 0; + Vector<Vector2i> substrings; // x is start index, y is length. +}; + +class FuzzySearchResult { + friend class FuzzySearch; + + int miss_budget = 0; + Vector2i match_interval = Vector2i(-1, -1); + + bool can_add_token_match(const FuzzyTokenMatch &p_match) const; + void score_token_match(FuzzyTokenMatch &p_match, bool p_case_insensitive) const; + void add_token_match(const FuzzyTokenMatch &p_match); + void maybe_apply_score_bonus(); + +public: + String target; + int score = 0; + int dir_index = -1; + Vector<FuzzyTokenMatch> token_matches; +}; + +class FuzzySearch { + Vector<FuzzySearchToken> tokens; + + void sort_and_filter(Vector<FuzzySearchResult> &p_results) const; + +public: + int start_offset = 0; + bool case_sensitive = false; + int max_results = 100; + int max_misses = 2; + bool allow_subsequences = true; + + void set_query(const String &p_query); + bool search(const String &p_target, FuzzySearchResult &p_result) const; + void search_all(const PackedStringArray &p_targets, Vector<FuzzySearchResult> &p_results) const; +}; + +#endif // FUZZY_SEARCH_H diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index a78f0ff5ff..521dfe0b8c 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3387,7 +3387,7 @@ int String::find(const char *p_str, int p_from) const { return -1; } -int String::find_char(const char32_t &p_char, int p_from) const { +int String::find_char(char32_t p_char, int p_from) const { return _cowdata.find(p_char, p_from); } @@ -3624,6 +3624,10 @@ int String::rfind(const char *p_str, int p_from) const { return -1; } +int String::rfind_char(char32_t p_char, int p_from) const { + return _cowdata.rfind(p_char, p_from); +} + int String::rfindn(const String &p_str, int p_from) const { // establish a limit int limit = length() - p_str.length(); @@ -3837,6 +3841,15 @@ bool String::is_quoted() const { return is_enclosed_in("\"") || is_enclosed_in("'"); } +bool String::is_lowercase() const { + for (const char32_t *str = &operator[](0); *str; str++) { + if (is_unicode_upper_case(*str)) { + return false; + } + } + return true; +} + int String::_count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const { if (p_string.is_empty()) { return 0; diff --git a/core/string/ustring.h b/core/string/ustring.h index 11d187beb4..d6e563223a 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -287,11 +287,12 @@ public: String substr(int p_from, int p_chars = -1) const; int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed - int find_char(const char32_t &p_char, int p_from = 0) const; ///< return <0 if failed + int find_char(char32_t p_char, int p_from = 0) const; ///< return <0 if failed int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive int findn(const char *p_str, int p_from = 0) const; ///< return <0 if failed int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed int rfind(const char *p_str, int p_from = -1) const; ///< return <0 if failed + int rfind_char(char32_t p_char, int p_from = -1) const; ///< return <0 if failed int rfindn(const String &p_str, int p_from = -1) const; ///< return <0 if failed, case insensitive int rfindn(const char *p_str, int p_from = -1) const; ///< return <0 if failed int findmk(const Vector<String> &p_keys, int p_from = 0, int *r_key = nullptr) const; ///< return <0 if failed @@ -305,6 +306,7 @@ public: bool is_subsequence_of(const String &p_string) const; bool is_subsequence_ofn(const String &p_string) const; bool is_quoted() const; + bool is_lowercase() const; Vector<String> bigrams() const; float similarity(const String &p_string) const; String format(const Variant &values, const String &placeholder = "{_}") const; diff --git a/core/templates/list.h b/core/templates/list.h index 6663f06c30..02afeec74d 100644 --- a/core/templates/list.h +++ b/core/templates/list.h @@ -224,7 +224,7 @@ private: Element *last = nullptr; int size_cache = 0; - bool erase(const Element *p_I) { + bool erase(Element *p_I) { ERR_FAIL_NULL_V(p_I, false); ERR_FAIL_COND_V(p_I->data != this, false); @@ -244,7 +244,7 @@ private: p_I->next_ptr->prev_ptr = p_I->prev_ptr; } - memdelete_allocator<Element, A>(const_cast<Element *>(p_I)); + memdelete_allocator<Element, A>(p_I); size_cache--; return true; @@ -430,7 +430,7 @@ public: /** * erase an element in the list, by iterator pointing to it. Return true if it was found/erased. */ - bool erase(const Element *p_I) { + bool erase(Element *p_I) { if (_data && p_I) { bool ret = _data->erase(p_I); diff --git a/core/typedefs.h b/core/typedefs.h index 85d62df96b..35c4668581 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -315,6 +315,4 @@ struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {}; #define ___gd_is_defined(val) ____gd_is_defined(__GDARG_PLACEHOLDER_##val) #define GD_IS_DEFINED(x) ___gd_is_defined(x) -#define FORCE_SEMICOLON ; - #endif // TYPEDEFS_H diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 7550477d70..65bfc29a55 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -2719,8 +2719,7 @@ Variant::Variant(const Vector<Plane> &p_array) : } } -Variant::Variant(const Vector<Face3> &p_face_array) : - type(NIL) { +Variant::Variant(const Vector<Face3> &p_face_array) { PackedVector3Array vertices; int face_count = p_face_array.size(); vertices.resize(face_count * 3); @@ -2739,8 +2738,7 @@ Variant::Variant(const Vector<Face3> &p_face_array) : *this = vertices; } -Variant::Variant(const Vector<Variant> &p_array) : - type(NIL) { +Variant::Variant(const Vector<Variant> &p_array) { Array arr; arr.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { @@ -2749,8 +2747,7 @@ Variant::Variant(const Vector<Variant> &p_array) : *this = arr; } -Variant::Variant(const Vector<StringName> &p_array) : - type(NIL) { +Variant::Variant(const Vector<StringName> &p_array) { PackedStringArray v; int len = p_array.size(); v.resize(len); @@ -2908,8 +2905,7 @@ Variant::Variant(const IPAddress &p_address) : memnew_placement(_data._mem, String(p_address)); } -Variant::Variant(const Variant &p_variant) : - type(NIL) { +Variant::Variant(const Variant &p_variant) { reference(p_variant); } diff --git a/core/variant/variant.h b/core/variant/variant.h index 3b1924e8ea..9702c67a37 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -814,8 +814,7 @@ public: static void unregister_types(); Variant(const Variant &p_variant); - _FORCE_INLINE_ Variant() : - type(NIL) {} + _FORCE_INLINE_ Variant() {} _FORCE_INLINE_ ~Variant() { clear(); } diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index 188d9652a8..ae2de055cb 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -326,13 +326,13 @@ <return type="bool" /> <param index="0" name="aabb" type="AABB" /> <description> - Returns [code]true[/code] if this bounding box and [param aabb] are approximately equal, by calling [method Vector2.is_equal_approx] on the [member position] and the [member size]. + Returns [code]true[/code] if this bounding box and [param aabb] are approximately equal, by calling [method Vector3.is_equal_approx] on the [member position] and the [member size]. </description> </method> <method name="is_finite" qualifiers="const"> <return type="bool" /> <description> - Returns [code]true[/code] if this bounding box's values are finite, by calling [method Vector2.is_finite] on the [member position] and the [member size]. + Returns [code]true[/code] if this bounding box's values are finite, by calling [method Vector3.is_finite] on the [member position] and the [member size]. </description> </method> <method name="merge" qualifiers="const"> diff --git a/doc/classes/AnimationNodeStateMachineTransition.xml b/doc/classes/AnimationNodeStateMachineTransition.xml index 7bd0bd7e7e..c729eeebba 100644 --- a/doc/classes/AnimationNodeStateMachineTransition.xml +++ b/doc/classes/AnimationNodeStateMachineTransition.xml @@ -26,7 +26,7 @@ Use an expression as a condition for state machine transitions. It is possible to create complex animation advance conditions for switching between states and gives much greater flexibility for creating complex state machines by directly interfacing with the script code. </member> <member name="advance_mode" type="int" setter="set_advance_mode" getter="get_advance_mode" enum="AnimationNodeStateMachineTransition.AdvanceMode" default="1"> - Determines whether the transition should disabled, enabled when using [method AnimationNodeStateMachinePlayback.travel], or traversed automatically if the [member advance_condition] and [member advance_expression] checks are true (if assigned). + Determines whether the transition should be disabled, enabled when using [method AnimationNodeStateMachinePlayback.travel], or traversed automatically if the [member advance_condition] and [member advance_expression] checks are [code]true[/code] (if assigned). </member> <member name="break_loop_at_end" type="bool" setter="set_break_loop_at_end" getter="is_loop_broken_at_end" default="false"> If [code]true[/code], breaks the loop at the end of the loop cycle for transition, even if the animation is looping. @@ -72,7 +72,7 @@ Only use this transition during [method AnimationNodeStateMachinePlayback.travel]. </constant> <constant name="ADVANCE_MODE_AUTO" value="2" enum="AdvanceMode"> - Automatically use this transition if the [member advance_condition] and [member advance_expression] checks are true (if assigned). + Automatically use this transition if the [member advance_condition] and [member advance_expression] checks are [code]true[/code] (if assigned). </constant> </constants> </class> diff --git a/doc/classes/AudioStreamPlaybackPolyphonic.xml b/doc/classes/AudioStreamPlaybackPolyphonic.xml index f71762d6a5..894c9b2262 100644 --- a/doc/classes/AudioStreamPlaybackPolyphonic.xml +++ b/doc/classes/AudioStreamPlaybackPolyphonic.xml @@ -13,7 +13,7 @@ <return type="bool" /> <param index="0" name="stream" type="int" /> <description> - Return true whether the stream associated with an integer ID is still playing. Check [method play_stream] for information on when this ID becomes invalid. + Returns [code]true[/code] if the stream associated with the given integer ID is still playing. Check [method play_stream] for information on when this ID becomes invalid. </description> </method> <method name="play_stream"> diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index 68fb918904..c774667a7d 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -127,6 +127,9 @@ <theme_item name="icon_max_width" data_type="constant" type="int" default="0"> The maximum allowed width of the [Button]'s icon. This limit is applied on top of the default size of the icon, or its expanded size if [member expand_icon] is [code]true[/code]. The height is adjusted according to the icon's ratio. If the button has additional icons (e.g. [CheckBox]), they will also be limited. </theme_item> + <theme_item name="line_spacing" data_type="constant" type="int" default="0"> + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. + </theme_item> <theme_item name="outline_size" data_type="constant" type="int" default="0"> The size of the text outline. [b]Note:[/b] If using a font with [member FontFile.multichannel_signed_distance_field] enabled, its [member FontFile.msdf_pixel_range] must be set to at least [i]twice[/i] the value of [theme_item outline_size] for outline rendering to look correct. Otherwise, the outline may appear to be cut off earlier than intended. diff --git a/doc/classes/CameraFeed.xml b/doc/classes/CameraFeed.xml index 2b6db13906..6748fdb95b 100644 --- a/doc/classes/CameraFeed.xml +++ b/doc/classes/CameraFeed.xml @@ -34,6 +34,21 @@ Returns the position of camera on the device. </description> </method> + <method name="get_texture_tex_id"> + <return type="int" /> + <param index="0" name="feed_image_type" type="int" enum="CameraServer.FeedImage" /> + <description> + Returns the texture backend ID (usable by some external libraries that need a handle to a texture to write data). + </description> + </method> + <method name="set_external"> + <return type="void" /> + <param index="0" name="width" type="int" /> + <param index="1" name="height" type="int" /> + <description> + Sets the feed as external feed provided by another library. + </description> + </method> <method name="set_format"> <return type="bool" /> <param index="0" name="index" type="int" /> @@ -110,6 +125,9 @@ <constant name="FEED_YCBCR_SEP" value="3" enum="FeedDataType"> Feed supplies separate Y and CbCr images that need to be combined and converted to RGB. </constant> + <constant name="FEED_EXTERNAL" value="4" enum="FeedDataType"> + Feed supplies external image. + </constant> <constant name="FEED_UNSPECIFIED" value="0" enum="FeedPosition"> Unspecified position. </constant> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index d455bd7d68..0131f8f4af 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -993,8 +993,9 @@ Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does. </member> <member name="mouse_force_pass_scroll_events" type="bool" setter="set_force_pass_scroll_events" getter="is_force_pass_scroll_events" default="true"> - When enabled, scroll wheel events processed by [method _gui_input] will be passed to the parent control even if [member mouse_filter] is set to [constant MOUSE_FILTER_STOP]. As it defaults to true, this allows nested scrollable containers to work out of the box. + When enabled, scroll wheel events processed by [method _gui_input] will be passed to the parent control even if [member mouse_filter] is set to [constant MOUSE_FILTER_STOP]. You should disable it on the root of your UI if you do not want scroll events to go to the [method Node._unhandled_input] processing. + [b]Note:[/b] Because this property defaults to [code]true[/code], this allows nested scrollable containers to work out of the box. </member> <member name="offset_bottom" type="float" setter="set_offset" getter="get_offset" default="0.0"> Distance between the node's bottom edge and its parent control, based on [member anchor_bottom]. diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 3142c60e3b..dafa86d42e 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -185,7 +185,7 @@ <return type="Color" /> <description> Returns OS theme accent color. Returns [code]Color(0, 0, 0, 0)[/code], if accent color is unknown. - [b]Note:[/b] This method is implemented on macOS and Windows. + [b]Note:[/b] This method is implemented on macOS, Windows, and Android. </description> </method> <method name="get_base_color" qualifiers="const"> diff --git a/doc/classes/EditorFileSystemImportFormatSupportQuery.xml b/doc/classes/EditorFileSystemImportFormatSupportQuery.xml index b1a810fe6e..fc2feca911 100644 --- a/doc/classes/EditorFileSystemImportFormatSupportQuery.xml +++ b/doc/classes/EditorFileSystemImportFormatSupportQuery.xml @@ -24,7 +24,7 @@ <method name="_query" qualifiers="virtual const"> <return type="bool" /> <description> - Query support. Return false if import must not continue. + Query support. Return [code]false[/code] if import must not continue. </description> </method> </methods> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index 28614b6631..e5f3010366 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -124,7 +124,8 @@ <return type="bool" /> <description> Tells whether this importer can be run in parallel on threads, or, on the contrary, it's only safe for the editor to call it from the main thread, for one file at a time. - If this method is not overridden, it will return [code]true[/code] by default (i.e., safe for parallel importing). + If this method is not overridden, it will return [code]false[/code] by default. + If this importer's implementation is thread-safe and can be run in parallel, override this with [code]true[/code] to optimize for concurrency. </description> </method> <method name="_get_import_options" qualifiers="virtual const"> diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml index ed3fdae352..a0c1a43fb2 100644 --- a/doc/classes/EditorResourcePreview.xml +++ b/doc/classes/EditorResourcePreview.xml @@ -32,7 +32,7 @@ <param index="3" name="userdata" type="Variant" /> <description> Queue the [param resource] being edited for preview. Once the preview is ready, the [param receiver]'s [param receiver_func] will be called. The [param receiver_func] must take the following four arguments: [String] path, [Texture2D] preview, [Texture2D] thumbnail_preview, [Variant] userdata. [param userdata] can be anything, and will be returned when [param receiver_func] is called. - [b]Note:[/b] If it was not possible to create the preview the [param receiver_func] will still be called, but the preview will be null. + [b]Note:[/b] If it was not possible to create the preview the [param receiver_func] will still be called, but the preview will be [code]null[/code]. </description> </method> <method name="queue_resource_preview"> @@ -43,7 +43,7 @@ <param index="3" name="userdata" type="Variant" /> <description> Queue a resource file located at [param path] for preview. Once the preview is ready, the [param receiver]'s [param receiver_func] will be called. The [param receiver_func] must take the following four arguments: [String] path, [Texture2D] preview, [Texture2D] thumbnail_preview, [Variant] userdata. [param userdata] can be anything, and will be returned when [param receiver_func] is called. - [b]Note:[/b] If it was not possible to create the preview the [param receiver_func] will still be called, but the preview will be null. + [b]Note:[/b] If it was not possible to create the preview the [param receiver_func] will still be called, but the preview will be [code]null[/code]. </description> </method> <method name="remove_preview_generator"> diff --git a/doc/classes/EditorScenePostImportPlugin.xml b/doc/classes/EditorScenePostImportPlugin.xml index 5c1c898c9d..0004ec65c6 100644 --- a/doc/classes/EditorScenePostImportPlugin.xml +++ b/doc/classes/EditorScenePostImportPlugin.xml @@ -28,7 +28,7 @@ <param index="0" name="category" type="int" /> <param index="1" name="option" type="String" /> <description> - Return true whether updating the 3D view of the import dialog needs to be updated if an option has changed. + Should return [code]true[/code] if the 3D view of the import dialog needs to update when changing the given option. </description> </method> <method name="_get_internal_option_visibility" qualifiers="virtual const"> @@ -37,7 +37,7 @@ <param index="1" name="for_animation" type="bool" /> <param index="2" name="option" type="String" /> <description> - Return true or false whether a given option should be visible. Return null to ignore. + Should return [code]true[/code] to show the given option, [code]false[/code] to hide the given option, or [code]null[/code] to ignore. </description> </method> <method name="_get_option_visibility" qualifiers="virtual const"> @@ -46,7 +46,7 @@ <param index="1" name="for_animation" type="bool" /> <param index="2" name="option" type="String" /> <description> - Return true or false whether a given option should be visible. Return null to ignore. + Should return [code]true[/code] to show the given option, [code]false[/code] to hide the given option, or [code]null[/code] to ignore. </description> </method> <method name="_internal_process" qualifiers="virtual"> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index a5097521dc..ea5207e826 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -152,7 +152,7 @@ <param index="1" name="value" type="Variant" /> <param index="2" name="update_current" type="bool" /> <description> - Sets the initial value of the setting specified by [param name] to [param value]. This is used to provide a value for the Revert button in the Editor Settings. If [param update_current] is true, the current value of the setting will be set to [param value] as well. + Sets the initial value of the setting specified by [param name] to [param value]. This is used to provide a value for the Revert button in the Editor Settings. If [param update_current] is [code]true[/code], the setting is reset to [param value] as well. </description> </method> <method name="set_project_metadata"> @@ -230,7 +230,7 @@ If [code]true[/code], when a node is deleted with animation tracks referencing it, a confirmation dialog appears before the tracks are deleted. The dialog will appear even when using the "Delete (No Confirm)" shortcut. </member> <member name="docks/scene_tree/ask_before_revoking_unique_name" type="bool" setter="" getter=""> - If [code]true[/code], displays a confirmation dialog before left-clicking the "percent" icon next to a node name in the Scene tree dock. When clicked, this icon revokes the node's scene-unique name, which can impact the behavior of scripts that rely on this scene-unique name due to identifiers not being found anymore. + If [code]true[/code], displays a confirmation dialog after left-clicking the "percent" icon next to a node name in the Scene tree dock. When clicked, this icon revokes the node's scene-unique name, which can impact the behavior of scripts that rely on this scene-unique name due to identifiers not being found anymore. </member> <member name="docks/scene_tree/auto_expand_to_selected" type="bool" setter="" getter=""> If [code]true[/code], the scene tree dock will automatically unfold nodes when a node that has folded parents is selected. @@ -717,9 +717,21 @@ <member name="filesystem/quick_open_dialog/default_display_mode" type="int" setter="" getter=""> If set to [code]Adaptive[/code], the dialog opens in list view or grid view depending on the requested type. If set to [code]Last Used[/code], the display mode will always open the way you last used it. </member> + <member name="filesystem/quick_open_dialog/enable_fuzzy_matching" type="bool" setter="" getter=""> + If [code]true[/code], fuzzy matching of search tokens is allowed. + </member> <member name="filesystem/quick_open_dialog/include_addons" type="bool" setter="" getter=""> If [code]true[/code], results will include files located in the [code]addons[/code] folder. </member> + <member name="filesystem/quick_open_dialog/max_fuzzy_misses" type="int" setter="" getter=""> + The number of allowed missed query characters in a match, if fuzzy matching is enabled. For example, with the default value of 2, [code]foobar[/code] would match [code]foobur[/code] and [code]foob[/code] but not [code]foo[/code]. + </member> + <member name="filesystem/quick_open_dialog/max_results" type="int" setter="" getter=""> + Maximum number of matches to show in dialog. + </member> + <member name="filesystem/quick_open_dialog/show_search_highlight" type="bool" setter="" getter=""> + If [code]true[/code], results will be highlighted with their search matches. + </member> <member name="filesystem/tools/oidn/oidn_denoise_path" type="String" setter="" getter=""> The path to the directory containing the Open Image Denoise (OIDN) executable, used optionally for denoising lightmaps. It can be downloaded from [url=https://www.openimagedenoise.org/downloads.html]openimagedenoise.org[/url]. To enable this feature for your specific project, use [member ProjectSettings.rendering/lightmapping/denoising/denoiser]. @@ -1395,7 +1407,7 @@ The script editor's documentation comment color. In GDScript, this is used for comments starting with [code]##[/code]. In C#, this is used for comments starting with [code]///[/code] or [code]/**[/code]. </member> <member name="text_editor/theme/highlighting/engine_type_color" type="Color" setter="" getter=""> - The script editor's engine type color ([Vector2], [Vector3], [Color], ...). + The script editor's engine type color ([Object], [Mesh], [Node], ...). </member> <member name="text_editor/theme/highlighting/executing_line_color" type="Color" setter="" getter=""> The script editor's color for the debugger's executing line icon (displayed in the gutter). diff --git a/doc/classes/EditorUndoRedoManager.xml b/doc/classes/EditorUndoRedoManager.xml index 0f8c69a1bb..6a66a35ce8 100644 --- a/doc/classes/EditorUndoRedoManager.xml +++ b/doc/classes/EditorUndoRedoManager.xml @@ -87,7 +87,7 @@ <return type="void" /> <param index="0" name="execute" type="bool" default="true" /> <description> - Commit the action. If [param execute] is true (default), all "do" methods/properties are called/set when this function is called. + Commits the action. If [param execute] is [code]true[/code] (default), all "do" methods/properties are called/set when this function is called. </description> </method> <method name="create_action"> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index cc3acad6d6..fc8bc15b5c 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -154,7 +154,7 @@ <return type="bool" /> <param index="0" name="slot_index" type="int" /> <description> - Returns true if the background [StyleBox] of the slot with the given [param slot_index] is drawn. + Returns [code]true[/code] if the background [StyleBox] of the slot with the given [param slot_index] is drawn. </description> </method> <method name="is_slot_enabled_left" qualifiers="const"> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 0fd84fb452..9b71a8c37f 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -510,7 +510,7 @@ <param index="1" name="lossy" type="bool" default="false" /> <param index="2" name="quality" type="float" default="0.75" /> <description> - Saves the image as a WebP (Web Picture) file to the file at [param path]. By default it will save lossless. If [param lossy] is true, the image will be saved lossy, using the [param quality] setting between 0.0 and 1.0 (inclusive). Lossless WebP offers more efficient compression than PNG. + Saves the image as a WebP (Web Picture) file to the file at [param path]. By default it will save lossless. If [param lossy] is [code]true[/code], the image will be saved lossy, using the [param quality] setting between [code]0.0[/code] and [code]1.0[/code] (inclusive). Lossless WebP offers more efficient compression than PNG. [b]Note:[/b] The WebP format is limited to a size of 16383×16383 pixels, while PNG can save larger images. </description> </method> @@ -519,7 +519,7 @@ <param index="0" name="lossy" type="bool" default="false" /> <param index="1" name="quality" type="float" default="0.75" /> <description> - Saves the image as a WebP (Web Picture) file to a byte array. By default it will save lossless. If [param lossy] is true, the image will be saved lossy, using the [param quality] setting between 0.0 and 1.0 (inclusive). Lossless WebP offers more efficient compression than PNG. + Saves the image as a WebP (Web Picture) file to a byte array. By default it will save lossless. If [param lossy] is [code]true[/code], the image will be saved lossy, using the [param quality] setting between [code]0.0[/code] and [code]1.0[/code] (inclusive). Lossless WebP offers more efficient compression than PNG. [b]Note:[/b] The WebP format is limited to a size of 16383×16383 pixels, while PNG can save larger images. </description> </method> diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index f91006f69a..ae5a62753f 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -122,7 +122,7 @@ [Color] of the text's shadow effect. </theme_item> <theme_item name="line_spacing" data_type="constant" type="int" default="3"> - Vertical space between lines in multiline [Label]. + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. </theme_item> <theme_item name="outline_size" data_type="constant" type="int" default="0"> Text outline size. diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml index ff26c5490d..7584a1d526 100644 --- a/doc/classes/Label3D.xml +++ b/doc/classes/Label3D.xml @@ -79,7 +79,7 @@ Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. </member> <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0"> - Vertical space between lines in multiline [Label3D]. + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. </member> <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color(1, 1, 1, 1)" keywords="color, colour"> Text [Color] of the [Label3D]. diff --git a/doc/classes/LabelSettings.xml b/doc/classes/LabelSettings.xml index 8cdb30c303..ff7b8e7b0e 100644 --- a/doc/classes/LabelSettings.xml +++ b/doc/classes/LabelSettings.xml @@ -19,7 +19,7 @@ Size of the text. </member> <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="3.0"> - Vertical space between lines when the text is multiline. + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. </member> <member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)"> The color of the outline. diff --git a/doc/classes/MultiplayerPeer.xml b/doc/classes/MultiplayerPeer.xml index edb2c39e24..cec9464102 100644 --- a/doc/classes/MultiplayerPeer.xml +++ b/doc/classes/MultiplayerPeer.xml @@ -65,7 +65,7 @@ <method name="is_server_relay_supported" qualifiers="const"> <return type="bool" /> <description> - Returns true if the server can act as a relay in the current configuration (i.e. if the higher level [MultiplayerAPI] should notify connected clients of other peers, and implement a relay protocol to allow communication between them). + Returns [code]true[/code] if the server can act as a relay in the current configuration. That is, if the higher level [MultiplayerAPI] should notify connected clients of other peers, and implement a relay protocol to allow communication between them. </description> </method> <method name="poll"> diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index 7e78006240..5c19a6b355 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -133,7 +133,7 @@ <return type="bool" /> <param index="0" name="agent" type="RID" /> <description> - Returns true if the map got changed the previous frame. + Returns [code]true[/code] if the map got changed the previous frame. </description> </method> <method name="agent_set_avoidance_callback"> @@ -215,7 +215,7 @@ <param index="0" name="agent" type="RID" /> <param index="1" name="paused" type="bool" /> <description> - If [param paused] is true the specified [param agent] will not be processed, e.g. calculate avoidance velocities or receive avoidance callbacks. + If [param paused] is [code]true[/code] the specified [param agent] will not be processed, e.g. calculate avoidance velocities or receive avoidance callbacks. </description> </method> <method name="agent_set_position"> @@ -573,7 +573,7 @@ <return type="bool" /> <param index="0" name="map" type="RID" /> <description> - Returns true if the map is active. + Returns [code]true[/code] if the map is active. </description> </method> <method name="map_set_active"> @@ -707,7 +707,7 @@ <param index="0" name="obstacle" type="RID" /> <param index="1" name="paused" type="bool" /> <description> - If [param paused] is true the specified [param obstacle] will not be processed, e.g. affect avoidance velocities. + If [param paused] is [code]true[/code] the specified [param obstacle] will not be processed, e.g. affect avoidance velocities. </description> </method> <method name="obstacle_set_position"> diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 7e206046d6..66a286758b 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -147,7 +147,7 @@ <return type="bool" /> <param index="0" name="agent" type="RID" /> <description> - Returns true if the map got changed the previous frame. + Returns [code]true[/code] if the map got changed the previous frame. </description> </method> <method name="agent_set_avoidance_callback"> @@ -237,7 +237,7 @@ <param index="0" name="agent" type="RID" /> <param index="1" name="paused" type="bool" /> <description> - If [param paused] is true the specified [param agent] will not be processed, e.g. calculate avoidance velocities or receive avoidance callbacks. + If [param paused] is [code]true[/code] the specified [param agent] will not be processed, e.g. calculate avoidance velocities or receive avoidance callbacks. </description> </method> <method name="agent_set_position"> @@ -645,14 +645,14 @@ <return type="bool" /> <param index="0" name="map" type="RID" /> <description> - Returns true if the navigation [param map] allows navigation regions to use edge connections to connect with other navigation regions within proximity of the navigation map edge connection margin. + Returns [code]true[/code] if the navigation [param map] allows navigation regions to use edge connections to connect with other navigation regions within proximity of the navigation map edge connection margin. </description> </method> <method name="map_is_active" qualifiers="const"> <return type="bool" /> <param index="0" name="map" type="RID" /> <description> - Returns true if the map is active. + Returns [code]true[/code] if the map is active. </description> </method> <method name="map_set_active"> @@ -832,7 +832,7 @@ <param index="0" name="obstacle" type="RID" /> <param index="1" name="paused" type="bool" /> <description> - If [param paused] is true the specified [param obstacle] will not be processed, e.g. affect avoidance velocities. + If [param paused] is [code]true[/code] the specified [param obstacle] will not be processed, e.g. affect avoidance velocities. </description> </method> <method name="obstacle_set_position"> @@ -1023,7 +1023,7 @@ <return type="bool" /> <param index="0" name="region" type="RID" /> <description> - Returns true if the navigation [param region] is set to use edge connections to connect with other navigation regions within proximity of the navigation map edge connection margin. + Returns [code]true[/code] if the navigation [param region] is set to use edge connections to connect with other navigation regions within proximity of the navigation map edge connection margin. </description> </method> <method name="region_owns_point" qualifiers="const"> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 2767a11e80..a130a71826 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -454,7 +454,7 @@ <return type="Variant" /> <param index="0" name="method" type="StringName" /> <description> - Calls the [param method] on the object during idle time. Always returns null, [b]not[/b] the method's result. + Calls the [param method] on the object during idle time. Always returns [code]null[/code], [b]not[/b] the method's result. Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. This means you should not call a method deferred from itself (or from a method called by it), as this causes infinite recursion the same way as if you had called the method directly. This method supports a variable number of arguments, so parameters can be passed as a comma separated list. [codeblocks] diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3358e6838c..fff6c8d3bb 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -469,10 +469,10 @@ If the [code]--log-file <file>[/code] [url=$DOCS_URL/tutorials/editor/command_line_tutorial.html]command line argument[/url] is used, log rotation is always disabled. </member> <member name="debug/gdscript/warnings/assert_always_false" type="int" setter="" getter="" default="1"> - When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when an [code]assert[/code] call always evaluates to false. + When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when an [code]assert[/code] call always evaluates to [code]false[/code]. </member> <member name="debug/gdscript/warnings/assert_always_true" type="int" setter="" getter="" default="1"> - When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when an [code]assert[/code] call always evaluates to true. + When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when an [code]assert[/code] call always evaluates to [code]true[/code]. </member> <member name="debug/gdscript/warnings/confusable_capture_reassignment" type="int" setter="" getter="" default="1"> When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a local variable captured by a lambda is reassigned, since this does not modify the outer local variable. @@ -561,10 +561,10 @@ When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when defining a local or member variable, signal, or enum that would have the same name as a built-in function or global class name, thus shadowing it. </member> <member name="debug/gdscript/warnings/shadowed_variable" type="int" setter="" getter="" default="1"> - When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when defining a local or member variable that would shadow a member variable that the class defines. + When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a local variable or local constant shadows a member declared in the current class. </member> <member name="debug/gdscript/warnings/shadowed_variable_base_class" type="int" setter="" getter="" default="1"> - When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when defining a local or subclass member variable that would shadow a variable that is inherited from a parent class. + When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a local variable or local constant shadows a member declared in a base class. </member> <member name="debug/gdscript/warnings/standalone_expression" type="int" setter="" getter="" default="1"> When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when calling an expression that may have no effect on the surrounding code, such as writing [code]2 + 2[/code] as a statement. @@ -3014,7 +3014,7 @@ Specify whether OpenXR should be configured for an HMD or a hand held device. </member> <member name="xr/openxr/foveation_dynamic" type="bool" setter="" getter="" default="false"> - If true and foveation is supported, will automatically adjust foveation level based on framerate up to the level set on [member xr/openxr/foveation_level]. + If [code]true[/code] and foveation is supported, will automatically adjust foveation level based on framerate up to the level set on [member xr/openxr/foveation_level]. [b]Note:[/b] Only works on the Compatibility rendering method. </member> <member name="xr/openxr/foveation_level" type="int" setter="" getter="" default=""0""> diff --git a/doc/classes/RDPipelineDepthStencilState.xml b/doc/classes/RDPipelineDepthStencilState.xml index dc1e70eb55..425890bb8d 100644 --- a/doc/classes/RDPipelineDepthStencilState.xml +++ b/doc/classes/RDPipelineDepthStencilState.xml @@ -34,10 +34,10 @@ The method used for comparing the previous and current depth values. </member> <member name="depth_range_max" type="float" setter="set_depth_range_max" getter="get_depth_range_max" default="0.0"> - The maximum depth that returns true for [member enable_depth_range]. + The maximum depth that returns [code]true[/code] for [member enable_depth_range]. </member> <member name="depth_range_min" type="float" setter="set_depth_range_min" getter="get_depth_range_min" default="0.0"> - The minimum depth that returns true for [member enable_depth_range]. + The minimum depth that returns [code]true[/code] for [member enable_depth_range]. </member> <member name="enable_depth_range" type="bool" setter="set_enable_depth_range" getter="get_enable_depth_range" default="false"> If [code]true[/code], each depth value will be tested to see if it is between [member depth_range_min] and [member depth_range_max]. If it is outside of these values, it is discarded. @@ -46,7 +46,7 @@ If [code]true[/code], enables depth testing which allows objects to be automatically occluded by other objects based on their depth. This also allows objects to be partially occluded by other objects. If [code]false[/code], objects will appear in the order they were drawn (like in Godot's 2D renderer). </member> <member name="enable_depth_write" type="bool" setter="set_enable_depth_write" getter="get_enable_depth_write" default="false"> - If [code]true[/code], writes to the depth buffer whenever the depth test returns true. Only works when enable_depth_test is also true. + If [code]true[/code], writes to the depth buffer whenever the depth test returns [code]true[/code]. Only works when enable_depth_test is also [code]true[/code]. </member> <member name="enable_stencil" type="bool" setter="set_enable_stencil" getter="get_enable_stencil" default="false"> If [code]true[/code], enables stencil testing. There are separate stencil buffers for front-facing triangles and back-facing triangles. See properties that begin with "front_op" and properties with "back_op" for each. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 16a554eded..284dc07fd4 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -224,7 +224,7 @@ <param index="0" name="item" type="RID" /> <param index="1" name="ignore" type="bool" /> <description> - If [param ignore] is [code]true[/code], ignore clipping on items drawn with this canvas item until this is called again with [param ignore] set to false. + If [param ignore] is [code]true[/code], ignore clipping on items drawn with this canvas item until this is called again with [param ignore] set to [code]false[/code]. </description> </method> <method name="canvas_item_add_lcd_texture_rect_region"> @@ -1278,6 +1278,14 @@ Sets the intensity of the background color. </description> </method> + <method name="environment_set_camera_id"> + <return type="void" /> + <param index="0" name="env" type="RID" /> + <param index="1" name="id" type="int" /> + <description> + Sets the camera ID to be used as environment background. + </description> + </method> <method name="environment_set_canvas_max_layer"> <return type="void" /> <param index="0" name="env" type="RID" /> @@ -2949,7 +2957,7 @@ <param index="0" name="particles" type="RID" /> <param index="1" name="emitting" type="bool" /> <description> - If [code]true[/code], particles will emit over time. Setting to false does not reset the particles, but only stops their emission. Equivalent to [member GPUParticles3D.emitting]. + If [code]true[/code], particles will emit over time. Setting to [code]false[/code] does not reset the particles, but only stops their emission. Equivalent to [member GPUParticles3D.emitting]. </description> </method> <method name="particles_set_explosiveness_ratio"> diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index 56c3208fc3..f718ad15d8 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -104,7 +104,7 @@ <param index="1" name="progress" type="Array" default="[]" /> <description> Returns the status of a threaded loading operation started with [method load_threaded_request] for the resource at [param path]. See [enum ThreadLoadStatus] for possible return values. - An array variable can optionally be passed via [param progress], and will return a one-element array containing the percentage of completion of the threaded loading. + An array variable can optionally be passed via [param progress], and will return a one-element array containing the ratio of completion of the threaded loading (between [code]0.0[/code] and [code]1.0[/code]). [b]Note:[/b] The recommended way of using this method is to call it during different frames (e.g., in [method Node._process], instead of a loop). </description> </method> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 4a2cbbc3d8..2ac346b5c2 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -810,7 +810,7 @@ The default background color for odd rows. </theme_item> <theme_item name="line_separation" data_type="constant" type="int" default="0"> - The vertical space between lines. + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. </theme_item> <theme_item name="outline_size" data_type="constant" type="int" default="0"> The size of the text outline. diff --git a/doc/classes/Shader.xml b/doc/classes/Shader.xml index 1e7f9e5ee5..3fbe1da687 100644 --- a/doc/classes/Shader.xml +++ b/doc/classes/Shader.xml @@ -31,8 +31,8 @@ <return type="Array" /> <param index="0" name="get_groups" type="bool" default="false" /> <description> - Get the list of shader uniforms that can be assigned to a [ShaderMaterial], for use with [method ShaderMaterial.set_shader_parameter] and [method ShaderMaterial.get_shader_parameter]. The parameters returned are contained in dictionaries in a similar format to the ones returned by [method Object.get_property_list]. - If argument [param get_groups] is true, parameter grouping hints will be provided. + Returns the list of shader uniforms that can be assigned to a [ShaderMaterial], for use with [method ShaderMaterial.set_shader_parameter] and [method ShaderMaterial.get_shader_parameter]. The parameters returned are contained in dictionaries in a similar format to the ones returned by [method Object.get_property_list]. + If argument [param get_groups] is [code]true[/code], parameter grouping hints are also included in the list. </description> </method> <method name="inspect_native_shader_code"> diff --git a/doc/classes/SkeletonIK3D.xml b/doc/classes/SkeletonIK3D.xml index 4858a6ce22..dbb099a22b 100644 --- a/doc/classes/SkeletonIK3D.xml +++ b/doc/classes/SkeletonIK3D.xml @@ -31,7 +31,7 @@ <method name="get_parent_skeleton" qualifiers="const"> <return type="Skeleton3D" /> <description> - Returns the parent [Skeleton3D] Node that was present when SkeletonIK entered the [SceneTree]. Returns null if the parent node was not a [Skeleton3D] Node when SkeletonIK3D entered the [SceneTree]. + Returns the parent [Skeleton3D] node that was present when SkeletonIK entered the scene tree. Returns [code]null[/code] if the parent node was not a [Skeleton3D] node when SkeletonIK3D entered the scene tree. </description> </method> <method name="is_running"> diff --git a/doc/classes/Slider.xml b/doc/classes/Slider.xml index a4ffa5c1e7..b1e78e8987 100644 --- a/doc/classes/Slider.xml +++ b/doc/classes/Slider.xml @@ -28,12 +28,12 @@ <signal name="drag_ended"> <param index="0" name="value_changed" type="bool" /> <description> - Emitted when dragging stops. If [param value_changed] is true, [member Range.value] is different from the value when you started the dragging. + Emitted when the grabber stops being dragged. If [param value_changed] is [code]true[/code], [member Range.value] is different from the value when the dragging was started. </description> </signal> <signal name="drag_started"> <description> - Emitted when dragging is started. This is emitted before the corresponding [signal Range.value_changed] signal. + Emitted when the grabber starts being dragged. This is emitted before the corresponding [signal Range.value_changed] signal. </description> </signal> </signals> diff --git a/doc/classes/SpringArm3D.xml b/doc/classes/SpringArm3D.xml index 99389fb78d..330317f352 100644 --- a/doc/classes/SpringArm3D.xml +++ b/doc/classes/SpringArm3D.xml @@ -7,6 +7,7 @@ [SpringArm3D] casts a ray or a shape along its Z axis and moves all its direct children to the collision point, with an optional margin. This is useful for 3rd person cameras that move closer to the player when inside a tight space (you may need to exclude the player's collider from the [SpringArm3D]'s collision check). </description> <tutorials> + <link title="Third-person camera with spring arm">$DOCS_URL/tutorials/3d/spring_arm.html</link> </tutorials> <methods> <method name="add_excluded_object"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 42558bf992..7a4bef5747 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1624,7 +1624,7 @@ The caret's width in pixels. Greater values can be used to improve accessibility by ensuring the caret is easily visible, or to ensure consistency with a large font size. If set to [code]0[/code] or lower, the caret width is automatically set to 1 pixel and multiplied by the display scaling factor. </theme_item> <theme_item name="line_spacing" data_type="constant" type="int" default="4"> - Sets the spacing between the lines. + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. </theme_item> <theme_item name="outline_size" data_type="constant" type="int" default="0"> The size of the text outline. diff --git a/doc/classes/TextMesh.xml b/doc/classes/TextMesh.xml index 898d19aed3..b6b1052af5 100644 --- a/doc/classes/TextMesh.xml +++ b/doc/classes/TextMesh.xml @@ -37,7 +37,7 @@ Language code used for text shaping algorithms, if left empty current locale is used instead. </member> <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0"> - Vertical space between lines in multiline [TextMesh]. + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)"> The text drawing offset (in pixels). diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml index 46197f19b8..c9ac660b8c 100644 --- a/doc/classes/TextParagraph.xml +++ b/doc/classes/TextParagraph.xml @@ -280,6 +280,9 @@ <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" is_bitfield="true" default="163"> Line fill alignment rules. See [enum TextServer.JustificationFlag] for more information. </member> + <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0"> + Additional vertical spacing between lines (in pixels), spacing is added to line descent. This value can be negative. + </member> <member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1"> Limits the lines of text shown. </member> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 0995a5a672..4683f063f1 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -380,7 +380,7 @@ <param index="4" name="ignore_empty_terrains" type="bool" default="true" /> <description> Update all the cells in the [param cells] coordinates array so that they use the given [param terrain] for the given [param terrain_set]. If an updated cell has the same terrain as one of its neighboring cells, this function tries to join the two. This function might update neighboring tiles if needed to create correct terrain transitions. - If [param ignore_empty_terrains] is true, empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. + If [param ignore_empty_terrains] is [code]true[/code], empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. If [param layer] is negative, the layers are accessed from the last one. [b]Note:[/b] To work correctly, this method requires the TileMap's TileSet to have terrains set up with all required terrain combinations. Otherwise, it may produce unexpected results. </description> @@ -394,7 +394,7 @@ <param index="4" name="ignore_empty_terrains" type="bool" default="true" /> <description> Update all the cells in the [param path] coordinates array so that they use the given [param terrain] for the given [param terrain_set]. The function will also connect two successive cell in the path with the same terrain. This function might update neighboring tiles if needed to create correct terrain transitions. - If [param ignore_empty_terrains] is true, empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. + If [param ignore_empty_terrains] is [code]true[/code], empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. If [param layer] is negative, the layers are accessed from the last one. [b]Note:[/b] To work correctly, this method requires the TileMap's TileSet to have terrains set up with all required terrain combinations. Otherwise, it may produce unexpected results. </description> diff --git a/doc/classes/TileMapLayer.xml b/doc/classes/TileMapLayer.xml index 135f85de69..6cbec9c2aa 100644 --- a/doc/classes/TileMapLayer.xml +++ b/doc/classes/TileMapLayer.xml @@ -228,7 +228,7 @@ <param index="3" name="ignore_empty_terrains" type="bool" default="true" /> <description> Update all the cells in the [param cells] coordinates array so that they use the given [param terrain] for the given [param terrain_set]. If an updated cell has the same terrain as one of its neighboring cells, this function tries to join the two. This function might update neighboring tiles if needed to create correct terrain transitions. - If [param ignore_empty_terrains] is true, empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. + If [param ignore_empty_terrains] is [code]true[/code], empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. [b]Note:[/b] To work correctly, this method requires the [TileMapLayer]'s TileSet to have terrains set up with all required terrain combinations. Otherwise, it may produce unexpected results. </description> </method> @@ -240,7 +240,7 @@ <param index="3" name="ignore_empty_terrains" type="bool" default="true" /> <description> Update all the cells in the [param path] coordinates array so that they use the given [param terrain] for the given [param terrain_set]. The function will also connect two successive cell in the path with the same terrain. This function might update neighboring tiles if needed to create correct terrain transitions. - If [param ignore_empty_terrains] is true, empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. + If [param ignore_empty_terrains] is [code]true[/code], empty terrains will be ignored when trying to find the best fitting tile for the given terrain constraints. [b]Note:[/b] To work correctly, this method requires the [TileMapLayer]'s TileSet to have terrains set up with all required terrain combinations. Otherwise, it may produce unexpected results. </description> </method> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 64cd4fb7b2..19b6e8d92c 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -4,7 +4,7 @@ Tile library for tilemaps. </brief_description> <description> - A TileSet is a library of tiles for a [TileMap]. A TileSet handles a list of [TileSetSource], each of them storing a set of tiles. + A TileSet is a library of tiles for a [TileMapLayer]. A TileSet handles a list of [TileSetSource], each of them storing a set of tiles. Tiles can either be from a [TileSetAtlasSource], which renders tiles out of a texture with support for physics, navigation, etc., or from a [TileSetScenesCollectionSource], which exposes scene-based tiles. Tiles are referenced by using three IDs: their source ID, their atlas coordinates ID, and their alternative tile ID. A TileSet can be configured so that its tiles expose more or fewer properties. To do so, the TileSet resources use property layers, which you can add or remove depending on your needs. @@ -218,6 +218,13 @@ Returns the collision mask of bodies on the given TileSet's physics layer. </description> </method> + <method name="get_physics_layer_collision_priority" qualifiers="const"> + <return type="float" /> + <param index="0" name="layer_index" type="int" /> + <description> + Returns the collision priority of bodies on the given TileSet's physics layer. + </description> + </method> <method name="get_physics_layer_physics_material" qualifiers="const"> <return type="PhysicsMaterial" /> <param index="0" name="layer_index" type="int" /> @@ -547,7 +554,7 @@ <param index="0" name="layer_index" type="int" /> <param index="1" name="layer" type="int" /> <description> - Sets the physics layer (as in the physics server) for bodies in the given TileSet physics layer. + Sets the collision layer (as in the physics server) for bodies in the given TileSet physics layer. </description> </method> <method name="set_physics_layer_collision_mask"> @@ -555,7 +562,15 @@ <param index="0" name="layer_index" type="int" /> <param index="1" name="mask" type="int" /> <description> - Sets the physics layer (as in the physics server) for bodies in the given TileSet physics layer. + Sets the collision mask for bodies in the given TileSet physics layer. + </description> + </method> + <method name="set_physics_layer_collision_priority"> + <return type="void" /> + <param index="0" name="layer_index" type="int" /> + <param index="1" name="priority" type="float" /> + <description> + Sets the collision priority for bodies in the given TileSet physics layer. </description> </method> <method name="set_physics_layer_physics_material"> diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml index f8f9393847..09f3dba8cf 100644 --- a/doc/classes/Timer.xml +++ b/doc/classes/Timer.xml @@ -43,6 +43,7 @@ <member name="autostart" type="bool" setter="set_autostart" getter="has_autostart" default="false"> If [code]true[/code], the timer will start immediately when it enters the scene tree. [b]Note:[/b] After the timer enters the tree, this property is automatically set to [code]false[/code]. + [b]Note:[/b] This property does nothing when the timer is running in the editor. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="is_one_shot" default="false"> If [code]true[/code], the timer will stop after reaching the end. Otherwise, as by default, the timer will automatically restart. diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index 132ecc3f92..d04a6f7316 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -267,7 +267,7 @@ <method name="get_next" qualifiers="const"> <return type="TreeItem" /> <description> - Returns the next sibling TreeItem in the tree or a null object if there is none. + Returns the next sibling TreeItem in the tree or a [code]null[/code] object if there is none. </description> </method> <method name="get_next_in_tree"> @@ -289,13 +289,13 @@ <method name="get_parent" qualifiers="const"> <return type="TreeItem" /> <description> - Returns the parent TreeItem or a null object if there is none. + Returns the parent TreeItem or a [code]null[/code] object if there is none. </description> </method> <method name="get_prev"> <return type="TreeItem" /> <description> - Returns the previous sibling TreeItem in the tree or a null object if there is none. + Returns the previous sibling TreeItem in the tree or a [code]null[/code] object if there is none. </description> </method> <method name="get_prev_in_tree"> diff --git a/doc/classes/VideoStreamPlayback.xml b/doc/classes/VideoStreamPlayback.xml index 8b4a7f8d29..17e29ae337 100644 --- a/doc/classes/VideoStreamPlayback.xml +++ b/doc/classes/VideoStreamPlayback.xml @@ -54,7 +54,7 @@ <method name="_play" qualifiers="virtual"> <return type="void" /> <description> - Called in response to [member VideoStreamPlayer.autoplay] or [method VideoStreamPlayer.play]. Note that manual playback may also invoke [method _stop] multiple times before this method is called. [method _is_playing] should return true once playing. + Called in response to [member VideoStreamPlayer.autoplay] or [method VideoStreamPlayer.play]. Note that manual playback may also invoke [method _stop] multiple times before this method is called. [method _is_playing] should return [code]true[/code] once playing. </description> </method> <method name="_seek" qualifiers="virtual"> @@ -81,14 +81,14 @@ <method name="_stop" qualifiers="virtual"> <return type="void" /> <description> - Stops playback. May be called multiple times before [method _play], or in response to [method VideoStreamPlayer.stop]. [method _is_playing] should return false once stopped. + Stops playback. May be called multiple times before [method _play], or in response to [method VideoStreamPlayer.stop]. [method _is_playing] should return [code]false[/code] once stopped. </description> </method> <method name="_update" qualifiers="virtual"> <return type="void" /> <param index="0" name="delta" type="float" /> <description> - Ticks video playback for [param delta] seconds. Called every frame as long as [method _is_paused] and [method _is_playing] return true. + Ticks video playback for [param delta] seconds. Called every frame as long as both [method _is_paused] and [method _is_playing] return [code]true[/code]. </description> </method> <method name="mix_audio"> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 333e61d03f..c4319fd360 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -48,7 +48,7 @@ <method name="get_camera_2d" qualifiers="const"> <return type="Camera2D" /> <description> - Returns the currently active 2D camera. Returns null if there are no active cameras. + Returns the currently active 2D camera. Returns [code]null[/code] if there are no active cameras. </description> </method> <method name="get_camera_3d" qualifiers="const"> @@ -144,13 +144,13 @@ <method name="gui_get_focus_owner" qualifiers="const"> <return type="Control" /> <description> - Returns the [Control] having the focus within this viewport. If no [Control] has the focus, returns null. + Returns the currently focused [Control] within this viewport. If no [Control] is focused, returns [code]null[/code]. </description> </method> <method name="gui_get_hovered_control" qualifiers="const"> <return type="Control" /> <description> - Returns the [Control] that the mouse is currently hovering over in this viewport. If no [Control] has the cursor, returns null. + Returns the [Control] that the mouse is currently hovering over in this viewport. If no [Control] has the cursor, returns [code]null[/code]. Typically the leaf [Control] node or deepest level of the subtree which claims hover. This is very useful when used together with [method Node.is_ancestor_of] to find if the mouse is within a control tree. </description> </method> diff --git a/doc/classes/VisualShaderNodeCompare.xml b/doc/classes/VisualShaderNodeCompare.xml index b566ca62f3..9f554dacb4 100644 --- a/doc/classes/VisualShaderNodeCompare.xml +++ b/doc/classes/VisualShaderNodeCompare.xml @@ -69,10 +69,10 @@ Represents the size of the [enum Function] enum. </constant> <constant name="COND_ALL" value="0" enum="Condition"> - The result will be true if all of component in vector satisfy the comparison condition. + The result will be [code]true[/code] if all components in the vector satisfy the comparison condition. </constant> <constant name="COND_ANY" value="1" enum="Condition"> - The result will be true if any of component in vector satisfy the comparison condition. + The result will be [code]true[/code] if any component in the vector satisfies the comparison condition. </constant> <constant name="COND_MAX" value="2" enum="Condition"> Represents the size of the [enum Condition] enum. diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index ab270e5e82..0cc89dfaca 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -6177,6 +6177,8 @@ uint64_t RenderingDeviceDriverD3D12::api_trait_get(ApiTrait p_trait) { return false; case API_TRAIT_USE_GENERAL_IN_COPY_QUEUES: return true; + case API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS: + return !barrier_capabilities.enhanced_barriers_supported; default: return RenderingDeviceDriver::api_trait_get(p_trait); } diff --git a/drivers/gles3/effects/feed_effects.cpp b/drivers/gles3/effects/feed_effects.cpp new file mode 100644 index 0000000000..8ca88da662 --- /dev/null +++ b/drivers/gles3/effects/feed_effects.cpp @@ -0,0 +1,128 @@ +/**************************************************************************/ +/* feed_effects.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "feed_effects.h" + +#ifdef ANDROID_ENABLED +#include <GLES3/gl3ext.h> +#endif + +#define GL_PROGRAM_POINT_SIZE 0x8642 + +using namespace GLES3; + +FeedEffects *FeedEffects::singleton = nullptr; + +FeedEffects *FeedEffects::get_singleton() { + return singleton; +} + +FeedEffects::FeedEffects() { + singleton = this; + + feed.shader.initialize(); + feed.shader_version = feed.shader.version_create(); + feed.shader.version_bind_shader(feed.shader_version, FeedShaderGLES3::MODE_DEFAULT); + + { // Screen Triangle. + glGenBuffers(1, &screen_triangle); + glBindBuffer(GL_ARRAY_BUFFER, screen_triangle); + + const float qv[6] = { + -1.0f, + -1.0f, + 3.0f, + -1.0f, + -1.0f, + 3.0f, + }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, qv, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + + glGenVertexArrays(1, &screen_triangle_array); + glBindVertexArray(screen_triangle_array); + glBindBuffer(GL_ARRAY_BUFFER, screen_triangle); + glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr); + glEnableVertexAttribArray(RS::ARRAY_VERTEX); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + } +} + +FeedEffects::~FeedEffects() { + singleton = nullptr; + glDeleteBuffers(1, &screen_triangle); + glDeleteVertexArrays(1, &screen_triangle_array); + feed.shader.version_free(feed.shader_version); +} + +Transform3D transform3D_from_mat4(const float *p_mat4) { + Transform3D res; + + res.basis.rows[0][0] = p_mat4[0]; + res.basis.rows[1][0] = p_mat4[1]; + res.basis.rows[2][0] = p_mat4[2]; + // p_mat4[3] = 0; + res.basis.rows[0][1] = p_mat4[4]; + res.basis.rows[1][1] = p_mat4[5]; + res.basis.rows[2][1] = p_mat4[6]; + // p_mat4[7] = 0; + res.basis.rows[0][2] = p_mat4[8]; + res.basis.rows[1][2] = p_mat4[9]; + res.basis.rows[2][2] = p_mat4[10]; + // p_mat4[11] = 0; + res.origin.x = p_mat4[12]; + res.origin.y = p_mat4[13]; + res.origin.z = p_mat4[14]; + // p_mat4[15] = 1; + + return res; +} + +void FeedEffects::draw() { + bool success = feed.shader.version_bind_shader(feed.shader_version, FeedShaderGLES3::MODE_DEFAULT, FeedShaderGLES3::USE_EXTERNAL_SAMPLER); + if (!success) { + OS::get_singleton()->print("Godot : FeedShaderGLES3 Could not bind version_bind_shader USE_EXTERNAL_SAMPLER"); + return; + } + + draw_screen_triangle(); +} + +void FeedEffects::draw_screen_triangle() { + glBindVertexArray(screen_triangle_array); + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); +} + +#endif // GLES3_ENABLED diff --git a/drivers/gles3/effects/feed_effects.h b/drivers/gles3/effects/feed_effects.h new file mode 100644 index 0000000000..5856a3e04b --- /dev/null +++ b/drivers/gles3/effects/feed_effects.h @@ -0,0 +1,68 @@ +/**************************************************************************/ +/* feed_effects.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 FEED_EFFECTS_GLES3_H +#define FEED_EFFECTS_GLES3_H + +#ifdef GLES3_ENABLED + +#include "drivers/gles3/shaders/feed.glsl.gen.h" + +namespace GLES3 { + +class FeedEffects { +private: + struct Feed { + FeedShaderGLES3 shader; + RID shader_version; + } feed; + + static FeedEffects *singleton; + + GLuint screen_triangle = 0; + GLuint screen_triangle_array = 0; + +public: + static FeedEffects *get_singleton(); + + FeedEffects(); + ~FeedEffects(); + + void draw(); + +private: + void draw_screen_triangle(); +}; + +} // namespace GLES3 + +#endif // GLES3_ENABLED + +#endif // FEED_EFFECTS_GLES3_H diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 3c959f0143..0138f99d50 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1654,28 +1654,39 @@ void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, c return; } - for (int i = 0; i < 4; i++) { - glViewport((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2); + Projection projection; + { + real_t fov = 90; + real_t nearp = p_near; + real_t farp = p_far; + real_t aspect = 1.0; - Projection projection; - { - real_t fov = 90; - real_t nearp = p_near; - real_t farp = p_far; - real_t aspect = 1.0; + real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5)); + real_t ymin = -ymax; + real_t xmin = ymin * aspect; + real_t xmax = ymax * aspect; - real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5)); - real_t ymin = -ymax; - real_t xmin = ymin * aspect; - real_t xmax = ymax * aspect; + projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); + } - projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); - } + // Precomputed: + // Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); + // projection = projection * Projection(Transform3D().looking_at(cam_targets[i], Vector3(0, 0, -1)).affine_inverse()); + const Projection projections[4] = { + projection * Projection(Vector4(0, 0, -1, 0), Vector4(1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)), - Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); + projection * Projection(Vector4(-1, 0, 0, 0), Vector4(0, 0, -1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)), + + projection * Projection(Vector4(0, 0, 1, 0), Vector4(-1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)), + + projection * Projection(Vector4(1, 0, 0, 0), Vector4(0, 0, 1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)) + + }; + + for (int i = 0; i < 4; i++) { + glViewport((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2); - projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); - shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, projection, shadow_render.shader_version, variant); + shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, projections[i], shadow_render.shader_version, variant); static const Vector2 directions[4] = { Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0), Vector2(0, -1) }; shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::DIRECTION, directions[i].x, directions[i].y, shadow_render.shader_version, variant); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 843b6eac05..0fda42979f 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -218,6 +218,7 @@ void RasterizerGLES3::finalize() { memdelete(glow); memdelete(cubemap_filter); memdelete(copy_effects); + memdelete(feed_effects); memdelete(light_storage); memdelete(particles_storage); memdelete(mesh_storage); @@ -366,6 +367,7 @@ RasterizerGLES3::RasterizerGLES3() { cubemap_filter = memnew(GLES3::CubemapFilter); glow = memnew(GLES3::Glow); post_effects = memnew(GLES3::PostEffects); + feed_effects = memnew(GLES3::FeedEffects); gi = memnew(GLES3::GI); fog = memnew(GLES3::Fog); canvas = memnew(RasterizerCanvasGLES3()); diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index 6765d8b4d5..abda2a5e06 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -35,6 +35,7 @@ #include "effects/copy_effects.h" #include "effects/cubemap_filter.h" +#include "effects/feed_effects.h" #include "effects/glow.h" #include "effects/post_effects.h" #include "environment/fog.h" @@ -78,6 +79,7 @@ protected: GLES3::CubemapFilter *cubemap_filter = nullptr; GLES3::Glow *glow = nullptr; GLES3::PostEffects *post_effects = nullptr; + GLES3::FeedEffects *feed_effects = nullptr; RasterizerCanvasGLES3 *canvas = nullptr; RasterizerSceneGLES3 *scene = nullptr; static RasterizerGLES3 *singleton; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index a73f14c796..537076d4ed 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -31,6 +31,7 @@ #include "rasterizer_scene_gles3.h" #include "drivers/gles3/effects/copy_effects.h" +#include "drivers/gles3/effects/feed_effects.h" #include "rasterizer_gles3.h" #include "storage/config.h" #include "storage/mesh_storage.h" @@ -39,6 +40,8 @@ #include "core/config/project_settings.h" #include "core/templates/sort_array.h" +#include "servers/camera/camera_feed.h" +#include "servers/camera_server.h" #include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_globals.h" @@ -2259,6 +2262,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ render_data.inv_cam_transform = render_data.cam_transform.affine_inverse(); render_data.cam_projection = p_camera_data->main_projection; render_data.cam_orthogonal = p_camera_data->is_orthogonal; + render_data.cam_frustum = p_camera_data->is_frustum; render_data.camera_visible_layers = p_camera_data->visible_layers; render_data.main_cam_transform = p_camera_data->main_transform; @@ -2382,7 +2386,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ bool draw_sky = false; bool draw_sky_fog_only = false; bool keep_color = false; + bool draw_feed = false; float sky_energy_multiplier = 1.0; + int camera_feed_id = -1; if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black @@ -2427,6 +2433,8 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ keep_color = true; } break; case RS::ENV_BG_CAMERA_FEED: { + camera_feed_id = environment_get_camera_feed_id(render_data.environment); + draw_feed = true; } break; default: { } @@ -2538,7 +2546,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ glClear(GL_DEPTH_BUFFER_BIT); } - if (!keep_color) { + if (!keep_color && !draw_feed) { clear_color.a = render_data.transparent_bg ? 0.0f : 1.0f; glClearBufferfv(GL_COLOR, 0, clear_color.components); } else if (fbo != rt->fbo) { @@ -2578,6 +2586,29 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ spec_constant_base_flags |= SceneShaderGLES3::APPLY_TONEMAPPING; } } + + if (draw_feed && camera_feed_id > -1) { + RENDER_TIMESTAMP("Render Camera feed"); + + scene_state.enable_gl_depth_draw(false); + scene_state.enable_gl_depth_test(false); + scene_state.enable_gl_blend(false); + scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK); + + Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id); + + if (feed.is_valid()) { + RID camera_YCBCR = feed->get_texture(CameraServer::FEED_YCBCR_IMAGE); + GLES3::TextureStorage::get_singleton()->texture_bind(camera_YCBCR, 0); + + GLES3::FeedEffects *feed_effects = GLES3::FeedEffects::get_singleton(); + feed_effects->draw(); + } + scene_state.enable_gl_depth_draw(true); + scene_state.enable_gl_depth_test(true); + scene_state.enable_gl_blend(true); + } + // Render Opaque Objects. RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe); @@ -2592,14 +2623,18 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ scene_state.enable_gl_blend(false); scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK); + Transform3D transform = render_data.cam_transform; Projection projection = render_data.cam_projection; if (is_reflection_probe) { Projection correction; correction.columns[1][1] = -1.0; projection = correction * render_data.cam_projection; + } else if (render_data.cam_frustum) { + // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. + projection[2].y = -projection[2].y; } - _draw_sky(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier, render_data.luminance_multiplier, p_camera_data->view_count > 1, flip_y, apply_color_adjustments_in_post); + _draw_sky(render_data.environment, projection, transform, sky_energy_multiplier, render_data.luminance_multiplier, p_camera_data->view_count > 1, flip_y, apply_color_adjustments_in_post); } if (rt && (scene_state.used_screen_texture || scene_state.used_depth_texture)) { diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 06371b2b7f..4f088a0e7d 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -103,6 +103,7 @@ struct RenderDataGLES3 { Transform3D inv_cam_transform; Projection cam_projection; bool cam_orthogonal = false; + bool cam_frustum = false; uint32_t camera_visible_layers = 0xFFFFFFFF; // For billboards to cast correct shadows. diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub index df2c515035..0207ba12b7 100644 --- a/drivers/gles3/shaders/SCsub +++ b/drivers/gles3/shaders/SCsub @@ -17,6 +17,7 @@ if "GLES3_GLSL" in env["BUILDERS"]: # as we have a few, not yet, converted files we name the ones we want to include: env.GLES3_GLSL("canvas.glsl") + env.GLES3_GLSL("feed.glsl") env.GLES3_GLSL("scene.glsl") env.GLES3_GLSL("sky.glsl") env.GLES3_GLSL("canvas_occlusion.glsl") diff --git a/drivers/gles3/shaders/feed.glsl b/drivers/gles3/shaders/feed.glsl new file mode 100644 index 0000000000..9d89fc699d --- /dev/null +++ b/drivers/gles3/shaders/feed.glsl @@ -0,0 +1,39 @@ +/* clang-format off */ +#[modes] + +mode_default = + +#[specializations] + +USE_EXTERNAL_SAMPLER = false + +#[vertex] + +layout(location = 0) in vec2 vertex_attrib; + +out vec2 uv_interp; + + +void main() { + uv_interp = vertex_attrib * 0.5 + 0.5; + gl_Position = vec4(vertex_attrib, 1.0, 1.0); +} + +/* clang-format off */ +#[fragment] + +layout(location = 0) out vec4 frag_color; +in vec2 uv_interp; + +/* clang-format on */ +#ifdef USE_EXTERNAL_SAMPLER +uniform samplerExternalOES sourceFeed; // texunit:0 +#else +uniform sampler2D sourceFeed; // texunit:0 +#endif + +void main() { + vec4 color = texture(sourceFeed, uv_interp); + + frag_color = color; +} diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h index 086f5f7936..0552a5324f 100644 --- a/drivers/gles3/storage/particles_storage.h +++ b/drivers/gles3/storage/particles_storage.h @@ -396,7 +396,7 @@ public: _FORCE_INLINE_ bool particles_has_collision(RID p_particles) { Particles *particles = particles_owner.get_or_null(p_particles); - ERR_FAIL_NULL_V(particles, 0); + ERR_FAIL_NULL_V(particles, false); return particles->has_collision_cache; } diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h index fd7d93bbbd..5eda826d2a 100644 --- a/drivers/metal/metal_objects.h +++ b/drivers/metal/metal_objects.h @@ -82,6 +82,9 @@ MTL_CLASS(Texture) } //namespace MTL +/// Metal buffer index for the view mask when rendering multi-view. +const uint32_t VIEW_MASK_BUFFER_INDEX = 24; + enum ShaderStageUsage : uint32_t { None = 0, Vertex = RDD::SHADER_STAGE_VERTEX_BIT, @@ -142,6 +145,12 @@ struct ClearAttKey { const static uint32_t STENCIL_INDEX = DEPTH_INDEX + 1; const static uint32_t ATTACHMENT_COUNT = STENCIL_INDEX + 1; + enum Flags : uint16_t { + CLEAR_FLAGS_NONE = 0, + CLEAR_FLAGS_LAYERED = 1 << 0, + }; + + Flags flags = CLEAR_FLAGS_NONE; uint16_t sample_count = 0; uint16_t pixel_formats[ATTACHMENT_COUNT] = { 0 }; @@ -150,19 +159,22 @@ struct ClearAttKey { _FORCE_INLINE_ void set_stencil_format(MTLPixelFormat p_fmt) { pixel_formats[STENCIL_INDEX] = p_fmt; } _FORCE_INLINE_ MTLPixelFormat depth_format() const { return (MTLPixelFormat)pixel_formats[DEPTH_INDEX]; } _FORCE_INLINE_ MTLPixelFormat stencil_format() const { return (MTLPixelFormat)pixel_formats[STENCIL_INDEX]; } + _FORCE_INLINE_ void enable_layered_rendering() { flags::set(flags, CLEAR_FLAGS_LAYERED); } _FORCE_INLINE_ bool is_enabled(uint32_t p_idx) const { return pixel_formats[p_idx] != 0; } _FORCE_INLINE_ bool is_depth_enabled() const { return pixel_formats[DEPTH_INDEX] != 0; } _FORCE_INLINE_ bool is_stencil_enabled() const { return pixel_formats[STENCIL_INDEX] != 0; } + _FORCE_INLINE_ bool is_layered_rendering_enabled() const { return flags::any(flags, CLEAR_FLAGS_LAYERED); } _FORCE_INLINE_ bool operator==(const ClearAttKey &p_rhs) const { return memcmp(this, &p_rhs, sizeof(ClearAttKey)) == 0; } uint32_t hash() const { - uint32_t h = hash_murmur3_one_32(sample_count); + uint32_t h = hash_murmur3_one_32(flags); + h = hash_murmur3_one_32(sample_count, h); h = hash_murmur3_buffer(pixel_formats, ATTACHMENT_COUNT * sizeof(pixel_formats[0]), h); - return h; + return hash_fmix32(h); } }; @@ -206,6 +218,97 @@ public: ~MDResourceCache() = default; }; +enum class MDAttachmentType : uint8_t { + None = 0, + Color = 1 << 0, + Depth = 1 << 1, + Stencil = 1 << 2, +}; + +_FORCE_INLINE_ MDAttachmentType &operator|=(MDAttachmentType &p_a, MDAttachmentType p_b) { + flags::set(p_a, p_b); + return p_a; +} + +_FORCE_INLINE_ bool operator&(MDAttachmentType p_a, MDAttachmentType p_b) { + return uint8_t(p_a) & uint8_t(p_b); +} + +struct MDSubpass { + uint32_t subpass_index = 0; + uint32_t view_count = 0; + LocalVector<RDD::AttachmentReference> input_references; + LocalVector<RDD::AttachmentReference> color_references; + RDD::AttachmentReference depth_stencil_reference; + LocalVector<RDD::AttachmentReference> resolve_references; + + MTLFmtCaps getRequiredFmtCapsForAttachmentAt(uint32_t p_index) const; +}; + +struct API_AVAILABLE(macos(11.0), ios(14.0)) MDAttachment { +private: + uint32_t index = 0; + uint32_t firstUseSubpassIndex = 0; + uint32_t lastUseSubpassIndex = 0; + +public: + MTLPixelFormat format = MTLPixelFormatInvalid; + MDAttachmentType type = MDAttachmentType::None; + MTLLoadAction loadAction = MTLLoadActionDontCare; + MTLStoreAction storeAction = MTLStoreActionDontCare; + MTLLoadAction stencilLoadAction = MTLLoadActionDontCare; + MTLStoreAction stencilStoreAction = MTLStoreActionDontCare; + uint32_t samples = 1; + + /*! + * @brief Returns true if this attachment is first used in the given subpass. + * @param p_subpass + * @return + */ + _FORCE_INLINE_ bool isFirstUseOf(MDSubpass const &p_subpass) const { + return p_subpass.subpass_index == firstUseSubpassIndex; + } + + /*! + * @brief Returns true if this attachment is last used in the given subpass. + * @param p_subpass + * @return + */ + _FORCE_INLINE_ bool isLastUseOf(MDSubpass const &p_subpass) const { + return p_subpass.subpass_index == lastUseSubpassIndex; + } + + void linkToSubpass(MDRenderPass const &p_pass); + + MTLStoreAction getMTLStoreAction(MDSubpass const &p_subpass, + bool p_is_rendering_entire_area, + bool p_has_resolve, + bool p_can_resolve, + bool p_is_stencil) const; + bool configureDescriptor(MTLRenderPassAttachmentDescriptor *p_desc, + PixelFormats &p_pf, + MDSubpass const &p_subpass, + id<MTLTexture> p_attachment, + bool p_is_rendering_entire_area, + bool p_has_resolve, + bool p_can_resolve, + bool p_is_stencil) const; + /** Returns whether this attachment should be cleared in the subpass. */ + bool shouldClear(MDSubpass const &p_subpass, bool p_is_stencil) const; +}; + +class API_AVAILABLE(macos(11.0), ios(14.0)) MDRenderPass { +public: + Vector<MDAttachment> attachments; + Vector<MDSubpass> subpasses; + + uint32_t get_sample_count() const { + return attachments.is_empty() ? 1 : attachments[0].samples; + } + + MDRenderPass(Vector<MDAttachment> &p_attachments, Vector<MDSubpass> &p_subpasses); +}; + class API_AVAILABLE(macos(11.0), ios(14.0)) MDCommandBuffer { private: RenderingDeviceDriverMetal *device_driver = nullptr; @@ -220,8 +323,8 @@ private: void _render_set_dirty_state(); void _render_bind_uniform_sets(); - static void _populate_vertices(simd::float4 *p_vertices, Size2i p_fb_size, VectorView<Rect2i> p_rects); - static uint32_t _populate_vertices(simd::float4 *p_vertices, uint32_t p_index, Rect2i const &p_rect, Size2i p_fb_size); + void _populate_vertices(simd::float4 *p_vertices, Size2i p_fb_size, VectorView<Rect2i> p_rects); + uint32_t _populate_vertices(simd::float4 *p_vertices, uint32_t p_index, Rect2i const &p_rect, Size2i p_fb_size); void _end_render_pass(); void _render_clear_render_area(); @@ -268,34 +371,14 @@ public: // Bit mask of the uniform sets that are dirty, to prevent redundant binding. uint64_t uniform_set_mask = 0; - _FORCE_INLINE_ void reset() { - pass = nil; - frameBuffer = nil; - pipeline = nil; - current_subpass = UINT32_MAX; - render_area = {}; - is_rendering_entire_area = false; - desc = nil; - encoder = nil; - index_buffer = nil; - index_type = MTLIndexTypeUInt16; - dirty = DIRTY_NONE; - uniform_sets.clear(); - uniform_set_mask = 0; - clear_values.clear(); - viewports.clear(); - scissors.clear(); - blend_constants.reset(); - vertex_buffers.clear(); - vertex_offsets.clear(); - // Keep the keys, as they are likely to be used again. - for (KeyValue<StageResourceUsage, LocalVector<__unsafe_unretained id<MTLResource>>> &kv : resource_usage) { - kv.value.clear(); - } - } - + _FORCE_INLINE_ void reset(); void end_encoding(); + _ALWAYS_INLINE_ const MDSubpass &get_subpass() const { + DEV_ASSERT(pass != nullptr); + return pass->subpasses[current_subpass]; + } + _FORCE_INLINE_ void mark_viewport_dirty() { if (viewports.is_empty()) { return; @@ -649,6 +732,7 @@ public: uint32_t size = 0; } frag; } push_constants; + bool needs_view_mask_buffer = false; MDLibrary *vert; MDLibrary *frag; @@ -659,7 +743,10 @@ public: void encode_push_constant_data(VectorView<uint32_t> p_data, MDCommandBuffer *p_cb) final; - MDRenderShader(CharString p_name, Vector<UniformSet> p_sets, MDLibrary *p_vert, MDLibrary *p_frag); + MDRenderShader(CharString p_name, + bool p_needs_view_mask_buffer, + Vector<UniformSet> p_sets, + MDLibrary *p_vert, MDLibrary *p_frag); }; _FORCE_INLINE_ StageResourceUsage &operator|=(StageResourceUsage &p_a, uint32_t p_b) { @@ -702,96 +789,6 @@ public: BoundUniformSet &boundUniformSetForShader(MDShader *p_shader, id<MTLDevice> p_device); }; -enum class MDAttachmentType : uint8_t { - None = 0, - Color = 1 << 0, - Depth = 1 << 1, - Stencil = 1 << 2, -}; - -_FORCE_INLINE_ MDAttachmentType &operator|=(MDAttachmentType &p_a, MDAttachmentType p_b) { - flags::set(p_a, p_b); - return p_a; -} - -_FORCE_INLINE_ bool operator&(MDAttachmentType p_a, MDAttachmentType p_b) { - return uint8_t(p_a) & uint8_t(p_b); -} - -struct MDSubpass { - uint32_t subpass_index = 0; - LocalVector<RDD::AttachmentReference> input_references; - LocalVector<RDD::AttachmentReference> color_references; - RDD::AttachmentReference depth_stencil_reference; - LocalVector<RDD::AttachmentReference> resolve_references; - - MTLFmtCaps getRequiredFmtCapsForAttachmentAt(uint32_t p_index) const; -}; - -struct API_AVAILABLE(macos(11.0), ios(14.0)) MDAttachment { -private: - uint32_t index = 0; - uint32_t firstUseSubpassIndex = 0; - uint32_t lastUseSubpassIndex = 0; - -public: - MTLPixelFormat format = MTLPixelFormatInvalid; - MDAttachmentType type = MDAttachmentType::None; - MTLLoadAction loadAction = MTLLoadActionDontCare; - MTLStoreAction storeAction = MTLStoreActionDontCare; - MTLLoadAction stencilLoadAction = MTLLoadActionDontCare; - MTLStoreAction stencilStoreAction = MTLStoreActionDontCare; - uint32_t samples = 1; - - /*! - * @brief Returns true if this attachment is first used in the given subpass. - * @param p_subpass - * @return - */ - _FORCE_INLINE_ bool isFirstUseOf(MDSubpass const &p_subpass) const { - return p_subpass.subpass_index == firstUseSubpassIndex; - } - - /*! - * @brief Returns true if this attachment is last used in the given subpass. - * @param p_subpass - * @return - */ - _FORCE_INLINE_ bool isLastUseOf(MDSubpass const &p_subpass) const { - return p_subpass.subpass_index == lastUseSubpassIndex; - } - - void linkToSubpass(MDRenderPass const &p_pass); - - MTLStoreAction getMTLStoreAction(MDSubpass const &p_subpass, - bool p_is_rendering_entire_area, - bool p_has_resolve, - bool p_can_resolve, - bool p_is_stencil) const; - bool configureDescriptor(MTLRenderPassAttachmentDescriptor *p_desc, - PixelFormats &p_pf, - MDSubpass const &p_subpass, - id<MTLTexture> p_attachment, - bool p_is_rendering_entire_area, - bool p_has_resolve, - bool p_can_resolve, - bool p_is_stencil) const; - /** Returns whether this attachment should be cleared in the subpass. */ - bool shouldClear(MDSubpass const &p_subpass, bool p_is_stencil) const; -}; - -class API_AVAILABLE(macos(11.0), ios(14.0)) MDRenderPass { -public: - Vector<MDAttachment> attachments; - Vector<MDSubpass> subpasses; - - uint32_t get_sample_count() const { - return attachments.is_empty() ? 1 : attachments[0].samples; - } - - MDRenderPass(Vector<MDAttachment> &p_attachments, Vector<MDSubpass> &p_subpasses); -}; - class API_AVAILABLE(macos(11.0), ios(14.0)) MDPipeline { public: MDPipelineType type; @@ -892,13 +889,39 @@ public: }; class API_AVAILABLE(macos(11.0), ios(14.0)) MDFrameBuffer { -public: Vector<MTL::Texture> textures; + +public: Size2i size; MDFrameBuffer(Vector<MTL::Texture> p_textures, Size2i p_size) : textures(p_textures), size(p_size) {} MDFrameBuffer() {} + /// Returns the texture at the given index. + _ALWAYS_INLINE_ MTL::Texture get_texture(uint32_t p_idx) const { + return textures[p_idx]; + } + + /// Returns true if the texture at the given index is not nil. + _ALWAYS_INLINE_ bool has_texture(uint32_t p_idx) const { + return textures[p_idx] != nil; + } + + /// Set the texture at the given index. + _ALWAYS_INLINE_ void set_texture(uint32_t p_idx, MTL::Texture p_texture) { + textures.write[p_idx] = p_texture; + } + + /// Unset or nil the texture at the given index. + _ALWAYS_INLINE_ void unset_texture(uint32_t p_idx) { + textures.write[p_idx] = nil; + } + + /// Resizes buffers to the specified size. + _ALWAYS_INLINE_ void set_texture_count(uint32_t p_size) { + textures.resize(p_size); + } + virtual ~MDFrameBuffer() = default; }; diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm index c3906af159..11ab209d60 100644 --- a/drivers/metal/metal_objects.mm +++ b/drivers/metal/metal_objects.mm @@ -96,6 +96,9 @@ void MDCommandBuffer::bind_pipeline(RDD::PipelineID p_pipeline) { MDRenderPipeline *rp = (MDRenderPipeline *)p; if (render.encoder == nil) { + // This error would happen if the render pass failed. + ERR_FAIL_NULL_MSG(render.desc, "Render pass descriptor is null."); + // This condition occurs when there are no attachments when calling render_next_subpass() // and is due to the SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS flag. render.desc.defaultRasterSampleCount = static_cast<NSUInteger>(rp->sample_count); @@ -223,8 +226,9 @@ void MDCommandBuffer::render_bind_uniform_set(RDD::UniformSetID p_uniform_set, R void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear> p_attachment_clears, VectorView<Rect2i> p_rects) { DEV_ASSERT(type == MDCommandBufferStateType::Render); - uint32_t vertex_count = p_rects.size() * 6; + const MDSubpass &subpass = render.get_subpass(); + uint32_t vertex_count = p_rects.size() * 6 * subpass.view_count; simd::float4 vertices[vertex_count]; simd::float4 clear_colors[ClearAttKey::ATTACHMENT_COUNT]; @@ -235,6 +239,9 @@ void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear> ClearAttKey key; key.sample_count = render.pass->get_sample_count(); + if (subpass.view_count > 1) { + key.enable_layered_rendering(); + } float depth_value = 0; uint32_t stencil_value = 0; @@ -245,7 +252,7 @@ void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear> if (attClear.aspect.has_flag(RDD::TEXTURE_ASPECT_COLOR_BIT)) { attachment_index = attClear.color_attachment; } else { - attachment_index = render.pass->subpasses[render.current_subpass].depth_stencil_reference.attachment; + attachment_index = subpass.depth_stencil_reference.attachment; } MDAttachment const &mda = render.pass->attachments[attachment_index]; @@ -310,6 +317,13 @@ void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear> void MDCommandBuffer::_render_set_dirty_state() { _render_bind_uniform_sets(); + MDSubpass const &subpass = render.get_subpass(); + if (subpass.view_count > 1) { + uint32_t view_range[2] = { 0, subpass.view_count }; + [render.encoder setVertexBytes:view_range length:sizeof(view_range) atIndex:VIEW_MASK_BUFFER_INDEX]; + [render.encoder setFragmentBytes:view_range length:sizeof(view_range) atIndex:VIEW_MASK_BUFFER_INDEX]; + } + if (render.dirty.has_flag(RenderState::DIRTY_PIPELINE)) { [render.encoder setRenderPipelineState:render.pipeline->state]; } @@ -492,36 +506,40 @@ uint32_t MDCommandBuffer::_populate_vertices(simd::float4 *p_vertices, uint32_t simd::float4 vtx; uint32_t idx = p_index; - vtx.z = 0.0; - vtx.w = (float)1; + uint32_t endLayer = render.get_subpass().view_count; + + for (uint32_t layer = 0; layer < endLayer; layer++) { + vtx.z = 0.0; + vtx.w = (float)layer; - // Top left vertex - First triangle. - vtx.y = topPos; - vtx.x = leftPos; - p_vertices[idx++] = vtx; + // Top left vertex - First triangle. + vtx.y = topPos; + vtx.x = leftPos; + p_vertices[idx++] = vtx; - // Bottom left vertex. - vtx.y = bottomPos; - vtx.x = leftPos; - p_vertices[idx++] = vtx; + // Bottom left vertex. + vtx.y = bottomPos; + vtx.x = leftPos; + p_vertices[idx++] = vtx; - // Bottom right vertex. - vtx.y = bottomPos; - vtx.x = rightPos; - p_vertices[idx++] = vtx; + // Bottom right vertex. + vtx.y = bottomPos; + vtx.x = rightPos; + p_vertices[idx++] = vtx; - // Bottom right vertex - Second triangle. - p_vertices[idx++] = vtx; + // Bottom right vertex - Second triangle. + p_vertices[idx++] = vtx; - // Top right vertex. - vtx.y = topPos; - vtx.x = rightPos; - p_vertices[idx++] = vtx; + // Top right vertex. + vtx.y = topPos; + vtx.x = rightPos; + p_vertices[idx++] = vtx; - // Top left vertex. - vtx.y = topPos; - vtx.x = leftPos; - p_vertices[idx++] = vtx; + // Top left vertex. + vtx.y = topPos; + vtx.x = leftPos; + p_vertices[idx++] = vtx; + } return idx; } @@ -548,8 +566,7 @@ void MDCommandBuffer::render_begin_pass(RDD::RenderPassID p_render_pass, RDD::Fr void MDCommandBuffer::_end_render_pass() { MDFrameBuffer const &fb_info = *render.frameBuffer; - MDRenderPass const &pass_info = *render.pass; - MDSubpass const &subpass = pass_info.subpasses[render.current_subpass]; + MDSubpass const &subpass = render.get_subpass(); PixelFormats &pf = device_driver->get_pixel_formats(); @@ -557,11 +574,11 @@ void MDCommandBuffer::_end_render_pass() { uint32_t color_index = subpass.color_references[i].attachment; uint32_t resolve_index = subpass.resolve_references[i].attachment; DEV_ASSERT((color_index == RDD::AttachmentReference::UNUSED) == (resolve_index == RDD::AttachmentReference::UNUSED)); - if (color_index == RDD::AttachmentReference::UNUSED || !fb_info.textures[color_index]) { + if (color_index == RDD::AttachmentReference::UNUSED || !fb_info.has_texture(color_index)) { continue; } - id<MTLTexture> resolve_tex = fb_info.textures[resolve_index]; + id<MTLTexture> resolve_tex = fb_info.get_texture(resolve_index); CRASH_COND_MSG(!flags::all(pf.getCapabilities(resolve_tex.pixelFormat), kMTLFmtCapsResolve), "not implemented: unresolvable texture types"); // see: https://github.com/KhronosGroup/MoltenVK/blob/d20d13fe2735adb845636a81522df1b9d89c0fba/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm#L407 @@ -572,7 +589,7 @@ void MDCommandBuffer::_end_render_pass() { void MDCommandBuffer::_render_clear_render_area() { MDRenderPass const &pass = *render.pass; - MDSubpass const &subpass = pass.subpasses[render.current_subpass]; + MDSubpass const &subpass = render.get_subpass(); // First determine attachments that should be cleared. LocalVector<RDD::AttachmentClear> clears; @@ -619,9 +636,14 @@ void MDCommandBuffer::render_next_subpass() { MDFrameBuffer const &fb = *render.frameBuffer; MDRenderPass const &pass = *render.pass; - MDSubpass const &subpass = pass.subpasses[render.current_subpass]; + MDSubpass const &subpass = render.get_subpass(); MTLRenderPassDescriptor *desc = MTLRenderPassDescriptor.renderPassDescriptor; + + if (subpass.view_count > 1) { + desc.renderTargetArrayLength = subpass.view_count; + } + PixelFormats &pf = device_driver->get_pixel_formats(); uint32_t attachmentCount = 0; @@ -638,7 +660,7 @@ void MDCommandBuffer::render_next_subpass() { bool has_resolve = resolveIdx != RDD::AttachmentReference::UNUSED; bool can_resolve = true; if (resolveIdx != RDD::AttachmentReference::UNUSED) { - id<MTLTexture> resolve_tex = fb.textures[resolveIdx]; + id<MTLTexture> resolve_tex = fb.get_texture(resolveIdx); can_resolve = flags::all(pf.getCapabilities(resolve_tex.pixelFormat), kMTLFmtCapsResolve); if (can_resolve) { ca.resolveTexture = resolve_tex; @@ -649,7 +671,9 @@ void MDCommandBuffer::render_next_subpass() { MDAttachment const &attachment = pass.attachments[idx]; - id<MTLTexture> tex = fb.textures[idx]; + id<MTLTexture> tex = fb.get_texture(idx); + ERR_FAIL_NULL_MSG(tex, "Frame buffer color texture is null."); + if ((attachment.type & MDAttachmentType::Color)) { if (attachment.configureDescriptor(ca, pf, subpass, tex, render.is_rendering_entire_area, has_resolve, can_resolve, false)) { Color clearColor = render.clear_values[idx].color; @@ -662,7 +686,8 @@ void MDCommandBuffer::render_next_subpass() { attachmentCount += 1; uint32_t idx = subpass.depth_stencil_reference.attachment; MDAttachment const &attachment = pass.attachments[idx]; - id<MTLTexture> tex = fb.textures[idx]; + id<MTLTexture> tex = fb.get_texture(idx); + ERR_FAIL_NULL_MSG(tex, "Frame buffer depth / stencil texture is null."); if (attachment.type & MDAttachmentType::Depth) { MTLRenderPassDepthAttachmentDescriptor *da = desc.depthAttachment; if (attachment.configureDescriptor(da, pf, subpass, tex, render.is_rendering_entire_area, false, false, false)) { @@ -702,8 +727,15 @@ void MDCommandBuffer::render_draw(uint32_t p_vertex_count, uint32_t p_base_vertex, uint32_t p_first_instance) { DEV_ASSERT(type == MDCommandBufferStateType::Render); + ERR_FAIL_NULL_MSG(render.pipeline, "No pipeline set for render command buffer."); + _render_set_dirty_state(); + MDSubpass const &subpass = render.get_subpass(); + if (subpass.view_count > 1) { + p_instance_count *= subpass.view_count; + } + DEV_ASSERT(render.dirty == 0); id<MTLRenderCommandEncoder> enc = render.encoder; @@ -751,8 +783,15 @@ void MDCommandBuffer::render_draw_indexed(uint32_t p_index_count, int32_t p_vertex_offset, uint32_t p_first_instance) { DEV_ASSERT(type == MDCommandBufferStateType::Render); + ERR_FAIL_NULL_MSG(render.pipeline, "No pipeline set for render command buffer."); + _render_set_dirty_state(); + MDSubpass const &subpass = render.get_subpass(); + if (subpass.view_count > 1) { + p_instance_count *= subpass.view_count; + } + id<MTLRenderCommandEncoder> enc = render.encoder; uint32_t index_offset = render.index_offset; @@ -770,6 +809,8 @@ void MDCommandBuffer::render_draw_indexed(uint32_t p_index_count, void MDCommandBuffer::render_draw_indexed_indirect(RDD::BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) { DEV_ASSERT(type == MDCommandBufferStateType::Render); + ERR_FAIL_NULL_MSG(render.pipeline, "No pipeline set for render command buffer."); + _render_set_dirty_state(); id<MTLRenderCommandEncoder> enc = render.encoder; @@ -794,6 +835,8 @@ void MDCommandBuffer::render_draw_indexed_indirect_count(RDD::BufferID p_indirec void MDCommandBuffer::render_draw_indirect(RDD::BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) { DEV_ASSERT(type == MDCommandBufferStateType::Render); + ERR_FAIL_NULL_MSG(render.pipeline, "No pipeline set for render command buffer."); + _render_set_dirty_state(); id<MTLRenderCommandEncoder> enc = render.encoder; @@ -813,6 +856,42 @@ void MDCommandBuffer::render_draw_indirect_count(RDD::BufferID p_indirect_buffer ERR_FAIL_MSG("not implemented"); } +void MDCommandBuffer::render_end_pass() { + DEV_ASSERT(type == MDCommandBufferStateType::Render); + + render.end_encoding(); + render.reset(); + type = MDCommandBufferStateType::None; +} + +#pragma mark - RenderState + +void MDCommandBuffer::RenderState::reset() { + pass = nil; + frameBuffer = nil; + pipeline = nil; + current_subpass = UINT32_MAX; + render_area = {}; + is_rendering_entire_area = false; + desc = nil; + encoder = nil; + index_buffer = nil; + index_type = MTLIndexTypeUInt16; + dirty = DIRTY_NONE; + uniform_sets.clear(); + uniform_set_mask = 0; + clear_values.clear(); + viewports.clear(); + scissors.clear(); + blend_constants.reset(); + vertex_buffers.clear(); + vertex_offsets.clear(); + // Keep the keys, as they are likely to be used again. + for (KeyValue<StageResourceUsage, LocalVector<__unsafe_unretained id<MTLResource>>> &kv : resource_usage) { + kv.value.clear(); + } +} + void MDCommandBuffer::RenderState::end_encoding() { if (encoder == nil) { return; @@ -842,6 +921,8 @@ void MDCommandBuffer::RenderState::end_encoding() { encoder = nil; } +#pragma mark - ComputeState + void MDCommandBuffer::ComputeState::end_encoding() { if (encoder == nil) { return; @@ -862,14 +943,6 @@ void MDCommandBuffer::ComputeState::end_encoding() { encoder = nil; } -void MDCommandBuffer::render_end_pass() { - DEV_ASSERT(type == MDCommandBufferStateType::Render); - - render.end_encoding(); - render.reset(); - type = MDCommandBufferStateType::None; -} - #pragma mark - Compute void MDCommandBuffer::compute_bind_uniform_set(RDD::UniformSetID p_uniform_set, RDD::ShaderID p_shader, uint32_t p_set_index) { @@ -943,8 +1016,11 @@ void MDComputeShader::encode_push_constant_data(VectorView<uint32_t> p_data, MDC [enc setBytes:ptr length:length atIndex:push_constants.binding]; } -MDRenderShader::MDRenderShader(CharString p_name, Vector<UniformSet> p_sets, MDLibrary *_Nonnull p_vert, MDLibrary *_Nonnull p_frag) : - MDShader(p_name, p_sets), vert(p_vert), frag(p_frag) { +MDRenderShader::MDRenderShader(CharString p_name, + bool p_needs_view_mask_buffer, + Vector<UniformSet> p_sets, + MDLibrary *_Nonnull p_vert, MDLibrary *_Nonnull p_frag) : + MDShader(p_name, p_sets), needs_view_mask_buffer(p_needs_view_mask_buffer), vert(p_vert), frag(p_frag) { } void MDRenderShader::encode_push_constant_data(VectorView<uint32_t> p_data, MDCommandBuffer *p_cb) { @@ -1279,7 +1355,7 @@ typedef struct { typedef struct { float4 v_position [[position]]; - uint layer; + uint layer%s; } VaryingsPos; vertex VaryingsPos vertClear(AttributesPos attributes [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) { @@ -1288,7 +1364,7 @@ vertex VaryingsPos vertClear(AttributesPos attributes [[stage_in]], constant Cle varyings.layer = uint(attributes.a_position.w); return varyings; } -)", ClearAttKey::DEPTH_INDEX]; +)", p_key.is_layered_rendering_enabled() ? " [[render_target_array_index]]" : "", ClearAttKey::DEPTH_INDEX]; return new_func(msl, @"vertClear", nil); } @@ -1578,7 +1654,7 @@ void ShaderCacheEntry::notify_free() const { self->_library = library; self->_error = error; if (error) { - ERR_PRINT(String(U"Error compiling shader %s: %s").format(entry->name.get_data(), error.localizedDescription.UTF8String)); + ERR_PRINT(vformat(U"Error compiling shader %s: %s", entry->name.get_data(), error.localizedDescription.UTF8String)); } { diff --git a/drivers/metal/rendering_context_driver_metal.mm b/drivers/metal/rendering_context_driver_metal.mm index b97b586352..cf8c7e1c83 100644 --- a/drivers/metal/rendering_context_driver_metal.mm +++ b/drivers/metal/rendering_context_driver_metal.mm @@ -134,7 +134,7 @@ public: frame_buffers.resize(p_desired_framebuffer_count); for (uint32_t i = 0; i < p_desired_framebuffer_count; i++) { // Reserve space for the drawable texture. - frame_buffers[i].textures.resize(1); + frame_buffers[i].set_texture_count(1); } return OK; @@ -154,7 +154,7 @@ public: id<CAMetalDrawable> drawable = layer.nextDrawable; ERR_FAIL_NULL_V_MSG(drawable, RDD::FramebufferID(), "no drawable available"); drawables[rear] = drawable; - frame_buffer.textures.write[0] = drawable.texture; + frame_buffer.set_texture(0, drawable.texture); return RDD::FramebufferID(&frame_buffer); } @@ -165,7 +165,7 @@ public: } // Release texture and drawable. - frame_buffers[front].textures.write[0] = nil; + frame_buffers[front].unset_texture(0); id<MTLDrawable> drawable = drawables[front]; drawables[front] = nil; diff --git a/drivers/metal/rendering_device_driver_metal.h b/drivers/metal/rendering_device_driver_metal.h index f62a164ef9..e238de958e 100644 --- a/drivers/metal/rendering_device_driver_metal.h +++ b/drivers/metal/rendering_device_driver_metal.h @@ -239,7 +239,13 @@ private: friend struct PushConstantData; private: - Error _reflect_spirv16(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection); + /// Contains additional metadata about the shader. + struct ShaderMeta { + /// Indicates whether the shader uses multiview. + bool has_multiview = false; + }; + + Error _reflect_spirv16(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection, ShaderMeta &r_shader_meta); public: virtual String shader_get_binary_cache_key() override final; diff --git a/drivers/metal/rendering_device_driver_metal.mm b/drivers/metal/rendering_device_driver_metal.mm index 4da11ecd21..d90f528a14 100644 --- a/drivers/metal/rendering_device_driver_metal.mm +++ b/drivers/metal/rendering_device_driver_metal.mm @@ -1026,7 +1026,7 @@ void RenderingDeviceDriverMetal::framebuffer_free(FramebufferID p_framebuffer) { #pragma mark - Shader -const uint32_t SHADER_BINARY_VERSION = 1; +const uint32_t SHADER_BINARY_VERSION = 2; // region Serialization @@ -1503,6 +1503,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0)) ShaderBinaryData { uint32_t fragment_output_mask = UINT32_MAX; uint32_t spirv_specialization_constants_ids_mask = UINT32_MAX; uint32_t is_compute = UINT32_MAX; + uint32_t needs_view_mask_buffer = UINT32_MAX; ComputeSize compute_local_size; PushConstantData push_constant; LocalVector<ShaderStageData> stages; @@ -1523,6 +1524,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0)) ShaderBinaryData { size += sizeof(uint32_t); // fragment_output_mask size += sizeof(uint32_t); // spirv_specialization_constants_ids_mask size += sizeof(uint32_t); // is_compute + size += sizeof(uint32_t); // needs_view_mask_buffer size += compute_local_size.serialize_size(); // compute_local_size size += push_constant.serialize_size(); // push_constant size += sizeof(uint32_t); // stages.size() @@ -1547,6 +1549,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0)) ShaderBinaryData { p_writer.write(fragment_output_mask); p_writer.write(spirv_specialization_constants_ids_mask); p_writer.write(is_compute); + p_writer.write(needs_view_mask_buffer); p_writer.write(compute_local_size); p_writer.write(push_constant); p_writer.write(VectorView(stages)); @@ -1561,6 +1564,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0)) ShaderBinaryData { p_reader.read(fragment_output_mask); p_reader.read(spirv_specialization_constants_ids_mask); p_reader.read(is_compute); + p_reader.read(needs_view_mask_buffer); p_reader.read(compute_local_size); p_reader.read(push_constant); p_reader.read(stages); @@ -1572,14 +1576,16 @@ struct API_AVAILABLE(macos(11.0), ios(14.0)) ShaderBinaryData { // endregion String RenderingDeviceDriverMetal::shader_get_binary_cache_key() { - return "Metal-SV" + uitos(SHADER_BINARY_VERSION); + static const String cache_key = "Metal-SV" + uitos(SHADER_BINARY_VERSION); + return cache_key; } -Error RenderingDeviceDriverMetal::_reflect_spirv16(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection) { +Error RenderingDeviceDriverMetal::_reflect_spirv16(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection, ShaderMeta &r_shader_meta) { using namespace spirv_cross; using spirv_cross::Resource; r_reflection = {}; + r_shader_meta = {}; for (uint32_t i = 0; i < p_spirv.size(); i++) { ShaderStageSPIRVData const &v = p_spirv[i]; @@ -1811,6 +1817,20 @@ Error RenderingDeviceDriverMetal::_reflect_spirv16(VectorView<ShaderStageSPIRVDa } } + for (const BuiltInResource &res : resources.builtin_inputs) { + if (res.builtin == spv::BuiltInViewIndex || res.builtin == spv::BuiltInViewportIndex) { + r_shader_meta.has_multiview = true; + } + } + + if (!r_shader_meta.has_multiview) { + for (const BuiltInResource &res : resources.builtin_outputs) { + if (res.builtin == spv::BuiltInViewIndex || res.builtin == spv::BuiltInViewportIndex) { + r_shader_meta.has_multiview = true; + } + } + } + // Specialization constants. for (SpecializationConstant const &constant : compiler.get_specialization_constants()) { int32_t existing = -1; @@ -1874,7 +1894,8 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec using spirv_cross::Resource; ShaderReflection spirv_data; - ERR_FAIL_COND_V(_reflect_spirv16(p_spirv, spirv_data), Result()); + ShaderMeta shader_meta; + ERR_FAIL_COND_V(_reflect_spirv16(p_spirv, spirv_data, shader_meta), Result()); ShaderBinaryData bin_data{}; if (!p_shader_name.is_empty()) { @@ -1893,6 +1914,7 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec bin_data.is_compute = spirv_data.is_compute; bin_data.push_constant.size = spirv_data.push_constant_size; bin_data.push_constant.stages = (ShaderStageUsage)(uint8_t)spirv_data.push_constant_stages; + bin_data.needs_view_mask_buffer = shader_meta.has_multiview ? 1 : 0; for (uint32_t i = 0; i < spirv_data.uniform_sets.size(); i++) { const ::Vector<ShaderUniform> &spirv_set = spirv_data.uniform_sets[i]; @@ -1947,6 +1969,11 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec msl_options.pad_fragment_output_components = true; msl_options.r32ui_alignment_constant_id = R32UI_ALIGNMENT_CONSTANT_ID; msl_options.agx_manual_cube_grad_fixup = true; + if (shader_meta.has_multiview) { + msl_options.multiview = true; + msl_options.multiview_layered_rendering = true; + msl_options.view_mask_buffer_index = VIEW_MASK_BUFFER_INDEX; + } CompilerGLSL::Options options{}; options.vertex.flip_vert_y = true; @@ -2448,7 +2475,7 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect #endif shader = cs; } else { - MDRenderShader *rs = new MDRenderShader(binary_data.shader_name, uniform_sets, libraries[ShaderStage::SHADER_STAGE_VERTEX], libraries[ShaderStage::SHADER_STAGE_FRAGMENT]); + MDRenderShader *rs = new MDRenderShader(binary_data.shader_name, (bool)binary_data.needs_view_mask_buffer, uniform_sets, libraries[ShaderStage::SHADER_STAGE_VERTEX], libraries[ShaderStage::SHADER_STAGE_FRAGMENT]); uint32_t *vert_binding = binary_data.push_constant.msl_binding.getptr(SHADER_STAGE_VERTEX); if (vert_binding) { @@ -2956,6 +2983,7 @@ RDD::RenderPassID RenderingDeviceDriverMetal::render_pass_create(VectorView<Atta for (uint32_t i = 0; i < subpass_count; i++) { MDSubpass &subpass = subpasses.write[i]; subpass.subpass_index = i; + subpass.view_count = p_view_count; subpass.input_references = p_subpasses[i].input_references; subpass.color_references = p_subpasses[i].color_references; subpass.depth_stencil_reference = p_subpasses[i].depth_stencil_reference; @@ -3675,8 +3703,7 @@ void RenderingDeviceDriverMetal::set_object_name(ObjectType p_type, ID p_driver_ uint64_t RenderingDeviceDriverMetal::get_resource_native_handle(DriverResource p_type, ID p_driver_id) { switch (p_type) { case DRIVER_RESOURCE_LOGICAL_DEVICE: { - uintptr_t devicePtr = (uintptr_t)(__bridge void *)device; - return (uint64_t)devicePtr; + return (uint64_t)(uintptr_t)(__bridge void *)device; } case DRIVER_RESOURCE_PHYSICAL_DEVICE: { return 0; @@ -3685,7 +3712,7 @@ uint64_t RenderingDeviceDriverMetal::get_resource_native_handle(DriverResource p return 0; } case DRIVER_RESOURCE_COMMAND_QUEUE: { - return 0; + return (uint64_t)(uintptr_t)(__bridge void *)device_queue; } case DRIVER_RESOURCE_QUEUE_FAMILY: { return 0; @@ -3702,15 +3729,20 @@ uint64_t RenderingDeviceDriverMetal::get_resource_native_handle(DriverResource p case DRIVER_RESOURCE_SAMPLER: { return p_driver_id.id; } - case DRIVER_RESOURCE_UNIFORM_SET: + case DRIVER_RESOURCE_UNIFORM_SET: { return 0; + } case DRIVER_RESOURCE_BUFFER: { return p_driver_id.id; } - case DRIVER_RESOURCE_COMPUTE_PIPELINE: - return 0; - case DRIVER_RESOURCE_RENDER_PIPELINE: - return 0; + case DRIVER_RESOURCE_COMPUTE_PIPELINE: { + MDComputePipeline *pipeline = (MDComputePipeline *)(p_driver_id.id); + return (uint64_t)(uintptr_t)(__bridge void *)pipeline->state; + } + case DRIVER_RESOURCE_RENDER_PIPELINE: { + MDRenderPipeline *pipeline = (MDRenderPipeline *)(p_driver_id.id); + return (uint64_t)(uintptr_t)(__bridge void *)pipeline->state; + } default: { return 0; } @@ -3842,7 +3874,7 @@ uint64_t RenderingDeviceDriverMetal::api_trait_get(ApiTrait p_trait) { bool RenderingDeviceDriverMetal::has_feature(Features p_feature) { switch (p_feature) { case SUPPORTS_MULTIVIEW: - return false; + return multiview_capabilities.is_supported; case SUPPORTS_FSR_HALF_FLOAT: return true; case SUPPORTS_ATTACHMENT_VRS: @@ -3951,6 +3983,18 @@ Error RenderingDeviceDriverMetal::initialize(uint32_t p_device_index, uint32_t p metal_device_properties = memnew(MetalDeviceProperties(device)); pixel_formats = memnew(PixelFormats(device)); + if (metal_device_properties->features.layeredRendering) { + multiview_capabilities.is_supported = true; + multiview_capabilities.max_view_count = metal_device_properties->limits.maxViewports; + // NOTE: I'm not sure what the limit is as I don't see it referenced anywhere + multiview_capabilities.max_instance_count = UINT32_MAX; + + print_verbose("- Metal multiview supported:"); + print_verbose(" max view count: " + itos(multiview_capabilities.max_view_count)); + print_verbose(" max instances: " + itos(multiview_capabilities.max_instance_count)); + } else { + print_verbose("- Metal multiview not supported"); + } // Check required features and abort if any of them is missing. if (!metal_device_properties->features.imageCubeArray) { diff --git a/drivers/png/SCsub b/drivers/png/SCsub index fce37257b1..4268a66475 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -46,18 +46,18 @@ if env["builtin_libpng"]: if "S_compiler" in env: env_neon["CC"] = env["S_compiler"] neon_sources = [] - neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/arm_init.c")) - neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/filter_neon_intrinsics.c")) - neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/filter_neon.S")) - neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/palette_neon_intrinsics.c")) + neon_sources.append(env_neon.Object(thirdparty_dir + "arm/arm_init.c")) + neon_sources.append(env_neon.Object(thirdparty_dir + "arm/filter_neon_intrinsics.c")) + neon_sources.append(env_neon.Object(thirdparty_dir + "arm/filter_neon.S")) + neon_sources.append(env_neon.Object(thirdparty_dir + "arm/palette_neon_intrinsics.c")) thirdparty_obj += neon_sources elif env["arch"].startswith("x86"): env_thirdparty.Append(CPPDEFINES=["PNG_INTEL_SSE"]) - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/intel/intel_init.c") - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/intel/filter_sse2_intrinsics.c") + env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "intel/intel_init.c") + env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "intel/filter_sse2_intrinsics.c") elif env["arch"] == "ppc64": - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/powerpc/powerpc_init.c") - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/powerpc/filter_vsx_intrinsics.c") + env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "powerpc/powerpc_init.c") + env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "powerpc/filter_vsx_intrinsics.c") env.drivers_sources += thirdparty_obj diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 3d584341ed..43ad0799ba 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -41,6 +41,11 @@ #include <sys/types.h> #include <unistd.h> +#if defined(TOOLS_ENABLED) +#include <limits.h> +#include <stdlib.h> +#endif + void FileAccessUnix::check_errors() const { ERR_FAIL_NULL_MSG(f, "File must be opened before use."); @@ -87,6 +92,22 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) { } } +#if defined(TOOLS_ENABLED) + if (p_mode_flags & READ) { + String real_path = get_real_path(); + if (real_path != path) { + // Don't warn on symlinks, since they can be used to simply share addons on multiple projects. + if (real_path.to_lower() == path.to_lower()) { + // The File system is case insensitive, but other platforms can be sensitive to it + // To ease cross-platform development, we issue a warning if users try to access + // a file using the wrong case (which *works* on Windows and macOS, but won't on other + // platforms). + WARN_PRINT(vformat("Case mismatch opening requested file '%s', stored as '%s' in the filesystem. This file will not open when exported to other case-sensitive platforms.", path, real_path)); + } + } + } +#endif + if (is_backup_save_enabled() && (p_mode_flags == WRITE)) { save_path = path; // Create a temporary file in the same directory as the target file. @@ -173,6 +194,26 @@ String FileAccessUnix::get_path_absolute() const { return path; } +#if defined(TOOLS_ENABLED) +String FileAccessUnix::get_real_path() const { + char *resolved_path = ::realpath(path.utf8().get_data(), nullptr); + + if (!resolved_path) { + return path; + } + + String result; + Error parse_ok = result.parse_utf8(resolved_path); + ::free(resolved_path); + + if (parse_ok != OK) { + return path; + } + + return result.simplify_path(); +} +#endif + void FileAccessUnix::seek(uint64_t p_position) { ERR_FAIL_NULL_MSG(f, "File must be opened before use."); diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 76f629f7c2..7caf8a14d7 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -51,6 +51,10 @@ class FileAccessUnix : public FileAccess { void _close(); +#if defined(TOOLS_ENABLED) + String get_real_path() const; // Returns the resolved real path for the current open file. +#endif + public: static CloseNotificationFunc close_notification_func; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index f9f1168a97..6eecd850f5 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -1519,7 +1519,7 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info); ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); - err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, NULL); + err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, nullptr); ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); // Bookkeep. @@ -1745,7 +1745,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat & ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImage failed with error " + itos(err) + "."); err = vmaAllocateMemoryForImage(allocator, vk_image, &alloc_create_info, &allocation, &alloc_info); ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't allocate memory for image, error: " + itos(err) + "."); - err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, NULL); + err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, nullptr); ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't bind memory to image, error: " + itos(err) + "."); // Create view. @@ -2611,7 +2611,10 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu // it'll lead to very low performance in Android by entering an endless loop where it'll always resize the swap chain // every frame. - ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR, FAILED); + ERR_FAIL_COND_V_MSG( + err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR, + FAILED, + "QueuePresentKHR failed with error: " + get_vulkan_result(err)); } return OK; @@ -2887,21 +2890,28 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, // No swapchain yet, this is the first time we're creating it. if (!swap_chain->vk_swapchain) { - uint32_t width = surface_capabilities.currentExtent.width; - uint32_t height = surface_capabilities.currentExtent.height; + if (surface_capabilities.currentExtent.width == 0xFFFFFFFF) { + // The current extent is currently undefined, so the current surface width and height will be clamped to the surface's capabilities. + // We make sure to overwrite surface_capabilities.currentExtent.width so that the same check further below + // does not set extent.width = CLAMP( surface->width, ... ) on the first run of this function, because + // that'd be potentially unswapped. + surface_capabilities.currentExtent.width = CLAMP(surface->width, surface_capabilities.minImageExtent.width, surface_capabilities.maxImageExtent.width); + surface_capabilities.currentExtent.height = CLAMP(surface->height, surface_capabilities.minImageExtent.height, surface_capabilities.maxImageExtent.height); + } + + // We must SWAP() only once otherwise we'll keep ping-ponging between + // the right and wrong resolutions after multiple calls to swap_chain_resize(). if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR || surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { // Swap to get identity width and height. - surface_capabilities.currentExtent.height = width; - surface_capabilities.currentExtent.width = height; + SWAP(surface_capabilities.currentExtent.width, surface_capabilities.currentExtent.height); } - - native_display_size = surface_capabilities.currentExtent; } VkExtent2D extent; if (surface_capabilities.currentExtent.width == 0xFFFFFFFF) { // The current extent is currently undefined, so the current surface width and height will be clamped to the surface's capabilities. + // We can only be here on the second call to swap_chain_resize(), by which time surface->width & surface->height should already be swapped if needed. extent.width = CLAMP(surface->width, surface_capabilities.minImageExtent.width, surface_capabilities.maxImageExtent.width); extent.height = CLAMP(surface->height, surface_capabilities.minImageExtent.height, surface_capabilities.maxImageExtent.height); } else { @@ -2991,11 +3001,29 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, swap_create_info.minImageCount = desired_swapchain_images; swap_create_info.imageFormat = swap_chain->format; swap_create_info.imageColorSpace = swap_chain->color_space; - swap_create_info.imageExtent = native_display_size; + swap_create_info.imageExtent = extent; swap_create_info.imageArrayLayers = 1; swap_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swap_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swap_create_info.preTransform = surface_transform_bits; + switch (swap_create_info.preTransform) { + case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR: + swap_chain->pre_transform_rotation_degrees = 0; + break; + case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR: + swap_chain->pre_transform_rotation_degrees = 90; + break; + case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR: + swap_chain->pre_transform_rotation_degrees = 180; + break; + case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR: + swap_chain->pre_transform_rotation_degrees = 270; + break; + default: + WARN_PRINT("Unexpected swap_create_info.preTransform = " + itos(swap_create_info.preTransform) + "."); + swap_chain->pre_transform_rotation_degrees = 0; + break; + } swap_create_info.compositeAlpha = composite_alpha; swap_create_info.presentMode = present_mode; swap_create_info.clipped = true; @@ -3167,6 +3195,13 @@ RDD::RenderPassID RenderingDeviceDriverVulkan::swap_chain_get_render_pass(SwapCh return swap_chain->render_pass; } +int RenderingDeviceDriverVulkan::swap_chain_get_pre_rotation_degrees(SwapChainID p_swap_chain) { + DEV_ASSERT(p_swap_chain.id != 0); + + SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id); + return swap_chain->pre_transform_rotation_degrees; +} + RDD::DataFormat RenderingDeviceDriverVulkan::swap_chain_get_format(SwapChainID p_swap_chain) { DEV_ASSERT(p_swap_chain.id != 0); @@ -4017,7 +4052,7 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<Bou } // Need a descriptor pool. - DescriptorSetPools::Iterator pool_sets_it = {}; + DescriptorSetPools::Iterator pool_sets_it; VkDescriptorPool vk_pool = _descriptor_set_pool_find_or_create(pool_key, &pool_sets_it); DEV_ASSERT(vk_pool); pool_sets_it->value[vk_pool]++; @@ -5402,6 +5437,23 @@ void RenderingDeviceDriverVulkan::print_lost_device_info() { on_device_lost(); } +inline String RenderingDeviceDriverVulkan::get_vulkan_result(VkResult err) { +#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED) + if (err == VK_ERROR_OUT_OF_HOST_MEMORY) { + return "VK_ERROR_OUT_OF_HOST_MEMORY"; + } else if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY) { + return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + } else if (err == VK_ERROR_DEVICE_LOST) { + return "VK_ERROR_DEVICE_LOST"; + } else if (err == VK_ERROR_SURFACE_LOST_KHR) { + return "VK_ERROR_SURFACE_LOST_KHR"; + } else if (err == VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT) { + return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; + } +#endif + return itos(err); +} + /********************/ /**** SUBMISSION ****/ /********************/ diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index 33cce30b34..06cd2a31be 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -359,6 +359,7 @@ private: LocalVector<CommandQueue *> command_queues_acquired; LocalVector<uint32_t> command_queues_acquired_semaphores; RenderPassID render_pass; + int pre_transform_rotation_degrees = 0; uint32_t image_index = 0; #ifdef ANDROID_ENABLED uint64_t refresh_duration = 0; @@ -366,13 +367,13 @@ private: }; void _swap_chain_release(SwapChain *p_swap_chain); - VkExtent2D native_display_size; public: virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override final; virtual Error swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) override final; virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override final; virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final; + virtual int swap_chain_get_pre_rotation_degrees(SwapChainID p_swap_chain) override final; virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final; virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final; virtual void swap_chain_free(SwapChainID p_swap_chain) override final; @@ -487,7 +488,7 @@ private: struct UniformSetInfo { VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE; VkDescriptorPool vk_descriptor_pool = VK_NULL_HANDLE; - DescriptorSetPools::Iterator pool_sets_it = {}; + DescriptorSetPools::Iterator pool_sets_it; }; public: @@ -654,6 +655,7 @@ public: virtual void command_insert_breadcrumb(CommandBufferID p_cmd_buffer, uint32_t p_data) override final; void print_lost_device_info(); void on_device_lost() const; + static String get_vulkan_result(VkResult err); /********************/ /**** SUBMISSION ****/ diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index f7632842ed..24a26b56ef 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -282,7 +282,7 @@ Error DirAccessWindows::rename(String p_path, String p_new_path) { uint64_t id = OS::get_singleton()->get_ticks_usec(); while (true) { tmpfile_utf16 = (path + itos(id++) + ".tmp").utf16(); - HANDLE handle = CreateFileW((LPCWSTR)tmpfile_utf16.get_data(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + HANDLE handle = CreateFileW((LPCWSTR)tmpfile_utf16.get_data(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); break; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index a8a2ea6b5e..7d2247d41a 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -127,7 +127,7 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) { } #ifdef TOOLS_ENABLED - // Windows is case insensitive, but all other platforms are sensitive to it + // Windows is case insensitive in the default configuration, but other platforms can be sensitive to it // To ease cross-platform development, we issue a warning if users try to access // a file using the wrong case (which *works* on Windows, but won't on other // platforms), we only check for relative paths, or paths in res:// or user://, @@ -193,7 +193,7 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) { uint64_t id = OS::get_singleton()->get_ticks_usec(); while (true) { tmpfile = path + itos(id++) + ".tmp"; - HANDLE handle = CreateFileW((LPCWSTR)tmpfile.utf16().get_data(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + HANDLE handle = CreateFileW((LPCWSTR)tmpfile.utf16().get_data(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); break; diff --git a/drivers/windows/file_access_windows_pipe.cpp b/drivers/windows/file_access_windows_pipe.cpp index 9bf0f4d852..7348b29a92 100644 --- a/drivers/windows/file_access_windows_pipe.cpp +++ b/drivers/windows/file_access_windows_pipe.cpp @@ -40,7 +40,7 @@ Error FileAccessWindowsPipe::open_existing(HANDLE p_rfd, HANDLE p_wfd, bool p_bl _close(); path_src = String(); - ERR_FAIL_COND_V_MSG(fd[0] != 0 || fd[1] != 0, ERR_ALREADY_IN_USE, "Pipe is already in use."); + ERR_FAIL_COND_V_MSG(fd[0] != nullptr || fd[1] != nullptr, ERR_ALREADY_IN_USE, "Pipe is already in use."); fd[0] = p_rfd; fd[1] = p_wfd; @@ -58,18 +58,18 @@ Error FileAccessWindowsPipe::open_internal(const String &p_path, int p_mode_flag _close(); path_src = p_path; - ERR_FAIL_COND_V_MSG(fd[0] != 0 || fd[1] != 0, ERR_ALREADY_IN_USE, "Pipe is already in use."); + ERR_FAIL_COND_V_MSG(fd[0] != nullptr || fd[1] != nullptr, ERR_ALREADY_IN_USE, "Pipe is already in use."); path = String("\\\\.\\pipe\\LOCAL\\") + p_path.replace("pipe://", "").replace("/", "_"); - HANDLE h = CreateFileW((LPCWSTR)path.utf16().get_data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE h = CreateFileW((LPCWSTR)path.utf16().get_data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (h == INVALID_HANDLE_VALUE) { h = CreateNamedPipeW((LPCWSTR)path.utf16().get_data(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 4096, 4096, 0, nullptr); if (h == INVALID_HANDLE_VALUE) { last_error = ERR_FILE_CANT_OPEN; return last_error; } - ConnectNamedPipe(h, NULL); + ConnectNamedPipe(h, nullptr); } fd[0] = h; fd[1] = h; @@ -79,19 +79,19 @@ Error FileAccessWindowsPipe::open_internal(const String &p_path, int p_mode_flag } void FileAccessWindowsPipe::_close() { - if (fd[0] == 0) { + if (fd[0] == nullptr) { return; } if (fd[1] != fd[0]) { CloseHandle(fd[1]); } CloseHandle(fd[0]); - fd[0] = 0; - fd[1] = 0; + fd[0] = nullptr; + fd[1] = nullptr; } bool FileAccessWindowsPipe::is_open() const { - return (fd[0] != 0 || fd[1] != 0); + return (fd[0] != nullptr || fd[1] != nullptr); } String FileAccessWindowsPipe::get_path() const { @@ -103,7 +103,7 @@ String FileAccessWindowsPipe::get_path_absolute() const { } uint64_t FileAccessWindowsPipe::get_buffer(uint8_t *p_dst, uint64_t p_length) const { - ERR_FAIL_COND_V_MSG(fd[0] == 0, -1, "Pipe must be opened before use."); + ERR_FAIL_COND_V_MSG(fd[0] == nullptr, -1, "Pipe must be opened before use."); ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); DWORD read = 0; @@ -120,7 +120,7 @@ Error FileAccessWindowsPipe::get_error() const { } void FileAccessWindowsPipe::store_buffer(const uint8_t *p_src, uint64_t p_length) { - ERR_FAIL_COND_MSG(fd[1] == 0, "Pipe must be opened before use."); + ERR_FAIL_COND_MSG(fd[1] == nullptr, "Pipe must be opened before use."); ERR_FAIL_COND(!p_src && p_length > 0); DWORD read = -1; diff --git a/drivers/windows/file_access_windows_pipe.h b/drivers/windows/file_access_windows_pipe.h index 1eb3c6ef2f..5edf0500a5 100644 --- a/drivers/windows/file_access_windows_pipe.h +++ b/drivers/windows/file_access_windows_pipe.h @@ -39,7 +39,7 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> class FileAccessWindowsPipe : public FileAccess { - HANDLE fd[2] = { 0, 0 }; + HANDLE fd[2] = { nullptr, nullptr }; mutable Error last_error = OK; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 77d21cb7b0..c210ad0761 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -6337,8 +6337,9 @@ bool AnimationTrackEditor::_is_track_compatible(int p_target_track_idx, Variant: } if (path_valid) { - if (is_source_bezier) + if (is_source_bezier) { p_source_value_type = Variant::FLOAT; + } return property_type == p_source_value_type; } else { if (animation->track_get_key_count(p_target_track_idx) > 0) { diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index b78aad1721..da59450dd0 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1033,6 +1033,9 @@ void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) { _update_buttons_state(); emit_signal(SNAME("started")); + Array quit_keys = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("editor/stop_running_project")); + _put_msg("scene:setup_scene", quit_keys); + if (EditorSettings::get_singleton()->get_project_metadata("debug_options", "autostart_profiler", false)) { profiler->set_profiling(true); } @@ -1170,6 +1173,12 @@ String ScriptEditorDebugger::get_var_value(const String &p_var) const { return inspector->get_stack_variable(p_var); } +void ScriptEditorDebugger::_resources_reimported(const PackedStringArray &p_resources) { + Array msg; + msg.push_back(p_resources); + _put_msg("scene:reload_cached_files", msg); +} + int ScriptEditorDebugger::_get_node_path_cache(const NodePath &p_path) { const int *r = node_path_cache.getptr(p_path); if (r) { @@ -1818,6 +1827,7 @@ ScriptEditorDebugger::ScriptEditorDebugger() { tabs->connect("tab_changed", callable_mp(this, &ScriptEditorDebugger::_tab_changed)); InspectorDock::get_inspector_singleton()->connect("object_id_selected", callable_mp(this, &ScriptEditorDebugger::_remote_object_selected)); + EditorFileSystem::get_singleton()->connect("resources_reimported", callable_mp(this, &ScriptEditorDebugger::_resources_reimported)); { //debugger VBoxContainer *vbc = memnew(VBoxContainer); diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index 1908b1e5a7..06a968e141 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -198,6 +198,8 @@ private: void _video_mem_request(); void _video_mem_export(); + void _resources_reimported(const PackedStringArray &p_resources); + int _get_node_path_cache(const NodePath &p_path); int _get_res_path_cache(const String &p_path); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 084ecf7229..0649272216 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -91,17 +91,26 @@ void EditorAudioBus::_notification(int p_what) { Color mute_color = EditorThemeManager::is_dark_theme() ? Color(1.0, 0.16, 0.16) : Color(2.35, 1.03, 1.03); Color bypass_color = EditorThemeManager::is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(1.03, 2.04, 2.35); float darkening_factor = EditorThemeManager::is_dark_theme() ? 0.15 : 0.65; + Color solo_color_darkened = solo_color.darkened(darkening_factor); + Color mute_color_darkened = mute_color.darkened(darkening_factor); + Color bypass_color_darkened = bypass_color.darkened(darkening_factor); - Ref<StyleBoxFlat>(solo->get_theme_stylebox(SceneStringName(pressed)))->set_border_color(solo_color.darkened(darkening_factor)); - Ref<StyleBoxFlat>(mute->get_theme_stylebox(SceneStringName(pressed)))->set_border_color(mute_color.darkened(darkening_factor)); - Ref<StyleBoxFlat>(bypass->get_theme_stylebox(SceneStringName(pressed)))->set_border_color(bypass_color.darkened(darkening_factor)); + Ref<StyleBoxFlat>(solo->get_theme_stylebox(SceneStringName(pressed)))->set_border_color(solo_color_darkened); + Ref<StyleBoxFlat>(mute->get_theme_stylebox(SceneStringName(pressed)))->set_border_color(mute_color_darkened); + Ref<StyleBoxFlat>(bypass->get_theme_stylebox(SceneStringName(pressed)))->set_border_color(bypass_color_darkened); + Ref<StyleBoxFlat>(solo->get_theme_stylebox("hover_pressed"))->set_border_color(solo_color_darkened); + Ref<StyleBoxFlat>(mute->get_theme_stylebox("hover_pressed"))->set_border_color(mute_color_darkened); + Ref<StyleBoxFlat>(bypass->get_theme_stylebox("hover_pressed"))->set_border_color(bypass_color_darkened); solo->set_button_icon(get_editor_theme_icon(SNAME("AudioBusSolo"))); solo->add_theme_color_override("icon_pressed_color", solo_color); + solo->add_theme_color_override("icon_hover_pressed_color", solo_color_darkened); mute->set_button_icon(get_editor_theme_icon(SNAME("AudioBusMute"))); mute->add_theme_color_override("icon_pressed_color", mute_color); + mute->add_theme_color_override("icon_hover_pressed_color", mute_color_darkened); bypass->set_button_icon(get_editor_theme_icon(SNAME("AudioBusBypass"))); bypass->add_theme_color_override("icon_pressed_color", bypass_color); + bypass->add_theme_color_override("icon_hover_pressed_color", bypass_color_darkened); bus_options->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); @@ -841,13 +850,18 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { child->begin_bulk_theme_override(); child->add_theme_style_override(CoreStringName(normal), sbempty); child->add_theme_style_override("hover", sbempty); + child->add_theme_style_override("hover_mirrored", sbempty); child->add_theme_style_override("focus", sbempty); + child->add_theme_style_override("focus_mirrored", sbempty); Ref<StyleBoxFlat> sbflat = memnew(StyleBoxFlat); sbflat->set_content_margin_all(0); sbflat->set_bg_color(Color(1, 1, 1, 0)); sbflat->set_border_width(Side::SIDE_BOTTOM, Math::round(3 * EDSCALE)); child->add_theme_style_override(SceneStringName(pressed), sbflat); + child->add_theme_style_override("pressed_mirrored", sbflat); + child->add_theme_style_override("hover_pressed", sbflat); + child->add_theme_style_override("hover_pressed_mirrored", sbflat); child->end_bulk_theme_override(); } diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 7ffbc39d75..9cf10c0ecb 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -43,37 +43,37 @@ const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = { TTRC("3D Editor"), TTRC("Script Editor"), - TTRC("Game View"), TTRC("Asset Library"), TTRC("Scene Tree Editing"), TTRC("Node Dock"), TTRC("FileSystem Dock"), TTRC("Import Dock"), TTRC("History Dock"), + TTRC("Game View"), }; const char *EditorFeatureProfile::feature_descriptions[FEATURE_MAX] = { TTRC("Allows to view and edit 3D scenes."), TTRC("Allows to edit scripts using the integrated script editor."), - TTRC("Provides tools for selecting and debugging nodes at runtime."), TTRC("Provides built-in access to the Asset Library."), TTRC("Allows editing the node hierarchy in the Scene dock."), TTRC("Allows to work with signals and groups of the node selected in the Scene dock."), TTRC("Allows to browse the local file system via a dedicated dock."), TTRC("Allows to configure import settings for individual assets. Requires the FileSystem dock to function."), TTRC("Provides an overview of the editor's and each scene's undo history."), + TTRC("Provides tools for selecting and debugging nodes at runtime."), }; const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { "3d", "script", - "game", "asset_lib", "scene_tree", "node_dock", "filesystem_dock", "import_dock", "history_dock", + "game", }; void EditorFeatureProfile::set_disable_class(const StringName &p_class, bool p_disabled) { diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index cd02482bc7..558eed98c6 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -2581,7 +2581,7 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector EditorFileSystemDirectory *fs = nullptr; int cpos = -1; bool found = _find_file(file, &fs, cpos); - ERR_FAIL_COND_V_MSG(!found, ERR_UNCONFIGURED, "Can't find file '" + file + "'."); + ERR_FAIL_COND_V_MSG(!found, ERR_UNCONFIGURED, vformat("Can't find file '%s' during group reimport.", file)); //update modified times, to avoid reimport fs->files[cpos]->modified_time = FileAccess::get_modified_time(file); @@ -2631,7 +2631,7 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin int cpos = -1; if (p_update_file_system) { bool found = _find_file(p_file, &fs, cpos); - ERR_FAIL_COND_V_MSG(!found, ERR_FILE_NOT_FOUND, "Can't find file '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(!found, ERR_FILE_NOT_FOUND, vformat("Can't find file '%s' during file reimport.", p_file)); } //try to obtain existing params diff --git a/editor/editor_node.h b/editor/editor_node.h index 39a4c7df65..49c1699c28 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -789,7 +789,7 @@ public: struct AdditiveNodeEntry { Node *node = nullptr; - NodePath parent = NodePath(); + NodePath parent; Node *owner = nullptr; int index = 0; // Used if the original parent node is lost diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index d5135f4198..caed02ae58 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -223,11 +223,6 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { args.push_back(p_scene); } - // Pass the debugger stop shortcut to the running instance(s). - String shortcut; - VariantWriter::write_to_string(ED_GET_SHORTCUT("editor/stop_running_project"), shortcut); - OS::get_singleton()->set_environment("__GODOT_EDITOR_STOP_SHORTCUT__", shortcut); - String exec = OS::get_singleton()->get_executable_path(); int instance_count = RunInstancesDialog::get_singleton()->get_instance_count(); for (int i = 0; i < instance_count; i++) { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 12a7c3a2ff..eeb8ceb1ed 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -602,6 +602,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "filesystem/file_dialog/thumbnail_size", 64, "32,128,16") // Quick Open dialog + EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "filesystem/quick_open_dialog/max_results", 100, "0,10000,1", PROPERTY_USAGE_DEFAULT) + _initial_set("filesystem/quick_open_dialog/show_search_highlight", true); + _initial_set("filesystem/quick_open_dialog/enable_fuzzy_matching", true); + EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "filesystem/quick_open_dialog/max_fuzzy_misses", 2, "0,10,1", PROPERTY_USAGE_DEFAULT) _initial_set("filesystem/quick_open_dialog/include_addons", false); EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "filesystem/quick_open_dialog/default_display_mode", 0, "Adaptive,Last Used") diff --git a/editor/gui/editor_quick_open_dialog.cpp b/editor/gui/editor_quick_open_dialog.cpp index a6ad002de7..44e7b3e483 100644 --- a/editor/gui/editor_quick_open_dialog.cpp +++ b/editor/gui/editor_quick_open_dialog.cpp @@ -30,6 +30,7 @@ #include "editor_quick_open_dialog.h" +#include "core/string/fuzzy_search.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" @@ -45,6 +46,55 @@ #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" +void HighlightedLabel::draw_substr_rects(const Vector2i &p_substr, Vector2 p_offset, int p_line_limit, int line_spacing) { + for (int i = get_lines_skipped(); i < p_line_limit; i++) { + RID line = get_line_rid(i); + Vector<Vector2> ranges = TS->shaped_text_get_selection(line, p_substr.x, p_substr.x + p_substr.y); + Rect2 line_rect = get_line_rect(i); + for (const Vector2 &range : ranges) { + Rect2 rect = Rect2(Point2(range.x, 0) + line_rect.position, Size2(range.y - range.x, line_rect.size.y)); + rect.position = p_offset + line_rect.position; + rect.position.x += range.x; + rect.size = Size2(range.y - range.x, line_rect.size.y); + rect.size.x = MIN(rect.size.x, line_rect.size.x - range.x); + if (rect.size.x > 0) { + draw_rect(rect, Color(1, 1, 1, 0.07), true); + draw_rect(rect, Color(0.5, 0.7, 1.0, 0.4), false, 1); + } + } + p_offset.y += line_spacing + TS->shaped_text_get_ascent(line) + TS->shaped_text_get_descent(line); + } +} + +void HighlightedLabel::add_highlight(const Vector2i &p_interval) { + if (p_interval.y > 0) { + highlights.append(p_interval); + queue_redraw(); + } +} + +void HighlightedLabel::reset_highlights() { + highlights.clear(); + queue_redraw(); +} + +void HighlightedLabel::_notification(int p_notification) { + if (p_notification == NOTIFICATION_DRAW) { + if (highlights.is_empty()) { + return; + } + + Vector2 offset; + int line_limit; + int line_spacing; + get_layout_data(offset, line_limit, line_spacing); + + for (const Vector2i &substr : highlights) { + draw_substr_rects(substr, offset, line_limit, line_spacing); + } + } +} + EditorQuickOpenDialog::EditorQuickOpenDialog() { VBoxContainer *vbc = memnew(VBoxContainer); vbc->add_theme_constant_override("separation", 0); @@ -100,7 +150,7 @@ void EditorQuickOpenDialog::popup_dialog(const Vector<StringName> &p_base_types, get_ok_button()->set_disabled(container->has_nothing_selected()); set_title(get_dialog_title(p_base_types)); - popup_centered_clamped(Size2(710, 650) * EDSCALE, 0.8f); + popup_centered_clamped(Size2(780, 650) * EDSCALE, 0.8f); search_box->grab_focus(); } @@ -119,13 +169,18 @@ void EditorQuickOpenDialog::cancel_pressed() { } void EditorQuickOpenDialog::_search_box_text_changed(const String &p_query) { - container->update_results(p_query.to_lower()); - + container->set_query_and_update(p_query); get_ok_button()->set_disabled(container->has_nothing_selected()); } //------------------------- Result Container +void style_button(Button *p_button) { + p_button->set_flat(true); + p_button->set_focus_mode(Control::FOCUS_NONE); + p_button->set_default_cursor_shape(Control::CURSOR_POINTING_HAND); +} + QuickOpenResultContainer::QuickOpenResultContainer() { set_h_size_flags(Control::SIZE_EXPAND_FILL); set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -175,91 +230,107 @@ QuickOpenResultContainer::QuickOpenResultContainer() { } { - // Bottom bar - HBoxContainer *bottom_bar = memnew(HBoxContainer); - add_child(bottom_bar); - + // Selected filepath file_details_path = memnew(Label); file_details_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); file_details_path->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_CENTER); file_details_path->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); - bottom_bar->add_child(file_details_path); + add_child(file_details_path); + } - { - HBoxContainer *hbc = memnew(HBoxContainer); - hbc->add_theme_constant_override("separation", 3); - bottom_bar->add_child(hbc); - - include_addons_toggle = memnew(CheckButton); - include_addons_toggle->set_flat(true); - include_addons_toggle->set_focus_mode(Control::FOCUS_NONE); - include_addons_toggle->set_default_cursor_shape(CURSOR_POINTING_HAND); - include_addons_toggle->set_tooltip_text(TTR("Include files from addons")); - include_addons_toggle->connect(SceneStringName(toggled), callable_mp(this, &QuickOpenResultContainer::_toggle_include_addons)); - hbc->add_child(include_addons_toggle); - - VSeparator *vsep = memnew(VSeparator); - vsep->set_v_size_flags(Control::SIZE_SHRINK_CENTER); - vsep->set_custom_minimum_size(Size2i(0, 14 * EDSCALE)); - hbc->add_child(vsep); - - display_mode_toggle = memnew(Button); - display_mode_toggle->set_flat(true); - display_mode_toggle->set_focus_mode(Control::FOCUS_NONE); - display_mode_toggle->set_default_cursor_shape(CURSOR_POINTING_HAND); - display_mode_toggle->connect(SceneStringName(pressed), callable_mp(this, &QuickOpenResultContainer::_toggle_display_mode)); - hbc->add_child(display_mode_toggle); - } + { + // Bottom bar + HBoxContainer *bottom_bar = memnew(HBoxContainer); + bottom_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL); + bottom_bar->set_alignment(ALIGNMENT_END); + bottom_bar->add_theme_constant_override("separation", 3); + add_child(bottom_bar); + + fuzzy_search_toggle = memnew(CheckButton); + style_button(fuzzy_search_toggle); + fuzzy_search_toggle->set_text(TTR("Fuzzy Search")); + fuzzy_search_toggle->set_tooltip_text(TTR("Enable fuzzy matching")); + fuzzy_search_toggle->connect(SceneStringName(toggled), callable_mp(this, &QuickOpenResultContainer::_toggle_fuzzy_search)); + bottom_bar->add_child(fuzzy_search_toggle); + + include_addons_toggle = memnew(CheckButton); + style_button(include_addons_toggle); + include_addons_toggle->set_text(TTR("Addons")); + include_addons_toggle->set_tooltip_text(TTR("Include files from addons")); + include_addons_toggle->connect(SceneStringName(toggled), callable_mp(this, &QuickOpenResultContainer::_toggle_include_addons)); + bottom_bar->add_child(include_addons_toggle); + + VSeparator *vsep = memnew(VSeparator); + vsep->set_v_size_flags(Control::SIZE_SHRINK_CENTER); + vsep->set_custom_minimum_size(Size2i(0, 14 * EDSCALE)); + bottom_bar->add_child(vsep); + + display_mode_toggle = memnew(Button); + style_button(display_mode_toggle); + display_mode_toggle->connect(SceneStringName(pressed), callable_mp(this, &QuickOpenResultContainer::_toggle_display_mode)); + bottom_bar->add_child(display_mode_toggle); } +} - // Creating and deleting nodes while searching is slow, so we allocate - // a bunch of result nodes and fill in the content based on result ranking. - result_items.resize(TOTAL_ALLOCATED_RESULT_ITEMS); - for (int i = 0; i < TOTAL_ALLOCATED_RESULT_ITEMS; i++) { +void QuickOpenResultContainer::_ensure_result_vector_capacity() { + int target_size = EDITOR_GET("filesystem/quick_open_dialog/max_results"); + int initial_size = result_items.size(); + for (int i = target_size; i < initial_size; i++) { + result_items[i]->queue_free(); + } + result_items.resize(target_size); + for (int i = initial_size; i < target_size; i++) { QuickOpenResultItem *item = memnew(QuickOpenResultItem); item->connect(SceneStringName(gui_input), callable_mp(this, &QuickOpenResultContainer::_item_input).bind(i)); result_items.write[i] = item; - } -} - -QuickOpenResultContainer::~QuickOpenResultContainer() { - if (never_opened) { - for (QuickOpenResultItem *E : result_items) { - memdelete(E); + if (!never_opened) { + _layout_result_item(item); } } } void QuickOpenResultContainer::init(const Vector<StringName> &p_base_types) { + _ensure_result_vector_capacity(); base_types = p_base_types; - never_opened = false; const int display_mode_behavior = EDITOR_GET("filesystem/quick_open_dialog/default_display_mode"); const bool adaptive_display_mode = (display_mode_behavior == 0); if (adaptive_display_mode) { _set_display_mode(get_adaptive_display_mode(p_base_types)); + } else if (never_opened) { + int last = EditorSettings::get_singleton()->get_project_metadata("quick_open_dialog", "last_mode", (int)QuickOpenDisplayMode::LIST); + _set_display_mode((QuickOpenDisplayMode)last); } + const bool fuzzy_matching = EDITOR_GET("filesystem/quick_open_dialog/enable_fuzzy_matching"); const bool include_addons = EDITOR_GET("filesystem/quick_open_dialog/include_addons"); + fuzzy_search_toggle->set_pressed_no_signal(fuzzy_matching); include_addons_toggle->set_pressed_no_signal(include_addons); + never_opened = false; - _create_initial_results(include_addons); + const bool enable_highlights = EDITOR_GET("filesystem/quick_open_dialog/show_search_highlight"); + for (QuickOpenResultItem *E : result_items) { + E->enable_highlights = enable_highlights; + } + + _create_initial_results(); } -void QuickOpenResultContainer::_create_initial_results(bool p_include_addons) { - file_type_icons.insert("__default_icon", get_editor_theme_icon(SNAME("Object"))); - _find_candidates_in_folder(EditorFileSystem::get_singleton()->get_filesystem(), p_include_addons); - max_total_results = MIN(candidates.size(), TOTAL_ALLOCATED_RESULT_ITEMS); +void QuickOpenResultContainer::_create_initial_results() { file_type_icons.clear(); - - update_results(query); + file_type_icons.insert("__default_icon", get_editor_theme_icon(SNAME("Object"))); + filepaths.clear(); + filetypes.clear(); + _find_filepaths_in_folder(EditorFileSystem::get_singleton()->get_filesystem(), include_addons_toggle->is_pressed()); + max_total_results = MIN(filepaths.size(), result_items.size()); + update_results(); } -void QuickOpenResultContainer::_find_candidates_in_folder(EditorFileSystemDirectory *p_directory, bool p_include_addons) { +void QuickOpenResultContainer::_find_filepaths_in_folder(EditorFileSystemDirectory *p_directory, bool p_include_addons) { for (int i = 0; i < p_directory->get_subdir_count(); i++) { if (p_include_addons || p_directory->get_name() != "addons") { - _find_candidates_in_folder(p_directory->get_subdir(i), p_include_addons); + _find_filepaths_in_folder(p_directory->get_subdir(i), p_include_addons); } } @@ -276,146 +347,91 @@ void QuickOpenResultContainer::_find_candidates_in_folder(EditorFileSystemDirect bool is_valid = ClassDB::is_parent_class(engine_type, parent_type) || (!is_engine_type && EditorNode::get_editor_data().script_class_is_parent(script_type, parent_type)); if (is_valid) { - Candidate c; - c.file_name = file_path.get_file(); - c.file_directory = file_path.get_base_dir(); - - EditorResourcePreview::PreviewItem item = EditorResourcePreview::get_singleton()->get_resource_preview_if_available(file_path); - if (item.preview.is_valid()) { - c.thumbnail = item.preview; - } else if (file_type_icons.has(actual_type)) { - c.thumbnail = *file_type_icons.lookup_ptr(actual_type); - } else if (has_theme_icon(actual_type, EditorStringName(EditorIcons))) { - c.thumbnail = get_editor_theme_icon(actual_type); - file_type_icons.insert(actual_type, c.thumbnail); - } else { - c.thumbnail = *file_type_icons.lookup_ptr("__default_icon"); - } - - candidates.push_back(c); - + filepaths.append(file_path); + filetypes.insert(file_path, actual_type); break; // Stop testing base types as soon as we get a match. } } } } -void QuickOpenResultContainer::update_results(const String &p_query) { +void QuickOpenResultContainer::set_query_and_update(const String &p_query) { query = p_query; - - int relevant_candidates = _sort_candidates(p_query); - _update_result_items(MIN(relevant_candidates, max_total_results), 0); -} - -int QuickOpenResultContainer::_sort_candidates(const String &p_query) { - if (p_query.is_empty()) { - return 0; + update_results(); +} + +void QuickOpenResultContainer::_setup_candidate(QuickOpenResultCandidate &candidate, const String &filepath) { + StringName actual_type = *filetypes.lookup_ptr(filepath); + candidate.file_path = filepath; + candidate.result = nullptr; + + EditorResourcePreview::PreviewItem item = EditorResourcePreview::get_singleton()->get_resource_preview_if_available(filepath); + if (item.preview.is_valid()) { + candidate.thumbnail = item.preview; + } else if (file_type_icons.has(actual_type)) { + candidate.thumbnail = *file_type_icons.lookup_ptr(actual_type); + } else if (has_theme_icon(actual_type, EditorStringName(EditorIcons))) { + candidate.thumbnail = get_editor_theme_icon(actual_type); + file_type_icons.insert(actual_type, candidate.thumbnail); + } else { + candidate.thumbnail = *file_type_icons.lookup_ptr("__default_icon"); } +} - const PackedStringArray search_tokens = p_query.to_lower().replace("/", " ").split(" ", false); +void QuickOpenResultContainer::_setup_candidate(QuickOpenResultCandidate &p_candidate, const FuzzySearchResult &p_result) { + _setup_candidate(p_candidate, p_result.target); + p_candidate.result = &p_result; +} - if (search_tokens.is_empty()) { - return 0; +void QuickOpenResultContainer::update_results() { + showing_history = false; + candidates.clear(); + if (query.is_empty()) { + _use_default_candidates(); + } else { + _score_and_sort_candidates(); } + _update_result_items(MIN(candidates.size(), max_total_results), 0); +} - // First, we assign a score to each candidate. - int num_relevant_candidates = 0; - for (Candidate &c : candidates) { - c.score = 0; - int prev_token_match_pos = -1; - - for (const String &token : search_tokens) { - const int file_pos = c.file_name.findn(token); - const int dir_pos = c.file_directory.findn(token); - - const bool file_match = file_pos > -1; - const bool dir_match = dir_pos > -1; - if (!file_match && !dir_match) { - c.score = -1.0f; - break; - } - - float token_score = file_match ? 0.6f : 0.1999f; - - // Add bias for shorter filenames/paths: they resemble the query more. - const String &matched_string = file_match ? c.file_name : c.file_directory; - int matched_string_token_pos = file_match ? file_pos : dir_pos; - token_score += 0.1f * (1.0f - ((float)matched_string_token_pos / (float)matched_string.length())); - - // Add bias if the match happened in the file name, not the extension. - if (file_match) { - int ext_pos = matched_string.rfind("."); - if (ext_pos == -1 || ext_pos > matched_string_token_pos) { - token_score += 0.1f; - } - } - - // Add bias if token is in order. - { - int candidate_string_token_pos = file_match ? (c.file_directory.length() + file_pos) : dir_pos; - - if (prev_token_match_pos != -1 && candidate_string_token_pos > prev_token_match_pos) { - token_score += 0.2f; - } - - prev_token_match_pos = candidate_string_token_pos; - } - - c.score += token_score; +void QuickOpenResultContainer::_use_default_candidates() { + if (filepaths.size() <= SHOW_ALL_FILES_THRESHOLD) { + candidates.resize(filepaths.size()); + QuickOpenResultCandidate *candidates_write = candidates.ptrw(); + for (const String &filepath : filepaths) { + _setup_candidate(*candidates_write++, filepath); } - - if (c.score > 0.0f) { - num_relevant_candidates++; + } else if (base_types.size() == 1) { + Vector<QuickOpenResultCandidate> *history = selected_history.lookup_ptr(base_types[0]); + if (history) { + showing_history = true; + candidates.append_array(*history); } } - - // Now we will sort the candidates based on score, resolving ties by favoring: - // 1. Shorter file length. - // 2. Shorter directory length. - // 3. Lower alphabetic order. - struct CandidateComparator { - _FORCE_INLINE_ bool operator()(const Candidate &p_a, const Candidate &p_b) const { - if (!Math::is_equal_approx(p_a.score, p_b.score)) { - return p_a.score > p_b.score; - } - - if (p_a.file_name.length() != p_b.file_name.length()) { - return p_a.file_name.length() < p_b.file_name.length(); - } - - if (p_a.file_directory.length() != p_b.file_directory.length()) { - return p_a.file_directory.length() < p_b.file_directory.length(); - } - - return p_a.file_name < p_b.file_name; - } - }; - candidates.sort_custom<CandidateComparator>(); - - return num_relevant_candidates; } -void QuickOpenResultContainer::_update_result_items(int p_new_visible_results_count, int p_new_selection_index) { - List<Candidate> *type_history = nullptr; - - showing_history = false; - - if (query.is_empty()) { - if (candidates.size() <= SHOW_ALL_FILES_THRESHOLD) { - p_new_visible_results_count = candidates.size(); - } else { - p_new_visible_results_count = 0; +void QuickOpenResultContainer::_update_fuzzy_search_results() { + FuzzySearch fuzzy_search; + fuzzy_search.start_offset = 6; // Don't match against "res://" at the start of each filepath. + fuzzy_search.set_query(query); + fuzzy_search.max_results = max_total_results; + bool fuzzy_matching = EDITOR_GET("filesystem/quick_open_dialog/enable_fuzzy_matching"); + int max_misses = EDITOR_GET("filesystem/quick_open_dialog/max_fuzzy_misses"); + fuzzy_search.allow_subsequences = fuzzy_matching; + fuzzy_search.max_misses = fuzzy_matching ? max_misses : 0; + fuzzy_search.search_all(filepaths, search_results); +} - if (base_types.size() == 1) { - type_history = selected_history.lookup_ptr(base_types[0]); - if (type_history) { - p_new_visible_results_count = type_history->size(); - showing_history = true; - } - } - } +void QuickOpenResultContainer::_score_and_sort_candidates() { + _update_fuzzy_search_results(); + candidates.resize(search_results.size()); + QuickOpenResultCandidate *candidates_write = candidates.ptrw(); + for (const FuzzySearchResult &result : search_results) { + _setup_candidate(*candidates_write++, result); } +} +void QuickOpenResultContainer::_update_result_items(int p_new_visible_results_count, int p_new_selection_index) { // Only need to update items that were not hidden in previous update. int num_items_needing_updates = MAX(num_visible_results, p_new_visible_results_count); num_visible_results = p_new_visible_results_count; @@ -424,13 +440,7 @@ void QuickOpenResultContainer::_update_result_items(int p_new_visible_results_co QuickOpenResultItem *item = result_items[i]; if (i < num_visible_results) { - if (type_history) { - const Candidate &c = type_history->get(i); - item->set_content(c.thumbnail, c.file_name, c.file_directory); - } else { - const Candidate &c = candidates[i]; - item->set_content(c.thumbnail, c.file_name, c.file_directory); - } + item->set_content(candidates[i]); } else { item->reset(); } @@ -443,7 +453,7 @@ void QuickOpenResultContainer::_update_result_items(int p_new_visible_results_co no_results_container->set_visible(!any_results); if (!any_results) { - if (candidates.is_empty()) { + if (filepaths.is_empty()) { no_results_label->set_text(TTR("No files found for this type")); } else if (query.is_empty()) { no_results_label->set_text(TTR("Start searching to find files...")); @@ -471,10 +481,12 @@ void QuickOpenResultContainer::handle_search_box_input(const Ref<InputEvent> &p_ } break; case Key::LEFT: case Key::RIGHT: { - // Both grid and the search box use left/right keys. By default, grid will take it. - // It would be nice if we could check for ALT to give the event to the searchbox cursor. - // However, if you press ALT, the searchbox also denies the input. - move_selection = (content_display_mode == QuickOpenDisplayMode::GRID); + if (content_display_mode == QuickOpenDisplayMode::GRID) { + // Maybe strip off the shift modifier to allow non-selecting navigation by character? + if (key_event->get_modifiers_mask() == 0) { + move_selection = true; + } + } } break; default: break; // Let the event through so it will reach the search box. @@ -489,6 +501,10 @@ void QuickOpenResultContainer::handle_search_box_input(const Ref<InputEvent> &p_ } void QuickOpenResultContainer::_move_selection_index(Key p_key) { + // Don't move selection if there are no results. + if (num_visible_results <= 0) { + return; + } const int max_index = num_visible_results - 1; int idx = selection_index; @@ -562,11 +578,15 @@ void QuickOpenResultContainer::_item_input(const Ref<InputEvent> &p_ev, int p_in } } +void QuickOpenResultContainer::_toggle_fuzzy_search(bool p_pressed) { + EditorSettings::get_singleton()->set("filesystem/quick_open_dialog/enable_fuzzy_matching", p_pressed); + update_results(); +} + void QuickOpenResultContainer::_toggle_include_addons(bool p_pressed) { EditorSettings::get_singleton()->set("filesystem/quick_open_dialog/include_addons", p_pressed); - cleanup(); - _create_initial_results(p_pressed); + _create_initial_results(); } void QuickOpenResultContainer::_toggle_display_mode() { @@ -574,41 +594,41 @@ void QuickOpenResultContainer::_toggle_display_mode() { _set_display_mode(new_display_mode); } -void QuickOpenResultContainer::_set_display_mode(QuickOpenDisplayMode p_display_mode) { - content_display_mode = p_display_mode; +CanvasItem *QuickOpenResultContainer::_get_result_root() { + if (content_display_mode == QuickOpenDisplayMode::LIST) { + return list; + } else { + return grid; + } +} - const bool show_list = (content_display_mode == QuickOpenDisplayMode::LIST); - if ((show_list && list->is_visible()) || (!show_list && grid->is_visible())) { - return; +void QuickOpenResultContainer::_layout_result_item(QuickOpenResultItem *item) { + item->set_display_mode(content_display_mode); + Node *parent = item->get_parent(); + if (parent) { + parent->remove_child(item); } + _get_result_root()->add_child(item); +} - hide(); +void QuickOpenResultContainer::_set_display_mode(QuickOpenDisplayMode p_display_mode) { + CanvasItem *prev_root = _get_result_root(); - // Move result item nodes from one container to the other. - CanvasItem *prev_root; - CanvasItem *next_root; - if (content_display_mode == QuickOpenDisplayMode::LIST) { - prev_root = Object::cast_to<CanvasItem>(grid); - next_root = Object::cast_to<CanvasItem>(list); - } else { - prev_root = Object::cast_to<CanvasItem>(list); - next_root = Object::cast_to<CanvasItem>(grid); + if (prev_root->is_visible() && content_display_mode == p_display_mode) { + return; } - const bool first_time = !list->is_visible() && !grid->is_visible(); + content_display_mode = p_display_mode; + CanvasItem *next_root = _get_result_root(); - prev_root->hide(); - for (QuickOpenResultItem *item : result_items) { - item->set_display_mode(content_display_mode); + EditorSettings::get_singleton()->set_project_metadata("quick_open_dialog", "last_mode", (int)content_display_mode); - if (!first_time) { - prev_root->remove_child(item); - } + prev_root->hide(); + next_root->show(); - next_root->add_child(item); + for (QuickOpenResultItem *item : result_items) { + _layout_result_item(item); } - next_root->show(); - show(); _update_result_items(num_visible_results, selection_index); @@ -627,16 +647,7 @@ bool QuickOpenResultContainer::has_nothing_selected() const { String QuickOpenResultContainer::get_selected() const { ERR_FAIL_COND_V_MSG(has_nothing_selected(), String(), "Tried to get selected file, but nothing was selected."); - - if (showing_history) { - const List<Candidate> *type_history = selected_history.lookup_ptr(base_types[0]); - - const Candidate &c = type_history->get(selection_index); - return c.file_directory.path_join(c.file_name); - } else { - const Candidate &c = candidates[selection_index]; - return c.file_directory.path_join(c.file_name); - } + return candidates[selection_index].file_path; } QuickOpenDisplayMode QuickOpenResultContainer::get_adaptive_display_mode(const Vector<StringName> &p_base_types) { @@ -649,8 +660,9 @@ QuickOpenDisplayMode QuickOpenResultContainer::get_adaptive_display_mode(const V for (const StringName &type : grid_preferred_types) { for (const StringName &base_type : p_base_types) { - if (base_type == type || ClassDB::is_parent_class(base_type, type)) + if (base_type == type || ClassDB::is_parent_class(base_type, type)) { return QuickOpenDisplayMode::GRID; + } } } @@ -664,32 +676,27 @@ void QuickOpenResultContainer::save_selected_item() { return; } - if (showing_history) { - // Selecting from history, so already added. - return; - } - const StringName &base_type = base_types[0]; + const QuickOpenResultCandidate &selected = candidates[selection_index]; + Vector<QuickOpenResultCandidate> *type_history = selected_history.lookup_ptr(base_type); - List<Candidate> *type_history = selected_history.lookup_ptr(base_type); if (!type_history) { - selected_history.insert(base_type, List<Candidate>()); + selected_history.insert(base_type, Vector<QuickOpenResultCandidate>()); type_history = selected_history.lookup_ptr(base_type); } else { - const Candidate &selected = candidates[selection_index]; - - for (const Candidate &candidate : *type_history) { - if (candidate.file_directory == selected.file_directory && candidate.file_name == selected.file_name) { - return; + for (int i = 0; i < type_history->size(); i++) { + if (selected.file_path == type_history->get(i).file_path) { + type_history->remove_at(i); + break; } } - - if (type_history->size() > 8) { - type_history->pop_back(); - } } - type_history->push_front(candidates[selection_index]); + type_history->insert(0, selected); + type_history->ptrw()->result = nullptr; + if (type_history->size() > MAX_HISTORY_SIZE) { + type_history->resize(MAX_HISTORY_SIZE); + } } void QuickOpenResultContainer::cleanup() { @@ -743,36 +750,35 @@ QuickOpenResultItem::QuickOpenResultItem() { void QuickOpenResultItem::set_display_mode(QuickOpenDisplayMode p_display_mode) { if (p_display_mode == QuickOpenDisplayMode::LIST) { grid_item->hide(); + grid_item->reset(); list_item->show(); } else { list_item->hide(); + list_item->reset(); grid_item->show(); } queue_redraw(); } -void QuickOpenResultItem::set_content(const Ref<Texture2D> &p_thumbnail, const String &p_file, const String &p_file_directory) { +void QuickOpenResultItem::set_content(const QuickOpenResultCandidate &p_candidate) { _set_enabled(true); if (list_item->is_visible()) { - list_item->set_content(p_thumbnail, p_file, p_file_directory); + list_item->set_content(p_candidate, enable_highlights); } else { - grid_item->set_content(p_thumbnail, p_file); + grid_item->set_content(p_candidate, enable_highlights); } + + queue_redraw(); } void QuickOpenResultItem::reset() { _set_enabled(false); - is_hovering = false; is_selected = false; - - if (list_item->is_visible()) { - list_item->reset(); - } else { - grid_item->reset(); - } + list_item->reset(); + grid_item->reset(); } void QuickOpenResultItem::highlight_item(bool p_enabled) { @@ -825,6 +831,22 @@ void QuickOpenResultItem::_notification(int p_what) { //----------------- List item +static Vector2i _get_path_interval(const Vector2i &p_interval, int p_dir_index) { + if (p_interval.x >= p_dir_index || p_interval.y < 1) { + return { -1, -1 }; + } + return { p_interval.x, MIN(p_interval.x + p_interval.y, p_dir_index) - p_interval.x }; +} + +static Vector2i _get_name_interval(const Vector2i &p_interval, int p_dir_index) { + if (p_interval.x + p_interval.y <= p_dir_index || p_interval.y < 1) { + return { -1, -1 }; + } + int first_name_idx = p_dir_index + 1; + int start = MAX(p_interval.x, first_name_idx); + return { start - first_name_idx, p_interval.y - start + p_interval.x }; +} + QuickOpenResultListItem::QuickOpenResultListItem() { set_h_size_flags(Control::SIZE_EXPAND_FILL); add_theme_constant_override("separation", 4 * EDSCALE); @@ -852,13 +874,13 @@ QuickOpenResultListItem::QuickOpenResultListItem() { text_container->set_v_size_flags(Control::SIZE_FILL); add_child(text_container); - name = memnew(Label); + name = memnew(HighlightedLabel); name->set_h_size_flags(Control::SIZE_EXPAND_FILL); name->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); name->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_LEFT); text_container->add_child(name); - path = memnew(Label); + path = memnew(HighlightedLabel); path->set_h_size_flags(Control::SIZE_EXPAND_FILL); path->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); path->add_theme_font_size_override(SceneStringName(font_size), 12 * EDSCALE); @@ -866,18 +888,29 @@ QuickOpenResultListItem::QuickOpenResultListItem() { } } -void QuickOpenResultListItem::set_content(const Ref<Texture2D> &p_thumbnail, const String &p_file, const String &p_file_directory) { - thumbnail->set_texture(p_thumbnail); - name->set_text(p_file); - path->set_text(p_file_directory); +void QuickOpenResultListItem::set_content(const QuickOpenResultCandidate &p_candidate, bool p_highlight) { + thumbnail->set_texture(p_candidate.thumbnail); + name->set_text(p_candidate.file_path.get_file()); + path->set_text(p_candidate.file_path.get_base_dir()); + name->reset_highlights(); + path->reset_highlights(); + + if (p_highlight && p_candidate.result != nullptr) { + for (const FuzzyTokenMatch &match : p_candidate.result->token_matches) { + for (const Vector2i &interval : match.substrings) { + path->add_highlight(_get_path_interval(interval, p_candidate.result->dir_index)); + name->add_highlight(_get_name_interval(interval, p_candidate.result->dir_index)); + } + } + } const int max_size = 32 * EDSCALE; - bool uses_icon = p_thumbnail->get_width() < max_size; + bool uses_icon = p_candidate.thumbnail->get_width() < max_size; if (uses_icon) { - thumbnail->set_custom_minimum_size(p_thumbnail->get_size()); + thumbnail->set_custom_minimum_size(p_candidate.thumbnail->get_size()); - int margin_needed = (max_size - p_thumbnail->get_width()) / 2; + int margin_needed = (max_size - p_candidate.thumbnail->get_width()) / 2; image_container->add_theme_constant_override("margin_left", CONTAINER_MARGIN + margin_needed); image_container->add_theme_constant_override("margin_right", margin_needed); } else { @@ -888,9 +921,11 @@ void QuickOpenResultListItem::set_content(const Ref<Texture2D> &p_thumbnail, con } void QuickOpenResultListItem::reset() { - name->set_text(""); thumbnail->set_texture(nullptr); + name->set_text(""); path->set_text(""); + name->reset_highlights(); + path->reset_highlights(); } void QuickOpenResultListItem::highlight_item(const Color &p_color) { @@ -919,10 +954,10 @@ QuickOpenResultGridItem::QuickOpenResultGridItem() { thumbnail = memnew(TextureRect); thumbnail->set_h_size_flags(Control::SIZE_SHRINK_CENTER); thumbnail->set_v_size_flags(Control::SIZE_SHRINK_CENTER); - thumbnail->set_custom_minimum_size(Size2i(80 * EDSCALE, 64 * EDSCALE)); + thumbnail->set_custom_minimum_size(Size2i(120 * EDSCALE, 64 * EDSCALE)); add_child(thumbnail); - name = memnew(Label); + name = memnew(HighlightedLabel); name->set_h_size_flags(Control::SIZE_EXPAND_FILL); name->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); name->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_CENTER); @@ -930,16 +965,23 @@ QuickOpenResultGridItem::QuickOpenResultGridItem() { add_child(name); } -void QuickOpenResultGridItem::set_content(const Ref<Texture2D> &p_thumbnail, const String &p_file) { - thumbnail->set_texture(p_thumbnail); +void QuickOpenResultGridItem::set_content(const QuickOpenResultCandidate &p_candidate, bool p_highlight) { + thumbnail->set_texture(p_candidate.thumbnail); + name->set_text(p_candidate.file_path.get_file()); + name->set_tooltip_text(p_candidate.file_path); + name->reset_highlights(); - const String &file_name = p_file.get_basename(); - name->set_text(file_name); - name->set_tooltip_text(file_name); + if (p_highlight && p_candidate.result != nullptr) { + for (const FuzzyTokenMatch &match : p_candidate.result->token_matches) { + for (const Vector2i &interval : match.substrings) { + name->add_highlight(_get_name_interval(interval, p_candidate.result->dir_index)); + } + } + } - bool uses_icon = p_thumbnail->get_width() < (32 * EDSCALE); + bool uses_icon = p_candidate.thumbnail->get_width() < (32 * EDSCALE); - if (uses_icon || p_thumbnail->get_height() <= thumbnail->get_custom_minimum_size().y) { + if (uses_icon || p_candidate.thumbnail->get_height() <= thumbnail->get_custom_minimum_size().y) { thumbnail->set_expand_mode(TextureRect::EXPAND_KEEP_SIZE); thumbnail->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED); } else { @@ -949,8 +991,9 @@ void QuickOpenResultGridItem::set_content(const Ref<Texture2D> &p_thumbnail, con } void QuickOpenResultGridItem::reset() { - name->set_text(""); thumbnail->set_texture(nullptr); + name->set_text(""); + name->reset_highlights(); } void QuickOpenResultGridItem::highlight_item(const Color &p_color) { diff --git a/editor/gui/editor_quick_open_dialog.h b/editor/gui/editor_quick_open_dialog.h index 49257aed6b..3b3f927527 100644 --- a/editor/gui/editor_quick_open_dialog.h +++ b/editor/gui/editor_quick_open_dialog.h @@ -48,6 +48,8 @@ class Texture2D; class TextureRect; class VBoxContainer; +class FuzzySearchResult; + class QuickOpenResultItem; enum class QuickOpenDisplayMode { @@ -55,13 +57,35 @@ enum class QuickOpenDisplayMode { LIST, }; +struct QuickOpenResultCandidate { + String file_path; + Ref<Texture2D> thumbnail; + const FuzzySearchResult *result = nullptr; +}; + +class HighlightedLabel : public Label { + GDCLASS(HighlightedLabel, Label) + + Vector<Vector2i> highlights; + + void draw_substr_rects(const Vector2i &p_substr, Vector2 p_offset, int p_line_limit, int line_spacing); + +public: + void add_highlight(const Vector2i &p_interval); + void reset_highlights(); + +protected: + void _notification(int p_notification); +}; + class QuickOpenResultContainer : public VBoxContainer { GDCLASS(QuickOpenResultContainer, VBoxContainer) public: void init(const Vector<StringName> &p_base_types); void handle_search_box_input(const Ref<InputEvent> &p_ie); - void update_results(const String &p_query); + void set_query_and_update(const String &p_query); + void update_results(); bool has_nothing_selected() const; String get_selected() const; @@ -70,27 +94,21 @@ public: void cleanup(); QuickOpenResultContainer(); - ~QuickOpenResultContainer(); protected: void _notification(int p_what); private: - static const int TOTAL_ALLOCATED_RESULT_ITEMS = 100; - static const int SHOW_ALL_FILES_THRESHOLD = 30; - - struct Candidate { - String file_name; - String file_directory; - - Ref<Texture2D> thumbnail; - float score = 0; - }; + static constexpr int SHOW_ALL_FILES_THRESHOLD = 30; + static constexpr int MAX_HISTORY_SIZE = 20; + Vector<FuzzySearchResult> search_results; Vector<StringName> base_types; - Vector<Candidate> candidates; + Vector<String> filepaths; + OAHashMap<String, StringName> filetypes; + Vector<QuickOpenResultCandidate> candidates; - OAHashMap<StringName, List<Candidate>> selected_history; + OAHashMap<StringName, Vector<QuickOpenResultCandidate>> selected_history; String query; int selection_index = -1; @@ -114,15 +132,21 @@ private: Label *file_details_path = nullptr; Button *display_mode_toggle = nullptr; CheckButton *include_addons_toggle = nullptr; + CheckButton *fuzzy_search_toggle = nullptr; OAHashMap<StringName, Ref<Texture2D>> file_type_icons; static QuickOpenDisplayMode get_adaptive_display_mode(const Vector<StringName> &p_base_types); - void _create_initial_results(bool p_include_addons); - void _find_candidates_in_folder(EditorFileSystemDirectory *p_directory, bool p_include_addons); + void _ensure_result_vector_capacity(); + void _create_initial_results(); + void _find_filepaths_in_folder(EditorFileSystemDirectory *p_directory, bool p_include_addons); - int _sort_candidates(const String &p_query); + void _setup_candidate(QuickOpenResultCandidate &p_candidate, const String &p_filepath); + void _setup_candidate(QuickOpenResultCandidate &p_candidate, const FuzzySearchResult &p_result); + void _update_fuzzy_search_results(); + void _use_default_candidates(); + void _score_and_sort_candidates(); void _update_result_items(int p_new_visible_results_count, int p_new_selection_index); void _move_selection_index(Key p_key); @@ -130,9 +154,12 @@ private: void _item_input(const Ref<InputEvent> &p_ev, int p_index); + CanvasItem *_get_result_root(); + void _layout_result_item(QuickOpenResultItem *p_item); void _set_display_mode(QuickOpenDisplayMode p_display_mode); void _toggle_display_mode(); void _toggle_include_addons(bool p_pressed); + void _toggle_fuzzy_search(bool p_pressed); static void _bind_methods(); }; @@ -143,14 +170,14 @@ class QuickOpenResultGridItem : public VBoxContainer { public: QuickOpenResultGridItem(); - void set_content(const Ref<Texture2D> &p_thumbnail, const String &p_file_name); void reset(); + void set_content(const QuickOpenResultCandidate &p_candidate, bool p_highlight); void highlight_item(const Color &p_color); void remove_highlight(); private: TextureRect *thumbnail = nullptr; - Label *name = nullptr; + HighlightedLabel *name = nullptr; }; class QuickOpenResultListItem : public HBoxContainer { @@ -159,8 +186,8 @@ class QuickOpenResultListItem : public HBoxContainer { public: QuickOpenResultListItem(); - void set_content(const Ref<Texture2D> &p_thumbnail, const String &p_file_name, const String &p_file_directory); void reset(); + void set_content(const QuickOpenResultCandidate &p_candidate, bool p_highlight); void highlight_item(const Color &p_color); void remove_highlight(); @@ -174,8 +201,8 @@ private: VBoxContainer *text_container = nullptr; TextureRect *thumbnail = nullptr; - Label *name = nullptr; - Label *path = nullptr; + HighlightedLabel *name = nullptr; + HighlightedLabel *path = nullptr; }; class QuickOpenResultItem : public HBoxContainer { @@ -184,10 +211,11 @@ class QuickOpenResultItem : public HBoxContainer { public: QuickOpenResultItem(); - void set_content(const Ref<Texture2D> &p_thumbnail, const String &p_file_name, const String &p_file_directory); - void set_display_mode(QuickOpenDisplayMode p_display_mode); - void reset(); + bool enable_highlights = true; + void reset(); + void set_content(const QuickOpenResultCandidate &p_candidate); + void set_display_mode(QuickOpenDisplayMode p_display_mode); void highlight_item(bool p_enabled); protected: diff --git a/editor/gui/editor_toaster.cpp b/editor/gui/editor_toaster.cpp index cc439d56b3..4ebd1922a7 100644 --- a/editor/gui/editor_toaster.cpp +++ b/editor/gui/editor_toaster.cpp @@ -108,7 +108,6 @@ void EditorToaster::_notification(int p_what) { } } break; - case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { if (vbox_container->is_visible()) { main_button->set_button_icon(get_editor_theme_icon(SNAME("Notification"))); @@ -134,9 +133,6 @@ void EditorToaster::_notification(int p_what) { error_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), EditorStringName(Editor)).lightened(0.03)); error_panel_style_progress->set_border_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor))); - - main_button->queue_redraw(); - disable_notifications_button->queue_redraw(); } break; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -243,6 +239,7 @@ void EditorToaster::_auto_hide_or_free_toasts() { main_button->set_tooltip_text(TTR("No notifications.")); main_button->set_modulate(Color(0.5, 0.5, 0.5)); main_button->set_disabled(true); + set_process_internal(false); } else { main_button->set_tooltip_text(TTR("Show notifications.")); main_button->set_modulate(Color(1, 1, 1)); @@ -361,6 +358,9 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ } panel->set_modulate(Color(1, 1, 1, 0)); panel->connect(SceneStringName(draw), callable_mp(this, &EditorToaster::_draw_progress).bind(panel)); + panel->connect(SceneStringName(theme_changed), callable_mp(this, &EditorToaster::_toast_theme_changed).bind(panel)); + + Toast &toast = toasts[panel]; // Horizontal container. HBoxContainer *hbox_container = memnew(HBoxContainer); @@ -375,20 +375,20 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ if (p_time > 0.0) { Button *close_button = memnew(Button); close_button->set_flat(true); - close_button->set_button_icon(get_editor_theme_icon(SNAME("Close"))); close_button->connect(SceneStringName(pressed), callable_mp(this, &EditorToaster::close).bind(panel)); - close_button->connect(SceneStringName(theme_changed), callable_mp(this, &EditorToaster::_close_button_theme_changed).bind(close_button)); hbox_container->add_child(close_button); + + toast.close_button = close_button; } - toasts[panel].severity = p_severity; + toast.severity = p_severity; if (p_time > 0.0) { - toasts[panel].duration = p_time; - toasts[panel].remaining_time = p_time; + toast.duration = p_time; + toast.remaining_time = p_time; } else { - toasts[panel].duration = -1.0; + toast.duration = -1.0; } - toasts[panel].popped = true; + toast.popped = true; vbox_container->add_child(panel); _auto_hide_or_free_toasts(); _update_vbox_position(); @@ -406,7 +406,7 @@ void EditorToaster::popup_str(const String &p_message, Severity p_severity, cons // Since "_popup_str" adds nodes to the tree, and since the "add_child" method is not // thread-safe, it's better to defer the call to the next cycle to be thread-safe. is_processing_error = true; - MessageQueue::get_main_singleton()->push_callable(callable_mp(this, &EditorToaster::_popup_str).bind(p_message, p_severity, p_tooltip)); + callable_mp(this, &EditorToaster::_popup_str).call_deferred(p_message, p_severity, p_tooltip); is_processing_error = false; } @@ -433,19 +433,22 @@ void EditorToaster::_popup_str(const String &p_message, Severity p_severity, con hb->add_child(count_label); control = popup(hb, p_severity, default_message_duration, p_tooltip); - toasts[control].message = p_message; - toasts[control].tooltip = p_tooltip; - toasts[control].count = 1; - toasts[control].message_label = label; - toasts[control].message_count_label = count_label; + + Toast &toast = toasts[control]; + toast.message = p_message; + toast.tooltip = p_tooltip; + toast.count = 1; + toast.message_label = label; + toast.message_count_label = count_label; } else { - if (toasts[control].popped) { - toasts[control].count += 1; + Toast &toast = toasts[control]; + if (toast.popped) { + toast.count += 1; } else { - toasts[control].count = 1; + toast.count = 1; } - toasts[control].remaining_time = toasts[control].duration; - toasts[control].popped = true; + toast.remaining_time = toast.duration; + toast.popped = true; control->show(); vbox_container->move_child(control, vbox_container->get_child_count()); _auto_hide_or_free_toasts(); @@ -480,6 +483,16 @@ void EditorToaster::_popup_str(const String &p_message, Severity p_severity, con vbox_container->reset_size(); is_processing_error = false; + set_process_internal(true); +} + +void EditorToaster::_toast_theme_changed(Control *p_control) { + ERR_FAIL_COND(!toasts.has(p_control)); + + Toast &toast = toasts[p_control]; + if (toast.close_button) { + toast.close_button->set_button_icon(get_editor_theme_icon(SNAME("Close"))); + } } void EditorToaster::close(Control *p_control) { @@ -488,20 +501,12 @@ void EditorToaster::close(Control *p_control) { toasts[p_control].popped = false; } -void EditorToaster::_close_button_theme_changed(Control *p_close_button) { - Button *close_button = Object::cast_to<Button>(p_close_button); - if (close_button) { - close_button->set_button_icon(get_editor_theme_icon(SNAME("Close"))); - } -} - EditorToaster *EditorToaster::get_singleton() { return singleton; } EditorToaster::EditorToaster() { set_notify_transform(true); - set_process_internal(true); // VBox. vbox_container = memnew(VBoxContainer); diff --git a/editor/gui/editor_toaster.h b/editor/gui/editor_toaster.h index 4bf32d94ba..35a4337746 100644 --- a/editor/gui/editor_toaster.h +++ b/editor/gui/editor_toaster.h @@ -31,8 +31,6 @@ #ifndef EDITOR_TOASTER_H #define EDITOR_TOASTER_H -#include "core/string/ustring.h" -#include "core/templates/local_vector.h" #include "scene/gui/box_container.h" class Button; @@ -76,6 +74,9 @@ private: real_t remaining_time = 0.0; bool popped = false; + // Buttons + Button *close_button = nullptr; + // Messages String message; String tooltip; @@ -101,7 +102,7 @@ private: void _set_notifications_enabled(bool p_enabled); void _repop_old(); void _popup_str(const String &p_message, Severity p_severity, const String &p_tooltip); - void _close_button_theme_changed(Control *p_close_button); + void _toast_theme_changed(Control *p_control); protected: static EditorToaster *singleton; diff --git a/editor/icons/MaterialPreviewQuad.svg b/editor/icons/MaterialPreviewQuad.svg new file mode 100644 index 0000000000..9765a15df7 --- /dev/null +++ b/editor/icons/MaterialPreviewQuad.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="none" stroke="#000" stroke-linejoin="round" stroke-opacity=".8" stroke-width="2" d="m2 1 12 1v11l-12 1z"/><path fill="#f9f9f9" d="m2 14 12-1v-11l-12-1z"/></svg>
\ No newline at end of file diff --git a/editor/import/3d/resource_importer_obj.cpp b/editor/import/3d/resource_importer_obj.cpp index e77f5ec2b1..3669844207 100644 --- a/editor/import/3d/resource_importer_obj.cpp +++ b/editor/import/3d/resource_importer_obj.cpp @@ -535,8 +535,6 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes, } } - mesh->optimize_indices_for_cache(); - if (p_generate_lods) { // Use normal merge/split angles that match the defaults used for 3D scene importing. mesh->generate_lods(60.0f, {}); @@ -546,6 +544,8 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes, mesh->create_shadow_mesh(); } + mesh->optimize_indices(); + if (p_single_mesh && mesh->get_surface_count() > 0) { r_meshes.push_back(mesh); } diff --git a/editor/import/3d/resource_importer_obj.h b/editor/import/3d/resource_importer_obj.h index faf0f336c0..9d299bc31a 100644 --- a/editor/import/3d/resource_importer_obj.h +++ b/editor/import/3d/resource_importer_obj.h @@ -63,9 +63,6 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; - // Threaded import can currently cause deadlocks, see GH-48265. - virtual bool can_import_threaded() const override { return false; } - ResourceImporterOBJ(); }; diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp index 58af558e7b..edf7aa66f0 100644 --- a/editor/import/3d/resource_importer_scene.cpp +++ b/editor/import/3d/resource_importer_scene.cpp @@ -2567,8 +2567,6 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ } } - src_mesh_node->get_mesh()->optimize_indices_for_cache(); - if (generate_lods) { Array skin_pose_transform_array = _get_skinned_pose_transforms(src_mesh_node); src_mesh_node->get_mesh()->generate_lods(merge_angle, skin_pose_transform_array); @@ -2578,6 +2576,8 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ src_mesh_node->get_mesh()->create_shadow_mesh(); } + src_mesh_node->get_mesh()->optimize_indices(); + if (!save_to_file.is_empty()) { Ref<Mesh> existing = ResourceCache::get_ref(save_to_file); if (existing.is_valid()) { @@ -2622,6 +2622,7 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ mesh_node->set_layer_mask(src_mesh_node->get_layer_mask()); mesh_node->set_cast_shadows_setting(src_mesh_node->get_cast_shadows_setting()); + mesh_node->set_visible(src_mesh_node->is_visible()); mesh_node->set_visibility_range_begin(src_mesh_node->get_visibility_range_begin()); mesh_node->set_visibility_range_begin_margin(src_mesh_node->get_visibility_range_begin_margin()); mesh_node->set_visibility_range_end(src_mesh_node->get_visibility_range_end()); diff --git a/editor/import/3d/resource_importer_scene.h b/editor/import/3d/resource_importer_scene.h index fe757dc2a3..daeab2ae03 100644 --- a/editor/import/3d/resource_importer_scene.h +++ b/editor/import/3d/resource_importer_scene.h @@ -304,8 +304,6 @@ public: virtual bool has_advanced_options() const override; virtual void show_advanced_options(const String &p_path) override; - virtual bool can_import_threaded() const override { return false; } - ResourceImporterScene(const String &p_scene_import_type = "PackedScene", bool p_singleton = false); ~ResourceImporterScene(); diff --git a/editor/import/3d/scene_import_settings.cpp b/editor/import/3d/scene_import_settings.cpp index 645b7fda88..945c1811d7 100644 --- a/editor/import/3d/scene_import_settings.cpp +++ b/editor/import/3d/scene_import_settings.cpp @@ -368,6 +368,7 @@ void SceneImportSettingsDialog::_fill_scene(Node *p_node, TreeItem *p_parent_ite mesh_node->set_transform(src_mesh_node->get_transform()); mesh_node->set_skin(src_mesh_node->get_skin()); mesh_node->set_skeleton_path(src_mesh_node->get_skeleton_path()); + mesh_node->set_visible(src_mesh_node->is_visible()); if (src_mesh_node->get_mesh().is_valid()) { Ref<ImporterMesh> editor_mesh = src_mesh_node->get_mesh(); mesh_node->set_mesh(editor_mesh->get_mesh()); diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index 8963c8d918..30564bf0fe 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -50,6 +50,8 @@ public: virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterBitMap(); ~ResourceImporterBitMap(); }; diff --git a/editor/import/resource_importer_bmfont.h b/editor/import/resource_importer_bmfont.h index d31cd03736..48f036ff13 100644 --- a/editor/import/resource_importer_bmfont.h +++ b/editor/import/resource_importer_bmfont.h @@ -50,6 +50,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterBMFont(); }; diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index c6b05eb043..9c83719ed1 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -51,6 +51,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterCSVTranslation(); }; diff --git a/editor/import/resource_importer_dynamic_font.h b/editor/import/resource_importer_dynamic_font.h index de89e6b76f..7c7a16cf92 100644 --- a/editor/import/resource_importer_dynamic_font.h +++ b/editor/import/resource_importer_dynamic_font.h @@ -60,6 +60,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterDynamicFont(); }; diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index 1490ab30d5..dd395009c1 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -52,6 +52,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterImage(); }; diff --git a/editor/import/resource_importer_imagefont.h b/editor/import/resource_importer_imagefont.h index 065351c361..6b30a3cd6e 100644 --- a/editor/import/resource_importer_imagefont.h +++ b/editor/import/resource_importer_imagefont.h @@ -50,6 +50,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterImageFont(); }; diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 26495eed8d..d8b5bc2d14 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -117,6 +117,8 @@ public: virtual bool are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const override; virtual String get_import_settings_string() const override; + virtual bool can_import_threaded() const override { return true; } + void set_mode(Mode p_mode) { mode = p_mode; } ResourceImporterLayeredTexture(bool p_singleton = false); diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h index aefc967989..b28dea36d6 100644 --- a/editor/import/resource_importer_shader_file.h +++ b/editor/import/resource_importer_shader_file.h @@ -51,6 +51,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterShaderFile(); }; diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 6d74c4e2f9..6c87cd0abb 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -102,6 +102,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + void update_imports(); virtual bool are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const override; diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h index 0f2b10424c..e4ad9ac230 100644 --- a/editor/import/resource_importer_texture_atlas.h +++ b/editor/import/resource_importer_texture_atlas.h @@ -67,6 +67,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual Error import_group_file(const String &p_group_file, const HashMap<String, HashMap<StringName, Variant>> &p_source_file_options, const HashMap<String, String> &p_base_paths) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterTextureAtlas(); }; diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 339e7921b3..2654952e8a 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -213,9 +213,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s frames = remaining_bytes; } - if (format_channels == 0) { - ERR_FAIL_COND_V(format_channels == 0, ERR_INVALID_DATA); - } + ERR_FAIL_COND_V(format_channels == 0, ERR_INVALID_DATA); frames /= format_channels; frames /= (format_bits >> 3); diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index 47af37ba41..2253756554 100644 --- a/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h @@ -142,6 +142,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterWAV(); }; diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index d9f8aae7f7..8b105955e7 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -859,7 +859,7 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { // 4-1. Guess Finger int tips_index = -1; - bool thumb_tips_size = 0; + bool thumb_tips_size = false; bool named_finger_is_found = false; LocalVector<String> fingers; fingers.push_back("thumb|pollex"); @@ -994,7 +994,7 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { } tips_index = -1; - thumb_tips_size = 0; + thumb_tips_size = false; named_finger_is_found = false; if (right_hand_or_palm != -1) { LocalVector<LocalVector<String>> right_fingers_map; diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index d27e85495c..7cf0b2d2ac 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -470,7 +470,7 @@ void EditorPropertyOTVariation::update_property() { Vector3i range = supported.get_value_at_index(i); EditorPropertyInteger *prop = memnew(EditorPropertyInteger); - prop->setup(range.x, range.y, false, 1, false, false); + prop->setup(range.x, range.y, false, true, false, false); prop->set_object_and_property(object.ptr(), "keys/" + itos(name_tag)); String name = TS->tag_to_name(name_tag); diff --git a/editor/plugins/game_view_plugin.cpp b/editor/plugins/game_view_plugin.cpp index f45af72e90..5c1f81ee94 100644 --- a/editor/plugins/game_view_plugin.cpp +++ b/editor/plugins/game_view_plugin.cpp @@ -30,6 +30,7 @@ #include "game_view_plugin.h" +#include "core/debugger/debugger_marshalls.h" #include "editor/editor_main_screen.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" @@ -40,7 +41,15 @@ #include "scene/gui/separator.h" void GameViewDebugger::_session_started(Ref<EditorDebuggerSession> p_session) { - p_session->send_message("scene:runtime_node_select_setup", Array()); + Array setup_data; + Dictionary settings; + settings["editors/panning/2d_editor_panning_scheme"] = EDITOR_GET("editors/panning/2d_editor_panning_scheme"); + settings["editors/panning/simple_panning"] = EDITOR_GET("editors/panning/simple_panning"); + settings["editors/panning/warped_mouse_panning"] = EDITOR_GET("editors/panning/warped_mouse_panning"); + settings["editors/panning/2d_editor_pan_speed"] = EDITOR_GET("editors/panning/2d_editor_pan_speed"); + settings["canvas_item_editor/pan_view"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("canvas_item_editor/pan_view")); + setup_data.append(settings); + p_session->send_message("scene:runtime_node_select_setup", setup_data); Array type; type.append(node_type); diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index be44d57376..8bdc763ebe 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -56,9 +56,15 @@ void MaterialEditor::gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) { rot.x -= mm->get_relative().y * 0.01; rot.y -= mm->get_relative().x * 0.01; - - rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2); + if (quad_instance->is_visible()) { + // Clamp rotation so the quad is always visible. + const real_t limit = Math::deg_to_rad(80.0); + rot = rot.clampf(-limit, limit); + } else { + rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2); + } _update_rotation(); + _store_rotation_metadata(); } } @@ -70,6 +76,7 @@ void MaterialEditor::_update_theme_item_cache() { theme_cache.sphere_icon = get_editor_theme_icon(SNAME("MaterialPreviewSphere")); theme_cache.box_icon = get_editor_theme_icon(SNAME("MaterialPreviewCube")); + theme_cache.quad_icon = get_editor_theme_icon(SNAME("MaterialPreviewQuad")); theme_cache.checkerboard = get_editor_theme_icon(SNAME("Checkerboard")); } @@ -82,6 +89,7 @@ void MaterialEditor::_notification(int p_what) { sphere_switch->set_button_icon(theme_cache.sphere_icon); box_switch->set_button_icon(theme_cache.box_icon); + quad_switch->set_button_icon(theme_cache.quad_icon); error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor))); } break; @@ -95,6 +103,18 @@ void MaterialEditor::_notification(int p_what) { } } +void MaterialEditor::_set_rotation(real_t p_x_degrees, real_t p_y_degrees) { + rot.x = Math::deg_to_rad(p_x_degrees); + rot.y = Math::deg_to_rad(p_y_degrees); + _update_rotation(); +} + +// Store the rotation so it can persist when switching between materials. +void MaterialEditor::_store_rotation_metadata() { + Vector2 rotation_degrees = Vector2(Math::rad_to_deg(rot.x), Math::rad_to_deg(rot.y)); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_rotation", rotation_degrees); +} + void MaterialEditor::_update_rotation() { Transform3D t; t.basis.rotate(Vector3(0, 1, 0), -rot.y); @@ -124,6 +144,7 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_en vc->show(); sphere_instance->set_material_override(material); box_instance->set_material_override(material); + quad_instance->set_material_override(material); break; default: layout_error->show(); @@ -136,10 +157,6 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_en } else { hide(); } - - rot.x = Math::deg_to_rad(-15.0); - rot.y = Math::deg_to_rad(30.0); - _update_rotation(); } void MaterialEditor::_on_light_1_switch_pressed() { @@ -151,19 +168,36 @@ void MaterialEditor::_on_light_2_switch_pressed() { } void MaterialEditor::_on_sphere_switch_pressed() { - box_instance->hide(); sphere_instance->show(); + box_instance->hide(); + quad_instance->hide(); box_switch->set_pressed(false); - sphere_switch->set_pressed(true); - EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", true); + quad_switch->set_pressed(false); + _set_rotation(-15.0, 30.0); + _store_rotation_metadata(); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "sphere"); } void MaterialEditor::_on_box_switch_pressed() { + sphere_instance->hide(); box_instance->show(); + quad_instance->hide(); + sphere_switch->set_pressed(false); + quad_switch->set_pressed(false); + _set_rotation(-15.0, 30.0); + _store_rotation_metadata(); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "box"); +} + +void MaterialEditor::_on_quad_switch_pressed() { sphere_instance->hide(); - box_switch->set_pressed(true); + box_instance->hide(); + quad_instance->show(); sphere_switch->set_pressed(false); - EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", false); + box_switch->set_pressed(false); + _set_rotation(0.0, 0.0); + _store_rotation_metadata(); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "quad"); } MaterialEditor::MaterialEditor() { @@ -213,7 +247,7 @@ MaterialEditor::MaterialEditor() { viewport = memnew(SubViewport); Ref<World3D> world_3d; world_3d.instantiate(); - viewport->set_world_3d(world_3d); //use own world + viewport->set_world_3d(world_3d); // Use own world. vc->add_child(viewport); viewport->set_disable_input(true); viewport->set_transparent_background(true); @@ -221,7 +255,7 @@ MaterialEditor::MaterialEditor() { camera = memnew(Camera3D); camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 1.1))); - // Use low field of view so the sphere/box is fully encompassed within the preview, + // Use low field of view so the sphere/box/quad is fully encompassed within the preview, // without much distortion. camera->set_perspective(20, 0.1, 10); camera->make_current(); @@ -249,13 +283,19 @@ MaterialEditor::MaterialEditor() { box_instance = memnew(MeshInstance3D); rotation->add_child(box_instance); - box_instance->set_transform(Transform3D() * 0.25); + quad_instance = memnew(MeshInstance3D); + rotation->add_child(quad_instance); + sphere_instance->set_transform(Transform3D() * 0.375); + box_instance->set_transform(Transform3D() * 0.25); + quad_instance->set_transform(Transform3D() * 0.375); sphere_mesh.instantiate(); sphere_instance->set_mesh(sphere_mesh); box_mesh.instantiate(); box_instance->set_mesh(box_mesh); + quad_mesh.instantiate(); + quad_instance->set_mesh(quad_mesh); set_custom_minimum_size(Size2(1, 150) * EDSCALE); @@ -269,17 +309,21 @@ MaterialEditor::MaterialEditor() { sphere_switch = memnew(Button); sphere_switch->set_theme_type_variation("PreviewLightButton"); sphere_switch->set_toggle_mode(true); - sphere_switch->set_pressed(true); vb_shape->add_child(sphere_switch); sphere_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_sphere_switch_pressed)); box_switch = memnew(Button); box_switch->set_theme_type_variation("PreviewLightButton"); box_switch->set_toggle_mode(true); - box_switch->set_pressed(false); vb_shape->add_child(box_switch); box_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_box_switch_pressed)); + quad_switch = memnew(Button); + quad_switch->set_theme_type_variation("PreviewLightButton"); + quad_switch->set_toggle_mode(true); + vb_shape->add_child(quad_switch); + quad_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_quad_switch_pressed)); + layout_3d->add_spacer(); VBoxContainer *vb_light = memnew(VBoxContainer); @@ -299,14 +343,23 @@ MaterialEditor::MaterialEditor() { vb_light->add_child(light_2_switch); light_2_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_light_2_switch_pressed)); - if (EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_on_sphere", true)) { + String shape = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_mesh", "sphere"); + if (shape == "sphere") { box_instance->hide(); + quad_instance->hide(); + sphere_switch->set_pressed_no_signal(true); + } else if (shape == "box") { + sphere_instance->hide(); + quad_instance->hide(); + box_switch->set_pressed_no_signal(true); } else { - box_instance->show(); sphere_instance->hide(); - box_switch->set_pressed(true); - sphere_switch->set_pressed(false); + box_instance->hide(); + quad_switch->set_pressed_no_signal(true); } + + Vector2 stored_rot = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_rotation", Vector2()); + _set_rotation(stored_rot.x, stored_rot.y); } /////////////////////// diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 28c59d27db..c1b37a5831 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -62,6 +62,7 @@ class MaterialEditor : public Control { Node3D *rotation = nullptr; MeshInstance3D *sphere_instance = nullptr; MeshInstance3D *box_instance = nullptr; + MeshInstance3D *quad_instance = nullptr; DirectionalLight3D *light1 = nullptr; DirectionalLight3D *light2 = nullptr; Camera3D *camera = nullptr; @@ -69,6 +70,7 @@ class MaterialEditor : public Control { Ref<SphereMesh> sphere_mesh; Ref<BoxMesh> box_mesh; + Ref<QuadMesh> quad_mesh; VBoxContainer *layout_error = nullptr; Label *error_label = nullptr; @@ -80,6 +82,7 @@ class MaterialEditor : public Control { Button *sphere_switch = nullptr; Button *box_switch = nullptr; + Button *quad_switch = nullptr; Button *light_1_switch = nullptr; Button *light_2_switch = nullptr; @@ -88,6 +91,7 @@ class MaterialEditor : public Control { Ref<Texture2D> light_2_icon; Ref<Texture2D> sphere_icon; Ref<Texture2D> box_icon; + Ref<Texture2D> quad_icon; Ref<Texture2D> checkerboard; } theme_cache; @@ -95,11 +99,14 @@ class MaterialEditor : public Control { void _on_light_2_switch_pressed(); void _on_sphere_switch_pressed(); void _on_box_switch_pressed(); + void _on_quad_switch_pressed(); protected: virtual void _update_theme_item_cache() override; void _notification(int p_what); void gui_input(const Ref<InputEvent> &p_event) override; + void _set_rotation(real_t p_x_degrees, real_t p_y_degrees); + void _store_rotation_metadata(); void _update_rotation(); public: diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 48dcd2e6fc..fdc222e64f 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "scene/3d/physics/collision_shape_3d.h" #include "scene/3d/physics/physics_body_3d.h" #include "scene/3d/physics/static_body_3d.h" +#include "scene/gui/aspect_ratio_container.h" #include "scene/gui/box_container.h" #include "scene/gui/dialogs.h" #include "scene/gui/menu_button.h" @@ -445,10 +446,43 @@ void MeshInstance3DEditor::_debug_uv_draw() { } debug_uv->set_clip_contents(true); - debug_uv->draw_rect(Rect2(Vector2(), debug_uv->get_size()), get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor))); + debug_uv->draw_rect( + Rect2(Vector2(), debug_uv->get_size()), + get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor))); + + // Draw an outline to represent the UV2's beginning and end area (useful on Black OLED theme). + // Top-left coordinate needs to be `(1, 1)` to prevent `clip_contents` from clipping the top and left lines. + debug_uv->draw_rect( + Rect2(Vector2(1, 1), debug_uv->get_size() - Vector2(1, 1)), + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.125), + false, + Math::round(EDSCALE)); + + for (int x = 1; x <= 7; x++) { + debug_uv->draw_line( + Vector2(debug_uv->get_size().x * 0.125 * x, 0), + Vector2(debug_uv->get_size().x * 0.125 * x, debug_uv->get_size().y), + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.125), + Math::round(EDSCALE)); + } + + for (int y = 1; y <= 7; y++) { + debug_uv->draw_line( + Vector2(0, debug_uv->get_size().y * 0.125 * y), + Vector2(debug_uv->get_size().x, debug_uv->get_size().y * 0.125 * y), + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.125), + Math::round(EDSCALE)); + } + debug_uv->draw_set_transform(Vector2(), 0, debug_uv->get_size()); + // Use a translucent color to allow overlapping triangles to be visible. - debug_uv->draw_multiline(uv_lines, get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.5)); + // Divide line width by the drawing scale set above, so that line width is consistent regardless of dialog size. + // Aspect ratio is preserved by the parent AspectRatioContainer, so we only need to check the X size which is always equal to Y. + debug_uv->draw_multiline( + uv_lines, + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.5), + Math::round(EDSCALE) / debug_uv->get_size().x); } void MeshInstance3DEditor::_create_navigation_mesh() { @@ -613,10 +647,14 @@ MeshInstance3DEditor::MeshInstance3DEditor() { debug_uv_dialog = memnew(AcceptDialog); debug_uv_dialog->set_title(TTR("UV Channel Debug")); add_child(debug_uv_dialog); + + debug_uv_arc = memnew(AspectRatioContainer); + debug_uv_dialog->add_child(debug_uv_arc); + debug_uv = memnew(Control); debug_uv->set_custom_minimum_size(Size2(600, 600) * EDSCALE); debug_uv->connect(SceneStringName(draw), callable_mp(this, &MeshInstance3DEditor::_debug_uv_draw)); - debug_uv_dialog->add_child(debug_uv); + debug_uv_arc->add_child(debug_uv); navigation_mesh_dialog = memnew(ConfirmationDialog); navigation_mesh_dialog->set_title(TTR("Create NavigationMesh")); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h index c982df9c5f..569ecd4fff 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.h +++ b/editor/plugins/mesh_instance_3d_editor_plugin.h @@ -36,6 +36,7 @@ #include "scene/gui/option_button.h" class AcceptDialog; +class AspectRatioContainer; class ConfirmationDialog; class MenuButton; class SpinBox; @@ -79,6 +80,7 @@ class MeshInstance3DEditor : public Control { AcceptDialog *err_dialog = nullptr; AcceptDialog *debug_uv_dialog = nullptr; + AspectRatioContainer *debug_uv_arc = nullptr; Control *debug_uv = nullptr; Vector<Vector2> uv_lines; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index b877c0b83e..5afe01025d 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -8480,7 +8480,7 @@ void Node3DEditor::clear() { } for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { - viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(Node3DEditorViewport::VIEW_AUDIO_LISTENER), i == 0); + viewports[i]->view_menu->get_popup()->set_item_checked(viewports[i]->view_menu->get_popup()->get_item_index(Node3DEditorViewport::VIEW_AUDIO_LISTENER), i == 0); viewports[i]->viewport->set_as_audio_listener_3d(i == 0); } diff --git a/editor/plugins/tiles/tile_map_layer_editor.cpp b/editor/plugins/tiles/tile_map_layer_editor.cpp index 804db68f86..16d4ee6f68 100644 --- a/editor/plugins/tiles/tile_map_layer_editor.cpp +++ b/editor/plugins/tiles/tile_map_layer_editor.cpp @@ -1550,6 +1550,7 @@ int TileMapLayerEditorTilesPlugin::_get_transformed_alternative(int p_alternativ case TRANSFORM_ROTATE_RIGHT: { // A matrix with every possible flip/transpose combination, sorted by what comes next when you rotate. const LocalVector<bool> rotation_matrix = { + // NOLINTBEGIN(modernize-use-bool-literals) 0, 0, 0, 0, 1, 1, 1, 1, 0, @@ -1558,6 +1559,7 @@ int TileMapLayerEditorTilesPlugin::_get_transformed_alternative(int p_alternativ 0, 0, 1, 0, 1, 0, 1, 1, 1 + // NOLINTEND(modernize-use-bool-literals) }; for (int i = 0; i < 8; i++) { diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h index 39f2f51ef3..f8b65bd675 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.h +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h @@ -91,7 +91,7 @@ public: TileSetAtlasSourceEditor *tiles_set_atlas_source_editor = nullptr; Ref<TileSetAtlasSource> tile_set_atlas_source; - RBSet<TileSelection> tiles = RBSet<TileSelection>(); + RBSet<TileSelection> tiles; protected: bool _set(const StringName &p_name, const Variant &p_value); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 05929c5f0d..9c1befa144 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1472,7 +1472,7 @@ void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_ if (visual_shader.is_valid() && visual_shader->get_shader_type() == p_type) { graph->disconnect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port); - for (const List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { + for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { connections.erase(E); break; diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index f8ceb871dc..d08610c93f 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -716,8 +716,9 @@ Vector<String> ProjectConverter3To4::check_for_files() { directories_to_check.append(current_dir.path_join(file_name) + "/"); } else { bool proper_extension = false; - if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".gdshader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj") || file_name.ends_with(".import")) + if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".gdshader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj") || file_name.ends_with(".import")) { proper_extension = true; + } if (proper_extension) { collected_files.append(current_dir.path_join(file_name)); @@ -1321,8 +1322,9 @@ Vector<String> ProjectConverter3To4::parse_arguments(const String &line) { break; }; case '"': { - if (previous_character != '\\') + if (previous_character != '\\') { is_inside_string = !is_inside_string; + } } } previous_character = character; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 19b7122a0d..87ba2e6875 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -126,7 +126,8 @@ void SceneTreeDock::input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT)) { - if (mb->is_pressed() && scene_tree->get_rect().has_point(scene_tree->get_local_mouse_position())) { + Tree *tree = scene_tree->get_scene_tree(); + if (mb->is_pressed() && tree->get_rect().has_point(tree->get_local_mouse_position())) { tree_clicked = true; } else if (!mb->is_pressed()) { tree_clicked = false; diff --git a/editor/themes/editor_color_map.cpp b/editor/themes/editor_color_map.cpp index 9046a8b688..3c3d755586 100644 --- a/editor/themes/editor_color_map.cpp +++ b/editor/themes/editor_color_map.cpp @@ -173,6 +173,8 @@ void EditorColorMap::create() { add_conversion_exception("OverbrightIndicator"); add_conversion_exception("MaterialPreviewCube"); add_conversion_exception("MaterialPreviewSphere"); + add_conversion_exception("MaterialPreviewQuad"); + add_conversion_exception("MaterialPreviewLight1"); add_conversion_exception("MaterialPreviewLight2"); diff --git a/main/main.cpp b/main/main.cpp index e8086db9d3..fb21ee502f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1801,6 +1801,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (arg == "--" || arg == "++") { adding_user_args = true; } else { + if (!FileAccess::exists(arg) && !DirAccess::exists(arg)) { + // Warn if the argument isn't recognized by Godot *and* the file/folder + // specified by a positional argument doesn't exist. + // This allows projects to read file or folder paths as a positional argument + // without printing a warning, as this scenario can't make use of user command line arguments. + WARN_PRINT(vformat("Unknown command line argument \"%s\". User arguments should be passed after a -- or ++ separator, e.g. \"-- %s\".", arg, arg)); + } main_args.push_back(arg); } diff --git a/methods.py b/methods.py index 65b88a5c65..64c3839718 100644 --- a/methods.py +++ b/methods.py @@ -73,21 +73,13 @@ def print_error(*values: object) -> None: def add_source_files_orig(self, sources, files, allow_gen=False): # Convert string to list of absolute paths (including expanding wildcard) - if isinstance(files, (str, bytes)): - # Keep SCons project-absolute path as they are (no wildcard support) - if files.startswith("#"): - if "*" in files: - print_error("Wildcards can't be expanded in SCons project-absolute path: '{}'".format(files)) - return - files = [files] - else: - # Exclude .gen.cpp files from globbing, to avoid including obsolete ones. - # They should instead be added manually. - skip_gen_cpp = "*" in files - dir_path = self.Dir(".").abspath - files = sorted(glob.glob(dir_path + "/" + files)) - if skip_gen_cpp and not allow_gen: - files = [f for f in files if not f.endswith(".gen.cpp")] + if isinstance(files, str): + # Exclude .gen.cpp files from globbing, to avoid including obsolete ones. + # They should instead be added manually. + skip_gen_cpp = "*" in files + files = self.Glob(files) + if skip_gen_cpp and not allow_gen: + files = [f for f in files if not str(f).endswith(".gen.cpp")] # Add each path as compiled Object following environment (self) configuration for path in files: @@ -98,35 +90,6 @@ def add_source_files_orig(self, sources, files, allow_gen=False): sources.append(obj) -# The section name is used for checking -# the hash table to see whether the folder -# is included in the SCU build. -# It will be something like "core/math". -def _find_scu_section_name(subdir): - section_path = os.path.abspath(subdir) + "/" - - folders = [] - folder = "" - - for i in range(8): - folder = os.path.dirname(section_path) - folder = os.path.basename(folder) - if folder == base_folder_only: - break - folders += [folder] - section_path += "../" - section_path = os.path.abspath(section_path) + "/" - - section_name = "" - for n in range(len(folders)): - # section_name += folders[len(folders) - n - 1] + " " - section_name += folders[len(folders) - n - 1] - if n != (len(folders) - 1): - section_name += "/" - - return section_name - - def add_source_files_scu(self, sources, files, allow_gen=False): if self["scu_build"] and isinstance(files, str): if "*." not in files: @@ -135,10 +98,8 @@ def add_source_files_scu(self, sources, files, allow_gen=False): # If the files are in a subdirectory, we want to create the scu gen # files inside this subdirectory. subdir = os.path.dirname(files) - if subdir != "": - subdir += "/" - - section_name = _find_scu_section_name(subdir) + subdir = subdir if subdir == "" else subdir + "/" + section_name = self.Dir(subdir).tpath # if the section name is in the hash table? # i.e. is it part of the SCU build? global _scu_folders @@ -277,34 +238,6 @@ def get_version_info(module_version_string="", silent=False): return version_info -def parse_cg_file(fname, uniforms, sizes, conditionals): - with open(fname, "r", encoding="utf-8") as fs: - line = fs.readline() - - while line: - if re.match(r"^\s*uniform", line): - res = re.match(r"uniform ([\d\w]*) ([\d\w]*)") - type = res.groups(1) - name = res.groups(2) - - uniforms.append(name) - - if type.find("texobj") != -1: - sizes.append(1) - else: - t = re.match(r"float(\d)x(\d)", type) - if t: - sizes.append(int(t.groups(1)) * int(t.groups(2))) - else: - t = re.match(r"float(\d)", type) - sizes.append(int(t.groups(1))) - - if line.find("[branch]") != -1: - conditionals.append(name) - - line = fs.readline() - - def get_cmdline_bool(option, default): """We use `ARGUMENTS.get()` to check if options were manually overridden on the command line, and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings. @@ -563,40 +496,7 @@ def detect_visual_c_compiler_version(tools_env): vc_chosen_compiler_index = -1 vc_chosen_compiler_str = "" - # Start with Pre VS 2017 checks which uses VCINSTALLDIR: - if "VCINSTALLDIR" in tools_env: - # print("Checking VCINSTALLDIR") - - # find() works with -1 so big ifs below are needed... the simplest solution, in fact - # First test if amd64 and amd64_x86 compilers are present in the path - vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64;") - if vc_amd64_compiler_detection_index > -1: - vc_chosen_compiler_index = vc_amd64_compiler_detection_index - vc_chosen_compiler_str = "amd64" - - vc_amd64_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64_x86;") - if vc_amd64_x86_compiler_detection_index > -1 and ( - vc_chosen_compiler_index == -1 or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index - ): - vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index - vc_chosen_compiler_str = "amd64_x86" - - # Now check the 32 bit compilers - vc_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN;") - if vc_x86_compiler_detection_index > -1 and ( - vc_chosen_compiler_index == -1 or vc_chosen_compiler_index > vc_x86_compiler_detection_index - ): - vc_chosen_compiler_index = vc_x86_compiler_detection_index - vc_chosen_compiler_str = "x86" - - vc_x86_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\x86_amd64;") - if vc_x86_amd64_compiler_detection_index > -1 and ( - vc_chosen_compiler_index == -1 or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index - ): - vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index - vc_chosen_compiler_str = "x86_amd64" - - # and for VS 2017 and newer we check VCTOOLSINSTALLDIR: + # VS 2017 and newer should set VCTOOLSINSTALLDIR if "VCTOOLSINSTALLDIR" in tools_env: # Newer versions have a different path available vc_amd64_compiler_detection_index = ( diff --git a/modules/bcdec/image_decompress_bcdec.cpp b/modules/bcdec/image_decompress_bcdec.cpp index c76470e3cc..8a62cd2a4e 100644 --- a/modules/bcdec/image_decompress_bcdec.cpp +++ b/modules/bcdec/image_decompress_bcdec.cpp @@ -47,7 +47,6 @@ inline void bcdec_bc6h_half_u(const void *compressedBlock, void *decompressedBlo static void decompress_image(BCdecFormat format, const void *src, void *dst, const uint64_t width, const uint64_t height) { const uint8_t *src_blocks = reinterpret_cast<const uint8_t *>(src); uint8_t *dec_blocks = reinterpret_cast<uint8_t *>(dst); - uint64_t src_pos = 0, dst_pos = 0; #define DECOMPRESS_LOOP(func, block_size, color_bytesize, color_components) \ for (uint64_t y = 0; y < height; y += 4) { \ @@ -59,34 +58,96 @@ static void decompress_image(BCdecFormat format, const void *src, void *dst, con dst_pos += 3 * width * color_bytesize; \ } - switch (format) { - case BCdec_BC1: { - DECOMPRESS_LOOP(bcdec_bc1, BCDEC_BC1_BLOCK_SIZE, 4, 4) - } break; - case BCdec_BC2: { - DECOMPRESS_LOOP(bcdec_bc2, BCDEC_BC2_BLOCK_SIZE, 4, 4) - } break; - case BCdec_BC3: { - DECOMPRESS_LOOP(bcdec_bc3, BCDEC_BC3_BLOCK_SIZE, 4, 4) - } break; - case BCdec_BC4: { - DECOMPRESS_LOOP(bcdec_bc4, BCDEC_BC4_BLOCK_SIZE, 1, 1) - } break; - case BCdec_BC5: { - DECOMPRESS_LOOP(bcdec_bc5, BCDEC_BC5_BLOCK_SIZE, 2, 2) - } break; - case BCdec_BC6U: { - DECOMPRESS_LOOP(bcdec_bc6h_half_u, BCDEC_BC6H_BLOCK_SIZE, 6, 3) - } break; - case BCdec_BC6S: { - DECOMPRESS_LOOP(bcdec_bc6h_half_s, BCDEC_BC6H_BLOCK_SIZE, 6, 3) - } break; - case BCdec_BC7: { - DECOMPRESS_LOOP(bcdec_bc7, BCDEC_BC7_BLOCK_SIZE, 4, 4) - } break; +#define DECOMPRESS_LOOP_SAFE(func, block_size, color_bytesize, color_components, output) \ + for (uint64_t y = 0; y < height; y += 4) { \ + for (uint64_t x = 0; x < width; x += 4) { \ + const uint32_t yblock = MIN(height - y, 4ul); \ + const uint32_t xblock = MIN(width - x, 4ul); \ + \ + const bool incomplete = yblock < 4 && xblock < 4; \ + uint8_t *dec_out = incomplete ? output : &dec_blocks[y * 4 * width + x * color_bytesize]; \ + \ + func(&src_blocks[src_pos], dec_out, 4 * color_components); \ + src_pos += block_size; \ + \ + if (incomplete) { \ + for (uint32_t cy = 0; cy < yblock; cy++) { \ + for (uint32_t cx = 0; cx < xblock; cx++) { \ + memcpy(&dec_blocks[(y + cy) * 4 * width + (x + cx) * color_bytesize], &output[cy * 4 + cx * color_bytesize], color_bytesize); \ + } \ + } \ + } \ + } \ + } + + if (width % 4 != 0 || height % 4 != 0) { + uint64_t src_pos = 0; + + uint8_t r8_output[4 * 4]; + uint8_t rg8_output[4 * 4 * 2]; + uint8_t rgba8_output[4 * 4 * 4]; + uint8_t rgbh_output[4 * 4 * 6]; + + switch (format) { + case BCdec_BC1: { + DECOMPRESS_LOOP_SAFE(bcdec_bc1, BCDEC_BC1_BLOCK_SIZE, 4, 4, rgba8_output) + } break; + case BCdec_BC2: { + DECOMPRESS_LOOP_SAFE(bcdec_bc2, BCDEC_BC2_BLOCK_SIZE, 4, 4, rgba8_output) + } break; + case BCdec_BC3: { + DECOMPRESS_LOOP_SAFE(bcdec_bc3, BCDEC_BC3_BLOCK_SIZE, 4, 4, rgba8_output) + } break; + case BCdec_BC4: { + DECOMPRESS_LOOP_SAFE(bcdec_bc4, BCDEC_BC4_BLOCK_SIZE, 1, 1, r8_output) + } break; + case BCdec_BC5: { + DECOMPRESS_LOOP_SAFE(bcdec_bc5, BCDEC_BC5_BLOCK_SIZE, 2, 2, rg8_output) + } break; + case BCdec_BC6U: { + DECOMPRESS_LOOP_SAFE(bcdec_bc6h_half_u, BCDEC_BC6H_BLOCK_SIZE, 6, 3, rgbh_output) + } break; + case BCdec_BC6S: { + DECOMPRESS_LOOP_SAFE(bcdec_bc6h_half_s, BCDEC_BC6H_BLOCK_SIZE, 6, 3, rgbh_output) + } break; + case BCdec_BC7: { + DECOMPRESS_LOOP_SAFE(bcdec_bc7, BCDEC_BC7_BLOCK_SIZE, 4, 4, rgba8_output) + } break; + } + + } else { + uint64_t src_pos = 0, dst_pos = 0; + + switch (format) { + case BCdec_BC1: { + DECOMPRESS_LOOP(bcdec_bc1, BCDEC_BC1_BLOCK_SIZE, 4, 4) + } break; + case BCdec_BC2: { + DECOMPRESS_LOOP(bcdec_bc2, BCDEC_BC2_BLOCK_SIZE, 4, 4) + } break; + case BCdec_BC3: { + DECOMPRESS_LOOP(bcdec_bc3, BCDEC_BC3_BLOCK_SIZE, 4, 4) + } break; + case BCdec_BC4: { + DECOMPRESS_LOOP(bcdec_bc4, BCDEC_BC4_BLOCK_SIZE, 1, 1) + } break; + case BCdec_BC5: { + DECOMPRESS_LOOP(bcdec_bc5, BCDEC_BC5_BLOCK_SIZE, 2, 2) + } break; + case BCdec_BC6U: { + DECOMPRESS_LOOP(bcdec_bc6h_half_u, BCDEC_BC6H_BLOCK_SIZE, 6, 3) + } break; + case BCdec_BC6S: { + DECOMPRESS_LOOP(bcdec_bc6h_half_s, BCDEC_BC6H_BLOCK_SIZE, 6, 3) + } break; + case BCdec_BC7: { + DECOMPRESS_LOOP(bcdec_bc7, BCDEC_BC7_BLOCK_SIZE, 4, 4) + } break; + } } #undef DECOMPRESS_LOOP +#undef DECOMPRESS_LOOP_SAFE } void image_decompress_bcdec(Image *p_image) { diff --git a/modules/betsy/image_compress_betsy.h b/modules/betsy/image_compress_betsy.h index 4e0bf0538f..ab7b785803 100644 --- a/modules/betsy/image_compress_betsy.h +++ b/modules/betsy/image_compress_betsy.h @@ -91,10 +91,10 @@ class BetsyCompressor : public Object { RenderingDevice *compress_rd = nullptr; RenderingContextDriver *compress_rcd = nullptr; HashMap<String, BetsyShader> cached_shaders; - RID src_sampler = RID(); + RID src_sampler; // Format-specific resources. - RID dxt1_encoding_table_buffer = RID(); + RID dxt1_encoding_table_buffer; void _init(); void _assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id); diff --git a/modules/camera/camera_feed_linux.cpp b/modules/camera/camera_feed_linux.cpp index 94bb2b6ad3..3ae1b70ac9 100644 --- a/modules/camera/camera_feed_linux.cpp +++ b/modules/camera/camera_feed_linux.cpp @@ -145,7 +145,7 @@ bool CameraFeedLinux::_request_buffers() { } buffers[i].length = buffer.length; - buffers[i].start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, file_descriptor, buffer.m.offset); + buffers[i].start = mmap(nullptr, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, file_descriptor, buffer.m.offset); if (buffers[i].start == MAP_FAILED) { for (unsigned int b = 0; b < i; b++) { diff --git a/modules/fbx/fbx_document.cpp b/modules/fbx/fbx_document.cpp index ce097092fb..d6c304d056 100644 --- a/modules/fbx/fbx_document.cpp +++ b/modules/fbx/fbx_document.cpp @@ -369,21 +369,25 @@ Error FBXDocument::_parse_nodes(Ref<FBXState> p_state) { // all skin clusters connected to the bone. for (const ufbx_connection &child_conn : fbx_node->element.connections_src) { ufbx_skin_cluster *child_cluster = ufbx_as_skin_cluster(child_conn.dst); - if (!child_cluster) + if (!child_cluster) { continue; + } ufbx_skin_deformer *child_deformer = _find_skin_deformer(child_cluster); - if (!child_deformer) + if (!child_deformer) { continue; + } // Found a skin cluster: Now iterate through all the skin clusters of the parent and // try to find one that used by the same deformer. for (const ufbx_connection &parent_conn : fbx_node->parent->element.connections_src) { ufbx_skin_cluster *parent_cluster = ufbx_as_skin_cluster(parent_conn.dst); - if (!parent_cluster) + if (!parent_cluster) { continue; + } ufbx_skin_deformer *parent_deformer = _find_skin_deformer(parent_cluster); - if (parent_deformer != child_deformer) + if (parent_deformer != child_deformer) { continue; + } // Success: Found two skin clusters from the same deformer, now we can resolve the // local bind pose from the difference between the two world-space bind poses. @@ -1389,7 +1393,7 @@ Error FBXDocument::_parse_animations(Ref<FBXState> p_state) { for (const ufbx_baked_node &fbx_baked_node : fbx_baked_anim->nodes) { const GLTFNodeIndex node = fbx_baked_node.typed_id; - GLTFAnimation::Track &track = animation->get_tracks()[node]; + GLTFAnimation::NodeTrack &track = animation->get_node_tracks()[node]; for (const ufbx_baked_vec3 &key : fbx_baked_node.translation_keys) { track.position_track.times.push_back(float(key.time)); @@ -1779,8 +1783,8 @@ void FBXDocument::_import_animation(Ref<FBXState> p_state, AnimationPlayer *p_an double anim_start_offset = p_trimming ? double(additional_animation_data["time_begin"]) : 0.0; - for (const KeyValue<int, GLTFAnimation::Track> &track_i : anim->get_tracks()) { - const GLTFAnimation::Track &track = track_i.value; + for (const KeyValue<int, GLTFAnimation::NodeTrack> &track_i : anim->get_node_tracks()) { + const GLTFAnimation::NodeTrack &track = track_i.value; //need to find the path: for skeletons, weight tracks will affect the mesh NodePath node_path; //for skeletons, transform tracks always affect bones diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 93d4a512a9..6241ada06a 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -5809,8 +5809,6 @@ void GDScriptAnalyzer::validate_call_arg(const List<GDScriptParser::DataType> &p #ifdef DEBUG_ENABLED void GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_identifier, const String &p_context, const bool p_in_local_scope) { const StringName &name = p_identifier->name; - GDScriptParser::DataType base = parser->current_class->get_datatype(); - GDScriptParser::ClassNode *base_class = base.class_type; { List<MethodInfo> gdscript_funcs; @@ -5838,37 +5836,53 @@ void GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_identifier } } + const GDScriptParser::DataType current_class_type = parser->current_class->get_datatype(); if (p_in_local_scope) { - while (base_class != nullptr) { + GDScriptParser::ClassNode *base_class = current_class_type.class_type; + + if (base_class != nullptr) { if (base_class->has_member(name)) { parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE, p_context, p_identifier->name, base_class->get_member(name).get_type_name(), itos(base_class->get_member(name).get_line())); return; } base_class = base_class->base_type.class_type; } + + while (base_class != nullptr) { + if (base_class->has_member(name)) { + String base_class_name = base_class->get_global_name(); + if (base_class_name.is_empty()) { + base_class_name = base_class->fqcn; + } + + parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, base_class->get_member(name).get_type_name(), itos(base_class->get_member(name).get_line()), base_class_name); + return; + } + base_class = base_class->base_type.class_type; + } } - StringName parent = base.native_type; - while (parent != StringName()) { - ERR_FAIL_COND_MSG(!class_exists(parent), "Non-existent native base class."); + StringName native_base_class = current_class_type.native_type; + while (native_base_class != StringName()) { + ERR_FAIL_COND_MSG(!class_exists(native_base_class), "Non-existent native base class."); - if (ClassDB::has_method(parent, name, true)) { - parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "method", parent); + if (ClassDB::has_method(native_base_class, name, true)) { + parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "method", native_base_class); return; - } else if (ClassDB::has_signal(parent, name, true)) { - parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "signal", parent); + } else if (ClassDB::has_signal(native_base_class, name, true)) { + parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "signal", native_base_class); return; - } else if (ClassDB::has_property(parent, name, true)) { - parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "property", parent); + } else if (ClassDB::has_property(native_base_class, name, true)) { + parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "property", native_base_class); return; - } else if (ClassDB::has_integer_constant(parent, name, true)) { - parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "constant", parent); + } else if (ClassDB::has_integer_constant(native_base_class, name, true)) { + parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "constant", native_base_class); return; - } else if (ClassDB::has_enum(parent, name, true)) { - parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "enum", parent); + } else if (ClassDB::has_enum(native_base_class, name, true)) { + parser->push_warning(p_identifier, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_identifier->name, "enum", native_base_class); return; } - parent = ClassDB::get_parent_class(parent); + native_base_class = ClassDB::get_parent_class(native_base_class); } } #endif // DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index bc063693a3..d94a6dfda2 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -790,8 +790,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { text += method->get_name(); text += "("; for (int i = 0; i < argc; i++) { - if (i > 0) + if (i > 0) { text += ", "; + } text += DADDR(1 + i); } text += ")"; @@ -833,8 +834,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { text += method->get_name(); text += "("; for (int i = 0; i < argc; i++) { - if (i > 0) + if (i > 0) { text += ", "; + } text += DADDR(1 + i); } text += ")"; diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp index 4ffb4bd9d1..a601cc4993 100644 --- a/modules/gdscript/gdscript_warning.cpp +++ b/modules/gdscript/gdscript_warning.cpp @@ -61,10 +61,13 @@ String GDScriptWarning::get_message() const { return vformat(R"(The signal "%s" is declared but never explicitly used in the class.)", symbols[0]); case SHADOWED_VARIABLE: CHECK_SYMBOLS(4); - return vformat(R"(The local %s "%s" is shadowing an already-declared %s at line %s.)", symbols[0], symbols[1], symbols[2], symbols[3]); + return vformat(R"(The local %s "%s" is shadowing an already-declared %s at line %s in the current class.)", symbols[0], symbols[1], symbols[2], symbols[3]); case SHADOWED_VARIABLE_BASE_CLASS: CHECK_SYMBOLS(4); - return vformat(R"(The local %s "%s" is shadowing an already-declared %s at the base class "%s".)", symbols[0], symbols[1], symbols[2], symbols[3]); + if (symbols.size() > 4) { + return vformat(R"(The local %s "%s" is shadowing an already-declared %s at line %s in the base class "%s".)", symbols[0], symbols[1], symbols[2], symbols[3], symbols[4]); + } + return vformat(R"(The local %s "%s" is shadowing an already-declared %s in the base class "%s".)", symbols[0], symbols[1], symbols[2], symbols[3]); case SHADOWED_GLOBAL_IDENTIFIER: CHECK_SYMBOLS(3); return vformat(R"(The %s "%s" has the same name as a %s.)", symbols[0], symbols[1], symbols[2]); diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index ffcf00a830..99e9b30af5 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -53,8 +53,8 @@ public: UNUSED_PRIVATE_CLASS_VARIABLE, // Class variable is declared private ("_" prefix) but never used in the class. UNUSED_PARAMETER, // Function parameter is never used. UNUSED_SIGNAL, // Signal is defined but never explicitly used in the class. - SHADOWED_VARIABLE, // Variable name shadowed by other variable in same class. - SHADOWED_VARIABLE_BASE_CLASS, // Variable name shadowed by other variable in some base class. + SHADOWED_VARIABLE, // A local variable/constant shadows a current class member. + SHADOWED_VARIABLE_BASE_CLASS, // A local variable/constant shadows a base class member. SHADOWED_GLOBAL_IDENTIFIER, // A global class or function has the same name as variable. UNREACHABLE_CODE, // Code after a return statement. UNREACHABLE_PATTERN, // Pattern in a match statement after a catch all pattern (wildcard or bind). diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out index 0e0d607831..cfe91e00bd 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage.out @@ -6,6 +6,6 @@ GDTEST_OK >> WARNING >> Line: 5 >> SHADOWED_VARIABLE ->> The local variable "a" is shadowing an already-declared variable at line 1. +>> The local variable "a" is shadowing an already-declared variable at line 1 in the current class. 1 2 diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out index 228a510490..ae0f2d8b8b 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_initializer.out @@ -10,6 +10,6 @@ GDTEST_OK >> WARNING >> Line: 5 >> SHADOWED_VARIABLE ->> The local variable "a" is shadowing an already-declared variable at line 1. +>> The local variable "a" is shadowing an already-declared variable at line 1 in the current class. 1 2 diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out index 0d20e9f7a0..101d27df9d 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_local_usage_loop.out @@ -6,7 +6,7 @@ GDTEST_OK >> WARNING >> Line: 6 >> SHADOWED_VARIABLE ->> The local variable "a" is shadowing an already-declared variable at line 1. +>> The local variable "a" is shadowing an already-declared variable at line 1 in the current class. 1 2 1 diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/lambda_shadowing_arg.out b/modules/gdscript/tests/scripts/analyzer/warnings/lambda_shadowing_arg.out index a98d80514c..5d059b9193 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/lambda_shadowing_arg.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/lambda_shadowing_arg.out @@ -2,5 +2,5 @@ GDTEST_OK >> WARNING >> Line: 4 >> SHADOWED_VARIABLE ->> The local function parameter "shadow" is shadowing an already-declared variable at line 1. +>> The local function parameter "shadow" is shadowing an already-declared variable at line 1 in the current class. shadow diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/shadowing_base.notest.gd b/modules/gdscript/tests/scripts/analyzer/warnings/shadowing_base.notest.gd new file mode 100644 index 0000000000..5819246ded --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/shadowing_base.notest.gd @@ -0,0 +1,7 @@ +class_name ShadowingBase + +const base_const_member = 1 +var base_variable_member + +func base_function_member(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.gd b/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.gd index 939e787ea5..6a16ae6bcc 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.gd +++ b/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.gd @@ -1,4 +1,5 @@ class_name ShadowedClass +extends ShadowingBase var member: int = 0 @@ -7,6 +8,7 @@ var print_debug := 'print_debug' var print := 'print' @warning_ignore("unused_variable") +@warning_ignore("unused_local_constant") func test(): var Array := 'Array' var Node := 'Node' @@ -15,5 +17,8 @@ func test(): var member := 'member' var reference := 'reference' var ShadowedClass := 'ShadowedClass' + var base_variable_member + const base_function_member = 1 + var base_const_member print('warn') diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.out b/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.out index 8297eed4b8..075f5d3225 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/shadowning.out @@ -1,34 +1,46 @@ GDTEST_OK >> WARNING ->> Line: 5 +>> Line: 6 >> SHADOWED_GLOBAL_IDENTIFIER >> The variable "print_debug" has the same name as a built-in function. >> WARNING ->> Line: 11 +>> Line: 13 >> SHADOWED_GLOBAL_IDENTIFIER >> The variable "Array" has the same name as a built-in type. >> WARNING ->> Line: 12 +>> Line: 14 >> SHADOWED_GLOBAL_IDENTIFIER >> The variable "Node" has the same name as a native class. >> WARNING ->> Line: 13 +>> Line: 15 >> SHADOWED_GLOBAL_IDENTIFIER >> The variable "is_same" has the same name as a built-in function. >> WARNING ->> Line: 14 +>> Line: 16 >> SHADOWED_GLOBAL_IDENTIFIER >> The variable "sqrt" has the same name as a built-in function. >> WARNING ->> Line: 15 +>> Line: 17 >> SHADOWED_VARIABLE ->> The local variable "member" is shadowing an already-declared variable at line 3. +>> The local variable "member" is shadowing an already-declared variable at line 4 in the current class. >> WARNING ->> Line: 16 +>> Line: 18 >> SHADOWED_VARIABLE_BASE_CLASS ->> The local variable "reference" is shadowing an already-declared method at the base class "RefCounted". +>> The local variable "reference" is shadowing an already-declared method in the base class "RefCounted". >> WARNING ->> Line: 17 +>> Line: 19 >> SHADOWED_GLOBAL_IDENTIFIER >> The variable "ShadowedClass" has the same name as a global class defined in "shadowning.gd". +>> WARNING +>> Line: 20 +>> SHADOWED_VARIABLE_BASE_CLASS +>> The local variable "base_variable_member" is shadowing an already-declared variable at line 4 in the base class "ShadowingBase". +>> WARNING +>> Line: 21 +>> SHADOWED_VARIABLE_BASE_CLASS +>> The local constant "base_function_member" is shadowing an already-declared function at line 6 in the base class "ShadowingBase". +>> WARNING +>> Line: 22 +>> SHADOWED_VARIABLE_BASE_CLASS +>> The local variable "base_const_member" is shadowing an already-declared constant at line 3 in the base class "ShadowingBase". warn diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_constant.out b/modules/gdscript/tests/scripts/parser/warnings/shadowed_constant.out index 75fa01f928..04df229f66 100644 --- a/modules/gdscript/tests/scripts/parser/warnings/shadowed_constant.out +++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_constant.out @@ -6,4 +6,4 @@ GDTEST_OK >> WARNING >> Line: 8 >> SHADOWED_VARIABLE ->> The local constant "TEST" is shadowing an already-declared constant at line 2. +>> The local constant "TEST" is shadowing an already-declared constant at line 2 in the current class. diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_class.out b/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_class.out index aab27e78e2..4a6964f503 100644 --- a/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_class.out +++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_class.out @@ -6,4 +6,4 @@ GDTEST_OK >> WARNING >> Line: 8 >> SHADOWED_VARIABLE ->> The local variable "foo" is shadowing an already-declared variable at line 1. +>> The local variable "foo" is shadowing an already-declared variable at line 1 in the current class. diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_function.out b/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_function.out index e3cd358126..45fb771829 100644 --- a/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_function.out +++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_variable_function.out @@ -6,4 +6,4 @@ GDTEST_OK >> WARNING >> Line: 2 >> SHADOWED_VARIABLE ->> The local variable "test" is shadowing an already-declared function at line 1. +>> The local variable "test" is shadowing an already-declared function at line 1 in the current class. diff --git a/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out b/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out index 5492c8f763..1650acadb5 100644 --- a/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out +++ b/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out @@ -2,11 +2,11 @@ GDTEST_OK >> WARNING >> Line: 5 >> SHADOWED_VARIABLE ->> The local function parameter "a" is shadowing an already-declared variable at line 3. +>> The local function parameter "a" is shadowing an already-declared variable at line 3 in the current class. >> WARNING >> Line: 15 >> SHADOWED_VARIABLE ->> The local function parameter "v" is shadowing an already-declared variable at line 13. +>> The local function parameter "v" is shadowing an already-declared variable at line 13 in the current class. a 1 b diff --git a/modules/gltf/config.py b/modules/gltf/config.py index 67233db579..823b8dbec2 100644 --- a/modules/gltf/config.py +++ b/modules/gltf/config.py @@ -20,6 +20,7 @@ def get_doc_classes(): "GLTFLight", "GLTFMesh", "GLTFNode", + "GLTFObjectModelProperty", "GLTFPhysicsBody", "GLTFPhysicsShape", "GLTFSkeleton", diff --git a/modules/gltf/doc_classes/GLTFAccessor.xml b/modules/gltf/doc_classes/GLTFAccessor.xml index bc142797a3..04fa2a9835 100644 --- a/modules/gltf/doc_classes/GLTFAccessor.xml +++ b/modules/gltf/doc_classes/GLTFAccessor.xml @@ -22,7 +22,7 @@ The offset relative to the start of the buffer view in bytes. </member> <member name="component_type" type="int" setter="set_component_type" getter="get_component_type" default="0"> - The glTF component type as an enum. Possible values are 5120 for "BYTE", 5121 for "UNSIGNED_BYTE", 5122 for "SHORT", 5123 for "UNSIGNED_SHORT", 5125 for "UNSIGNED_INT", and 5126 for "FLOAT". A value of 5125 or "UNSIGNED_INT" must not be used for any accessor that is not referenced by mesh.primitive.indices. + The glTF component type as an enum. See [enum GLTFComponentType] for possible values. Within the core glTF specification, a value of 5125 or "UNSIGNED_INT" must not be used for any accessor that is not referenced by mesh.primitive.indices. </member> <member name="count" type="int" setter="set_count" getter="get_count" default="0"> The number of elements referenced by this accessor. @@ -80,5 +80,41 @@ <constant name="TYPE_MAT4" value="6" enum="GLTFAccessorType"> Accessor type "MAT4". For the glTF object model, this maps to "float4x4", represented in the glTF JSON as an array of sixteen floats. </constant> + <constant name="COMPONENT_TYPE_NONE" value="0" enum="GLTFComponentType"> + Component type "NONE". This is not a valid component type, and is used to indicate that the component type is not set. + </constant> + <constant name="COMPONENT_TYPE_SIGNED_BYTE" value="5120" enum="GLTFComponentType"> + Component type "BYTE". The value is [code]0x1400[/code] which comes from OpenGL. This indicates data is stored in 1-byte or 8-bit signed integers. This is a core part of the glTF specification. + </constant> + <constant name="COMPONENT_TYPE_UNSIGNED_BYTE" value="5121" enum="GLTFComponentType"> + Component type "UNSIGNED_BYTE". The value is [code]0x1401[/code] which comes from OpenGL. This indicates data is stored in 1-byte or 8-bit unsigned integers. This is a core part of the glTF specification. + </constant> + <constant name="COMPONENT_TYPE_SIGNED_SHORT" value="5122" enum="GLTFComponentType"> + Component type "SHORT". The value is [code]0x1402[/code] which comes from OpenGL. This indicates data is stored in 2-byte or 16-bit signed integers. This is a core part of the glTF specification. + </constant> + <constant name="COMPONENT_TYPE_UNSIGNED_SHORT" value="5123" enum="GLTFComponentType"> + Component type "UNSIGNED_SHORT". The value is [code]0x1403[/code] which comes from OpenGL. This indicates data is stored in 2-byte or 16-bit unsigned integers. This is a core part of the glTF specification. + </constant> + <constant name="COMPONENT_TYPE_SIGNED_INT" value="5124" enum="GLTFComponentType"> + Component type "INT". The value is [code]0x1404[/code] which comes from OpenGL. This indicates data is stored in 4-byte or 32-bit signed integers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + </constant> + <constant name="COMPONENT_TYPE_UNSIGNED_INT" value="5125" enum="GLTFComponentType"> + Component type "UNSIGNED_INT". The value is [code]0x1405[/code] which comes from OpenGL. This indicates data is stored in 4-byte or 32-bit unsigned integers. This is a core part of the glTF specification. + </constant> + <constant name="COMPONENT_TYPE_SINGLE_FLOAT" value="5126" enum="GLTFComponentType"> + Component type "FLOAT". The value is [code]0x1406[/code] which comes from OpenGL. This indicates data is stored in 4-byte or 32-bit floating point numbers. This is a core part of the glTF specification. + </constant> + <constant name="COMPONENT_TYPE_DOUBLE_FLOAT" value="5130" enum="GLTFComponentType"> + Component type "DOUBLE". The value is [code]0x140A[/code] which comes from OpenGL. This indicates data is stored in 8-byte or 64-bit floating point numbers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + </constant> + <constant name="COMPONENT_TYPE_HALF_FLOAT" value="5131" enum="GLTFComponentType"> + Component type "HALF_FLOAT". The value is [code]0x140B[/code] which comes from OpenGL. This indicates data is stored in 2-byte or 16-bit floating point numbers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + </constant> + <constant name="COMPONENT_TYPE_SIGNED_LONG" value="5134" enum="GLTFComponentType"> + Component type "LONG". The value is [code]0x140E[/code] which comes from OpenGL. This indicates data is stored in 8-byte or 64-bit signed integers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + </constant> + <constant name="COMPONENT_TYPE_UNSIGNED_LONG" value="5135" enum="GLTFComponentType"> + Component type "UNSIGNED_LONG". The value is [code]0x140F[/code] which comes from OpenGL. This indicates data is stored in 8-byte or 64-bit unsigned integers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + </constant> </constants> </class> diff --git a/modules/gltf/doc_classes/GLTFAnimation.xml b/modules/gltf/doc_classes/GLTFAnimation.xml index d269145bbd..f11dea8ee8 100644 --- a/modules/gltf/doc_classes/GLTFAnimation.xml +++ b/modules/gltf/doc_classes/GLTFAnimation.xml @@ -13,7 +13,7 @@ <param index="0" name="extension_name" type="StringName" /> <description> Gets additional arbitrary data in this [GLTFAnimation] instance. This can be used to keep per-node state data in [GLTFDocumentExtension] classes, which is important because they are stateless. - The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is null. + The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is [code]null[/code]. </description> </method> <method name="set_additional_data"> diff --git a/modules/gltf/doc_classes/GLTFBufferView.xml b/modules/gltf/doc_classes/GLTFBufferView.xml index b7f499ad72..9c2ee3197f 100644 --- a/modules/gltf/doc_classes/GLTFBufferView.xml +++ b/modules/gltf/doc_classes/GLTFBufferView.xml @@ -34,10 +34,10 @@ The stride, in bytes, between interleaved data. If [code]-1[/code], this buffer view is not interleaved. </member> <member name="indices" type="bool" setter="set_indices" getter="get_indices" default="false"> - True if the GLTFBufferView's OpenGL GPU buffer type is an [code]ELEMENT_ARRAY_BUFFER[/code] used for vertex indices (integer constant [code]34963[/code]). False if the buffer type is any other value. See [url=https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md]Buffers, BufferViews, and Accessors[/url] for possible values. This property is set on import and used on export. + [code]true[/code] if the GLTFBufferView's OpenGL GPU buffer type is an [code]ELEMENT_ARRAY_BUFFER[/code] used for vertex indices (integer constant [code]34963[/code]). [code]false[/code] if the buffer type is any other value. See [url=https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md]Buffers, BufferViews, and Accessors[/url] for possible values. This property is set on import and used on export. </member> <member name="vertex_attributes" type="bool" setter="set_vertex_attributes" getter="get_vertex_attributes" default="false"> - True if the GLTFBufferView's OpenGL GPU buffer type is an [code]ARRAY_BUFFER[/code] used for vertex attributes (integer constant [code]34962[/code]). False if the buffer type is any other value. See [url=https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md]Buffers, BufferViews, and Accessors[/url] for possible values. This property is set on import and used on export. + [code]true[/code] if the GLTFBufferView's OpenGL GPU buffer type is an [code]ARRAY_BUFFER[/code] used for vertex attributes (integer constant [code]34962[/code]). [code]false[/code] if the buffer type is any other value. See [url=https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md]Buffers, BufferViews, and Accessors[/url] for possible values. This property is set on import and used on export. </member> </members> </class> diff --git a/modules/gltf/doc_classes/GLTFCamera.xml b/modules/gltf/doc_classes/GLTFCamera.xml index 9fce21659c..12334683ba 100644 --- a/modules/gltf/doc_classes/GLTFCamera.xml +++ b/modules/gltf/doc_classes/GLTFCamera.xml @@ -47,13 +47,13 @@ The distance to the near culling boundary for this camera relative to its local Z axis, in meters. This maps to glTF's [code]znear[/code] property. </member> <member name="fov" type="float" setter="set_fov" getter="get_fov" default="1.309"> - The FOV of the camera. This class and glTF define the camera FOV in radians, while Godot uses degrees. This maps to glTF's [code]yfov[/code] property. This value is only used for perspective cameras, when [member perspective] is true. + The FOV of the camera. This class and glTF define the camera FOV in radians, while Godot uses degrees. This maps to glTF's [code]yfov[/code] property. This value is only used for perspective cameras, when [member perspective] is [code]true[/code]. </member> <member name="perspective" type="bool" setter="set_perspective" getter="get_perspective" default="true"> - Whether or not the camera is in perspective mode. If false, the camera is in orthographic/orthogonal mode. This maps to glTF's camera [code]type[/code] property. See [member Camera3D.projection] and the glTF spec for more information. + If [code]true[/code], the camera is in perspective mode. Otherwise, the camera is in orthographic/orthogonal mode. This maps to glTF's camera [code]type[/code] property. See [member Camera3D.projection] and the glTF spec for more information. </member> <member name="size_mag" type="float" setter="set_size_mag" getter="get_size_mag" default="0.5"> - The size of the camera. This class and glTF define the camera size magnitude as a radius in meters, while Godot defines it as a diameter in meters. This maps to glTF's [code]ymag[/code] property. This value is only used for orthographic/orthogonal cameras, when [member perspective] is false. + The size of the camera. This class and glTF define the camera size magnitude as a radius in meters, while Godot defines it as a diameter in meters. This maps to glTF's [code]ymag[/code] property. This value is only used for orthographic/orthogonal cameras, when [member perspective] is [code]false[/code]. </member> </members> </class> diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index 10534594d3..47ffc624ba 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -45,6 +45,16 @@ Takes a Godot Engine scene node and exports it and its descendants to the given [GLTFState] object through the [param state] parameter. </description> </method> + <method name="export_object_model_property" qualifiers="static"> + <return type="GLTFObjectModelProperty" /> + <param index="0" name="state" type="GLTFState" /> + <param index="1" name="node_path" type="NodePath" /> + <param index="2" name="godot_node" type="Node" /> + <param index="3" name="gltf_node_index" type="int" /> + <description> + Determines a mapping between the given Godot [param node_path] and the corresponding glTF Object Model JSON pointer(s) in the generated glTF file. The details of this mapping are returned in a [GLTFObjectModelProperty] object. Additional mappings can be supplied via the [method GLTFDocumentExtension._import_object_model_property] callback method. + </description> + </method> <method name="generate_buffer"> <return type="PackedByteArray" /> <param index="0" name="state" type="GLTFState" /> @@ -70,12 +80,20 @@ [b]Note:[/b] If this method is run before a GLTFDocumentExtension is registered, its extensions won't be included in the list. Be sure to only run this method after all extensions are registered. If you run this when the engine starts, consider waiting a frame before calling this method to ensure all extensions are registered. </description> </method> + <method name="import_object_model_property" qualifiers="static"> + <return type="GLTFObjectModelProperty" /> + <param index="0" name="state" type="GLTFState" /> + <param index="1" name="json_pointer" type="String" /> + <description> + Determines a mapping between the given glTF Object Model [param json_pointer] and the corresponding Godot node path(s) in the generated Godot scene. The details of this mapping are returned in a [GLTFObjectModelProperty] object. Additional mappings can be supplied via the [method GLTFDocumentExtension._export_object_model_property] callback method. + </description> + </method> <method name="register_gltf_document_extension" qualifiers="static"> <return type="void" /> <param index="0" name="extension" type="GLTFDocumentExtension" /> <param index="1" name="first_priority" type="bool" default="false" /> <description> - Registers the given [GLTFDocumentExtension] instance with GLTFDocument. If [param first_priority] is true, this extension will be run first. Otherwise, it will be run last. + Registers the given [GLTFDocumentExtension] instance with GLTFDocument. If [param first_priority] is [code]true[/code], this extension will be run first. Otherwise, it will be run last. [b]Note:[/b] Like GLTFDocument itself, all GLTFDocumentExtension classes must be stateless in order to function properly. If you need to store data, use the [code]set_additional_data[/code] and [code]get_additional_data[/code] methods in [GLTFState] or [GLTFNode]. </description> </method> diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml index b33e296e1c..abdbce7eeb 100644 --- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml +++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml @@ -30,7 +30,21 @@ <param index="3" name="node" type="Node" /> <description> Part of the export process. This method is run after [method _get_saveable_image_formats] and before [method _export_post]. If this [GLTFDocumentExtension] is used for exporting images, this runs after [method _serialize_texture_json]. - This method can be used to modify the final JSON of each node. Data should be primarily stored in [param gltf_node] prior to serializing the JSON, but the original Godot [param node] is also provided if available. The node may be null if not available, such as when exporting glTF data not generated from a Godot scene. + This method can be used to modify the final JSON of each node. Data should be primarily stored in [param gltf_node] prior to serializing the JSON, but the original Godot [Node] is also provided if available. [param node] may be [code]null[/code] if not available, such as when exporting glTF data not generated from a Godot scene. + </description> + </method> + <method name="_export_object_model_property" qualifiers="virtual"> + <return type="GLTFObjectModelProperty" /> + <param index="0" name="state" type="GLTFState" /> + <param index="1" name="node_path" type="NodePath" /> + <param index="2" name="godot_node" type="Node" /> + <param index="3" name="gltf_node_index" type="int" /> + <param index="4" name="target_object" type="Object" /> + <param index="5" name="target_depth" type="int" /> + <description> + Part of the export process. Allows GLTFDocumentExtension classes to provide mappings for properties of nodes in the Godot scene tree, to JSON pointers to glTF properties, as defined by the glTF object model. + Returns a [GLTFObjectModelProperty] instance that defines how the property should be mapped. If your extension can't handle the property, return [code]null[/code] or an instance without any JSON pointers (see [method GLTFObjectModelProperty.has_json_pointers]). You should use [method GLTFObjectModelProperty.set_types] to set the types, and set the JSON pointer(s) using the [member GLTFObjectModelProperty.json_pointers] property. + The parameters provide context for the property, including the NodePath, the Godot node, the GLTF node index, and the target object. The [param target_object] will be equal to [param godot_node] if no sub-object can be found, otherwise it will point to a sub-object. For example, if the path is [code]^"A/B/C/MeshInstance3D:mesh:surface_0/material:emission_intensity"[/code], it will get the node, then the mesh, and then the material, so [param target_object] will be the [Material] resource, and [param target_depth] will be 2 because 2 levels were traversed to get to the target. </description> </method> <method name="_export_post" qualifiers="virtual"> @@ -75,7 +89,7 @@ <description> Part of the import process. This method is run after [method _import_pre_generate] and before [method _import_node]. Runs when generating a Godot scene node from a GLTFNode. The returned node will be added to the scene tree. Multiple nodes can be generated in this step if they are added as a child of the returned node. - [b]Note:[/b] The [param scene_parent] parameter may be null if this is the single root node. + [b]Note:[/b] The [param scene_parent] parameter may be [code]null[/code] if this is the single root node. </description> </method> <method name="_get_image_file_extension" qualifiers="virtual"> @@ -109,6 +123,17 @@ This method can be used to make modifications to each of the generated Godot scene nodes. </description> </method> + <method name="_import_object_model_property" qualifiers="virtual"> + <return type="GLTFObjectModelProperty" /> + <param index="0" name="state" type="GLTFState" /> + <param index="1" name="split_json_pointer" type="PackedStringArray" /> + <param index="2" name="partial_paths" type="NodePath[]" /> + <description> + Part of the import process. Allows GLTFDocumentExtension classes to provide mappings for JSON pointers to glTF properties, as defined by the glTF object model, to properties of nodes in the Godot scene tree. + Returns a [GLTFObjectModelProperty] instance that defines how the property should be mapped. If your extension can't handle the property, return [code]null[/code] or an instance without any NodePaths (see [method GLTFObjectModelProperty.has_node_paths]). You should use [method GLTFObjectModelProperty.set_types] to set the types, and [method GLTFObjectModelProperty.append_path_to_property] function is useful for most simple cases. + In many cases, [param partial_paths] will contain the start of a path, allowing the extension to complete the path. For example, for [code]/nodes/3/extensions/MY_ext/prop[/code], Godot will pass you a NodePath that leads to node 3, so the GLTFDocumentExtension class only needs to resolve the last [code]MY_ext/prop[/code] part of the path. In this example, the extension should check [code]split.size() > 4 and split[0] == "nodes" and split[2] == "extensions" and split[3] == "MY_ext"[/code] at the start of the function to check if this JSON pointer applies to it, then it can use [param partial_paths] and handle [code]split[4][/code]. + </description> + </method> <method name="_import_post" qualifiers="virtual"> <return type="int" enum="Error" /> <param index="0" name="state" type="GLTFState" /> diff --git a/modules/gltf/doc_classes/GLTFMesh.xml b/modules/gltf/doc_classes/GLTFMesh.xml index da73c20c1d..439078ffcc 100644 --- a/modules/gltf/doc_classes/GLTFMesh.xml +++ b/modules/gltf/doc_classes/GLTFMesh.xml @@ -15,7 +15,7 @@ <param index="0" name="extension_name" type="StringName" /> <description> Gets additional arbitrary data in this [GLTFMesh] instance. This can be used to keep per-node state data in [GLTFDocumentExtension] classes, which is important because they are stateless. - The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is null. + The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is [code]null[/code]. </description> </method> <method name="set_additional_data"> diff --git a/modules/gltf/doc_classes/GLTFNode.xml b/modules/gltf/doc_classes/GLTFNode.xml index a242a0d1d8..0fb85e4029 100644 --- a/modules/gltf/doc_classes/GLTFNode.xml +++ b/modules/gltf/doc_classes/GLTFNode.xml @@ -24,7 +24,16 @@ <param index="0" name="extension_name" type="StringName" /> <description> Gets additional arbitrary data in this [GLTFNode] instance. This can be used to keep per-node state data in [GLTFDocumentExtension] classes, which is important because they are stateless. - The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is null. + The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is [code]null[/code]. + </description> + </method> + <method name="get_scene_node_path"> + <return type="NodePath" /> + <param index="0" name="gltf_state" type="GLTFState" /> + <param index="1" name="handle_skeletons" type="bool" default="true" /> + <description> + Returns the [NodePath] that this GLTF node will have in the Godot scene tree after being imported. This is useful when importing glTF object model pointers with [GLTFObjectModelProperty], for handling extensions such as [code]KHR_animation_pointer[/code] or [code]KHR_interactivity[/code]. + If [param handle_skeletons] is [code]true[/code], paths to skeleton bone glTF nodes will be resolved properly. For example, a path that would be [code]^"A/B/C/Bone1/Bone2/Bone3"[/code] if [code]false[/code] will become [code]^"A/B/C/Skeleton3D:Bone3"[/code]. </description> </method> <method name="set_additional_data"> diff --git a/modules/gltf/doc_classes/GLTFObjectModelProperty.xml b/modules/gltf/doc_classes/GLTFObjectModelProperty.xml new file mode 100644 index 0000000000..a457d94c41 --- /dev/null +++ b/modules/gltf/doc_classes/GLTFObjectModelProperty.xml @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="GLTFObjectModelProperty" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> + <brief_description> + Describes how to access a property as defined in the glTF object model. + </brief_description> + <description> + GLTFObjectModelProperty defines a mapping between a property in the glTF object model and a NodePath in the Godot scene tree. This can be used to animate properties in a glTF file using the [code]KHR_animation_pointer[/code] extension, or to access them through an engine-agnostic script such as a behavior graph as defined by the [code]KHR_interactivity[/code] extension. + The glTF property is identified by JSON pointer(s) stored in [member json_pointers], while the Godot property it maps to is defined by [member node_paths]. In most cases [member json_pointers] and [member node_paths] will each only have one item, but in some cases a single glTF JSON pointer will map to multiple Godot properties, or a single Godot property will be mapped to multiple glTF JSON pointers, or it might be a many-to-many relationship. + [Expression] objects can be used to define conversions between the data, such as when glTF defines an angle in radians and Godot uses degrees. The [member object_model_type] property defines the type of data stored in the glTF file as defined by the object model, see [enum GLTFObjectModelType] for possible values. + </description> + <tutorials> + <link title="GLTF Object Model">https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc</link> + <link title="KHR_animation_pointer GLTF extension">https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_animation_pointer</link> + </tutorials> + <methods> + <method name="append_node_path"> + <return type="void" /> + <param index="0" name="node_path" type="NodePath" /> + <description> + Appends a [NodePath] to [member node_paths]. This can be used by [GLTFDocumentExtension] classes to define how a glTF object model property maps to a Godot property, or multiple Godot properties. Prefer using [method append_path_to_property] for simple cases. Be sure to also call [method set_types] once (the order does not matter). + </description> + </method> + <method name="append_path_to_property"> + <return type="void" /> + <param index="0" name="node_path" type="NodePath" /> + <param index="1" name="prop_name" type="StringName" /> + <description> + High-level wrapper over [method append_node_path] that handles the most common cases. It constructs a new [NodePath] using [param node_path] as a base and appends [param prop_name] to the subpath. Be sure to also call [method set_types] once (the order does not matter). + </description> + </method> + <method name="get_accessor_type" qualifiers="const"> + <return type="int" enum="GLTFAccessor.GLTFAccessorType" /> + <description> + The GLTF accessor type associated with this property's [member object_model_type]. See [member GLTFAccessor.accessor_type] for possible values, and see [enum GLTFObjectModelType] for how the object model type maps to accessor types. + </description> + </method> + <method name="has_json_pointers" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if [member json_pointers] is not empty. This is used during export to determine if a [GLTFObjectModelProperty] can handle converting a Godot property to a glTF object model property. + </description> + </method> + <method name="has_node_paths" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if [member node_paths] is not empty. This is used during import to determine if a [GLTFObjectModelProperty] can handle converting a glTF object model property to a Godot property. + </description> + </method> + <method name="set_types"> + <return type="void" /> + <param index="0" name="variant_type" type="int" enum="Variant.Type" /> + <param index="1" name="obj_model_type" type="int" enum="GLTFObjectModelProperty.GLTFObjectModelType" /> + <description> + Sets the [member variant_type] and [member object_model_type] properties. This is a convenience method to set both properties at once, since they are almost always known at the same time. This method should be called once. Calling it again with the same values will have no effect. + </description> + </method> + </methods> + <members> + <member name="gltf_to_godot_expression" type="Expression" setter="set_gltf_to_godot_expression" getter="get_gltf_to_godot_expression"> + If set, this [Expression] will be used to convert the property value from the glTF object model to the value expected by the Godot property. This is useful when the glTF object model uses a different unit system, or when the data needs to be transformed in some way. If [code]null[/code], the value will be copied as-is. + </member> + <member name="godot_to_gltf_expression" type="Expression" setter="set_godot_to_gltf_expression" getter="get_godot_to_gltf_expression"> + If set, this [Expression] will be used to convert the property value from the Godot property to the value expected by the glTF object model. This is useful when the glTF object model uses a different unit system, or when the data needs to be transformed in some way. If [code]null[/code], the value will be copied as-is. + </member> + <member name="json_pointers" type="PackedStringArray[]" setter="set_json_pointers" getter="get_json_pointers" default="[]"> + The glTF object model JSON pointers used to identify the property in the glTF object model. In most cases, there will be only one item in this array, but niche cases may require multiple pointers. The items are themselves arrays which represent the JSON pointer split into its components. + </member> + <member name="node_paths" type="NodePath[]" setter="set_node_paths" getter="get_node_paths" default="[]"> + An array of [NodePath]s that point to a property, or multiple properties, in the Godot scene tree. On import, this will either be set by [GLTFDocument], or by a [GLTFDocumentExtension] class. For simple cases, use [method append_path_to_property] to add properties to this array. + In most cases [member node_paths] will only have one item, but in some cases a single glTF JSON pointer will map to multiple Godot properties. For example, a [GLTFCamera] or [GLTFLight] used on multiple glTF nodes will be represented by multiple Godot nodes. + </member> + <member name="object_model_type" type="int" setter="set_object_model_type" getter="get_object_model_type" enum="GLTFObjectModelProperty.GLTFObjectModelType" default="0"> + The type of data stored in the glTF file as defined by the object model. This is a superset of the available accessor types, and determines the accessor type. See [enum GLTFObjectModelType] for possible values. + </member> + <member name="variant_type" type="int" setter="set_variant_type" getter="get_variant_type" enum="Variant.Type" default="0"> + The type of data stored in the Godot property. This is the type of the property that the [member node_paths] point to. + </member> + </members> + <constants> + <constant name="GLTF_OBJECT_MODEL_TYPE_UNKNOWN" value="0" enum="GLTFObjectModelType"> + Unknown or not set object model type. If the object model type is set to this value, the real type still needs to be determined. + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_BOOL" value="1" enum="GLTFObjectModelType"> + Object model type "bool". Represented in the glTF JSON as a boolean, and encoded in a [GLTFAccessor] as "SCALAR". When encoded in an accessor, a value of [code]0[/code] is [code]false[/code], and any other value is [code]true[/code]. + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT" value="2" enum="GLTFObjectModelType"> + Object model type "float". Represented in the glTF JSON as a number, and encoded in a [GLTFAccessor] as "SCALAR". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT_ARRAY" value="3" enum="GLTFObjectModelType"> + Object model type "float[lb][rb]". Represented in the glTF JSON as an array of numbers, and encoded in a [GLTFAccessor] as "SCALAR". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT2" value="4" enum="GLTFObjectModelType"> + Object model type "float2". Represented in the glTF JSON as an array of two numbers, and encoded in a [GLTFAccessor] as "VEC2". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT3" value="5" enum="GLTFObjectModelType"> + Object model type "float3". Represented in the glTF JSON as an array of three numbers, and encoded in a [GLTFAccessor] as "VEC3". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT4" value="6" enum="GLTFObjectModelType"> + Object model type "float4". Represented in the glTF JSON as an array of four numbers, and encoded in a [GLTFAccessor] as "VEC4". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT2X2" value="7" enum="GLTFObjectModelType"> + Object model type "float2x2". Represented in the glTF JSON as an array of four numbers, and encoded in a [GLTFAccessor] as "MAT2". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT3X3" value="8" enum="GLTFObjectModelType"> + Object model type "float3x3". Represented in the glTF JSON as an array of nine numbers, and encoded in a [GLTFAccessor] as "MAT3". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_FLOAT4X4" value="9" enum="GLTFObjectModelType"> + Object model type "float4x4". Represented in the glTF JSON as an array of sixteen numbers, and encoded in a [GLTFAccessor] as "MAT4". + </constant> + <constant name="GLTF_OBJECT_MODEL_TYPE_INT" value="10" enum="GLTFObjectModelType"> + Object model type "int". Represented in the glTF JSON as a number, and encoded in a [GLTFAccessor] as "SCALAR". The range of values is limited to signed integers. For [code]KHR_interactivity[/code], only 32-bit integers are supported. + </constant> + </constants> +</class> diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index de7ec2a4ca..376c3c89f5 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -17,7 +17,7 @@ <param index="0" name="extension_name" type="String" /> <param index="1" name="required" type="bool" /> <description> - Appends an extension to the list of extensions used by this glTF file during serialization. If [param required] is true, the extension will also be added to the list of required extensions. Do not run this in [method GLTFDocumentExtension._export_post], as that stage is too late to add extensions. The final list is sorted alphabetically. + Appends an extension to the list of extensions used by this glTF file during serialization. If [param required] is [code]true[/code], the extension will also be added to the list of required extensions. Do not run this in [method GLTFDocumentExtension._export_post], as that stage is too late to add extensions. The final list is sorted alphabetically. </description> </method> <method name="append_data_to_buffers"> @@ -25,7 +25,7 @@ <param index="0" name="data" type="PackedByteArray" /> <param index="1" name="deduplication" type="bool" /> <description> - Appends the given byte array data to the buffers and creates a [GLTFBufferView] for it. The index of the destination [GLTFBufferView] is returned. If [param deduplication] is true, the buffers will first be searched for duplicate data, otherwise new bytes will always be appended. + Appends the given byte array data to the buffers and creates a [GLTFBufferView] for it. The index of the destination [GLTFBufferView] is returned. If [param deduplication] is [code]true[/code], the buffers will first be searched for duplicate data, otherwise new bytes will always be appended. </description> </method> <method name="append_gltf_node"> @@ -35,7 +35,7 @@ <param index="2" name="parent_node_index" type="int" /> <description> Append the given [GLTFNode] to the state, and return its new index. This can be used to export one Godot node as multiple glTF nodes, or inject new glTF nodes at import time. On import, this must be called before [method GLTFDocumentExtension._generate_scene_node] finishes for the parent node. On export, this must be called before [method GLTFDocumentExtension._export_node] runs for the parent node. - The [param godot_scene_node] parameter is the Godot scene node that corresponds to this glTF node. This is highly recommended to be set to a valid node, but may be null if there is no corresponding Godot scene node. One Godot scene node may be used for multiple glTF nodes, so if exporting multiple glTF nodes for one Godot scene node, use the same Godot scene node for each. + The [param godot_scene_node] parameter is the Godot scene node that corresponds to this glTF node. This is highly recommended to be set to a valid node, but may be [code]null[/code] if there is no corresponding Godot scene node. One Godot scene node may be used for multiple glTF nodes, so if exporting multiple glTF nodes for one Godot scene node, use the same Godot scene node for each. The [param parent_node_index] parameter is the index of the parent [GLTFNode] in the state. If [code]-1[/code], the node will be a root node, otherwise the new node will be added to the parent's list of children. The index will also be written to the [member GLTFNode.parent] property of the new node. </description> </method> @@ -49,7 +49,7 @@ <param index="0" name="extension_name" type="StringName" /> <description> Gets additional arbitrary data in this [GLTFState] instance. This can be used to keep per-file state data in [GLTFDocumentExtension] classes, which is important because they are stateless. - The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is null. + The argument should be the [GLTFDocumentExtension] name (does not have to match the extension name in the glTF file), and the return value can be anything you set. If nothing was set, the return value is [code]null[/code]. </description> </method> <method name="get_animation_player"> diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp index 022d2e4477..872054ec2e 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp @@ -88,7 +88,7 @@ void SceneExporterGLTFPlugin::_popup_gltf_export_dialog() { } _file_dialog->set_current_file(filename + String(".gltf")); // Generate and refresh the export settings. - _export_settings->generate_property_list(_gltf_document); + _export_settings->generate_property_list(_gltf_document, root); _settings_inspector->edit(nullptr); _settings_inspector->edit(_export_settings.ptr()); // Show the file dialog. diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp index 511da078d8..c14e92c3a0 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp +++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp @@ -129,7 +129,7 @@ String get_friendly_config_prefix(Ref<GLTFDocumentExtension> p_extension) { } // Run this before popping up the export settings, because the extensions may have changed. -void EditorSceneExporterGLTFSettings::generate_property_list(Ref<GLTFDocument> p_document) { +void EditorSceneExporterGLTFSettings::generate_property_list(Ref<GLTFDocument> p_document, Node *p_root) { _property_list.clear(); _document = p_document; String image_format_hint_string = "None,PNG,JPEG"; diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.h b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h index 898cddfd68..aa0e54078d 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_settings.h +++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h @@ -55,7 +55,7 @@ protected: bool _get_extension_setting(const String &p_name_str, Variant &r_ret) const; public: - void generate_property_list(Ref<GLTFDocument> p_document); + void generate_property_list(Ref<GLTFDocument> p_document, Node *p_root = nullptr); String get_copyright() const; void set_copyright(const String &p_copyright); diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index 542e00e560..2db46adef4 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -319,6 +319,8 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_ state->set_import_as_skeleton_bones(true); } state->set_scene_name(blend_basename); + state->set_extract_path(p_path.get_base_dir()); + state->set_extract_prefix(blend_basename); err = gltf->append_from_file(sink.get_basename() + ".gltf", state, p_flags, base_dir); if (err != OK) { if (r_err) { diff --git a/modules/gltf/extensions/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp index 6e611762b6..0806eee6bf 100644 --- a/modules/gltf/extensions/gltf_document_extension.cpp +++ b/modules/gltf/extensions/gltf_document_extension.cpp @@ -38,6 +38,7 @@ void GLTFDocumentExtension::_bind_methods() { GDVIRTUAL_BIND(_parse_image_data, "state", "image_data", "mime_type", "ret_image"); GDVIRTUAL_BIND(_get_image_file_extension); GDVIRTUAL_BIND(_parse_texture_json, "state", "texture_json", "ret_gltf_texture"); + GDVIRTUAL_BIND(_import_object_model_property, "state", "split_json_pointer", "partial_paths"); GDVIRTUAL_BIND(_import_post_parse, "state"); GDVIRTUAL_BIND(_import_pre_generate, "state"); GDVIRTUAL_BIND(_generate_scene_node, "state", "gltf_node", "scene_parent"); @@ -48,6 +49,7 @@ void GLTFDocumentExtension::_bind_methods() { GDVIRTUAL_BIND(_convert_scene_node, "state", "gltf_node", "scene_node"); GDVIRTUAL_BIND(_export_post_convert, "state", "root"); GDVIRTUAL_BIND(_export_preserialize, "state"); + GDVIRTUAL_BIND(_export_object_model_property, "state", "node_path", "godot_node", "gltf_node_index", "target_object", "target_depth"); GDVIRTUAL_BIND(_get_saveable_image_formats); GDVIRTUAL_BIND(_serialize_image_to_bytes, "state", "image", "image_dict", "image_format", "lossy_quality"); GDVIRTUAL_BIND(_save_image_at_path, "state", "image", "file_path", "image_format", "lossy_quality"); @@ -100,6 +102,13 @@ Error GLTFDocumentExtension::parse_texture_json(Ref<GLTFState> p_state, const Di return err; } +Ref<GLTFObjectModelProperty> GLTFDocumentExtension::import_object_model_property(Ref<GLTFState> p_state, const PackedStringArray &p_split_json_pointer, const TypedArray<NodePath> &p_partial_paths) { + Ref<GLTFObjectModelProperty> ret; + ERR_FAIL_COND_V(p_state.is_null(), ret); + GDVIRTUAL_CALL(_import_object_model_property, p_state, p_split_json_pointer, p_partial_paths, ret); + return ret; +} + Error GLTFDocumentExtension::import_post_parse(Ref<GLTFState> p_state) { ERR_FAIL_COND_V(p_state.is_null(), ERR_INVALID_PARAMETER); Error err = OK; @@ -169,6 +178,15 @@ Error GLTFDocumentExtension::export_preserialize(Ref<GLTFState> p_state) { return err; } +Ref<GLTFObjectModelProperty> GLTFDocumentExtension::export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index, const Object *p_target_object, int p_target_depth) { + Ref<GLTFObjectModelProperty> ret; + ERR_FAIL_COND_V(p_state.is_null(), ret); + ERR_FAIL_NULL_V(p_godot_node, ret); + ERR_FAIL_NULL_V(p_target_object, ret); + GDVIRTUAL_CALL(_export_object_model_property, p_state, p_node_path, p_godot_node, p_gltf_node_index, p_target_object, p_target_depth, ret); + return ret; +} + Vector<String> GLTFDocumentExtension::get_saveable_image_formats() { Vector<String> ret; GDVIRTUAL_CALL(_get_saveable_image_formats, ret); diff --git a/modules/gltf/extensions/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h index b70710e015..a6368ea780 100644 --- a/modules/gltf/extensions/gltf_document_extension.h +++ b/modules/gltf/extensions/gltf_document_extension.h @@ -49,6 +49,7 @@ public: virtual Error parse_image_data(Ref<GLTFState> p_state, const PackedByteArray &p_image_data, const String &p_mime_type, Ref<Image> r_image); virtual String get_image_file_extension(); virtual Error parse_texture_json(Ref<GLTFState> p_state, const Dictionary &p_texture_json, Ref<GLTFTexture> r_gltf_texture); + virtual Ref<GLTFObjectModelProperty> import_object_model_property(Ref<GLTFState> p_state, const PackedStringArray &p_split_json_pointer, const TypedArray<NodePath> &p_partial_paths); virtual Error import_post_parse(Ref<GLTFState> p_state); virtual Error import_pre_generate(Ref<GLTFState> p_state); virtual Node3D *generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent); @@ -59,6 +60,7 @@ public: virtual void convert_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_node); virtual Error export_post_convert(Ref<GLTFState> p_state, Node *p_root); virtual Error export_preserialize(Ref<GLTFState> p_state); + virtual Ref<GLTFObjectModelProperty> export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index, const Object *p_target_object, int p_target_depth); virtual Vector<String> get_saveable_image_formats(); virtual PackedByteArray serialize_image_to_bytes(Ref<GLTFState> p_state, Ref<Image> p_image, Dictionary p_image_dict, const String &p_image_format, float p_lossy_quality); virtual Error save_image_at_path(Ref<GLTFState> p_state, Ref<Image> p_image, const String &p_file_path, const String &p_image_format, float p_lossy_quality); @@ -73,6 +75,7 @@ public: GDVIRTUAL4R(Error, _parse_image_data, Ref<GLTFState>, PackedByteArray, String, Ref<Image>); GDVIRTUAL0R(String, _get_image_file_extension); GDVIRTUAL3R(Error, _parse_texture_json, Ref<GLTFState>, Dictionary, Ref<GLTFTexture>); + GDVIRTUAL3R(Ref<GLTFObjectModelProperty>, _import_object_model_property, Ref<GLTFState>, PackedStringArray, TypedArray<NodePath>); GDVIRTUAL1R(Error, _import_post_parse, Ref<GLTFState>); GDVIRTUAL1R(Error, _import_pre_generate, Ref<GLTFState>); GDVIRTUAL3R(Node3D *, _generate_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *); @@ -83,6 +86,7 @@ public: GDVIRTUAL3(_convert_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *); GDVIRTUAL2R(Error, _export_post_convert, Ref<GLTFState>, Node *); GDVIRTUAL1R(Error, _export_preserialize, Ref<GLTFState>); + GDVIRTUAL6R(Ref<GLTFObjectModelProperty>, _export_object_model_property, Ref<GLTFState>, NodePath, const Node *, GLTFNodeIndex, const Object *, int); GDVIRTUAL0R(Vector<String>, _get_saveable_image_formats); GDVIRTUAL5R(PackedByteArray, _serialize_image_to_bytes, Ref<GLTFState>, Ref<Image>, Dictionary, String, float); GDVIRTUAL5R(Error, _save_image_at_path, Ref<GLTFState>, Ref<Image>, String, String, float); diff --git a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp index cde30bce18..b5edd35ad5 100644 --- a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp +++ b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp @@ -63,6 +63,7 @@ Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref<GLTFState> p_sta mesh_instance_node_3d->set_mesh(array_mesh); mesh_instance_node_3d->set_skin(importer_mesh_3d->get_skin()); mesh_instance_node_3d->set_skeleton_path(importer_mesh_3d->get_skeleton_path()); + mesh_instance_node_3d->set_visible(importer_mesh_3d->is_visible()); node->replace_by(mesh_instance_node_3d); _copy_meta(importer_mesh_3d, mesh_instance_node_3d); _copy_meta(mesh.ptr(), array_mesh.ptr()); diff --git a/modules/gltf/extensions/gltf_light.cpp b/modules/gltf/extensions/gltf_light.cpp index f6e91c1635..2bdcab2f0c 100644 --- a/modules/gltf/extensions/gltf_light.cpp +++ b/modules/gltf/extensions/gltf_light.cpp @@ -30,6 +30,7 @@ #include "gltf_light.h" +#include "../structures/gltf_object_model_property.h" #include "scene/3d/light_3d.h" void GLTFLight::_bind_methods() { @@ -62,6 +63,21 @@ void GLTFLight::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_cone_angle"), "set_outer_cone_angle", "get_outer_cone_angle"); // float } +void GLTFLight::set_cone_inner_attenuation_conversion_expressions(Ref<GLTFObjectModelProperty> &r_obj_model_prop) { + // Expression to convert glTF innerConeAngle to Godot spot_angle_attenuation. + Ref<Expression> gltf_to_godot_expr; + gltf_to_godot_expr.instantiate(); + PackedStringArray gltf_to_godot_args = { "inner_cone_angle" }; + gltf_to_godot_expr->parse("0.2 / (1.0 - inner_cone_angle / spot_angle) - 0.1", gltf_to_godot_args); + r_obj_model_prop->set_gltf_to_godot_expression(gltf_to_godot_expr); + // Expression to convert Godot spot_angle_attenuation to glTF innerConeAngle. + Ref<Expression> godot_to_gltf_expr; + godot_to_gltf_expr.instantiate(); + PackedStringArray godot_to_gltf_args = { "godot_spot_angle_att" }; + godot_to_gltf_expr->parse("spot_angle * maxf(0.0, 1.0 - (0.2 / (0.1 + godot_spot_angle_att)))", godot_to_gltf_args); + r_obj_model_prop->set_godot_to_gltf_expression(godot_to_gltf_expr); +} + Color GLTFLight::get_color() { return color; } diff --git a/modules/gltf/extensions/gltf_light.h b/modules/gltf/extensions/gltf_light.h index e0894fc8c6..3d522bd174 100644 --- a/modules/gltf/extensions/gltf_light.h +++ b/modules/gltf/extensions/gltf_light.h @@ -33,6 +33,7 @@ #include "core/io/resource.h" +class GLTFObjectModelProperty; class Light3D; // https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_lights_punctual @@ -54,6 +55,8 @@ private: Dictionary additional_data; public: + static void set_cone_inner_attenuation_conversion_expressions(Ref<GLTFObjectModelProperty> &r_obj_model_prop); + Color get_color(); void set_color(Color p_color); diff --git a/modules/gltf/extensions/physics/gltf_document_extension_physics.cpp b/modules/gltf/extensions/physics/gltf_document_extension_physics.cpp index 5c26a1686b..512f25a216 100644 --- a/modules/gltf/extensions/physics/gltf_document_extension_physics.cpp +++ b/modules/gltf/extensions/physics/gltf_document_extension_physics.cpp @@ -31,8 +31,11 @@ #include "gltf_document_extension_physics.h" #include "scene/3d/physics/area_3d.h" +#include "scene/3d/physics/rigid_body_3d.h" #include "scene/3d/physics/static_body_3d.h" +using GLTFShapeIndex = int64_t; + // Import process. Error GLTFDocumentExtensionPhysics::import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) { if (!p_extensions.has("OMI_collider") && !p_extensions.has("OMI_physics_body") && !p_extensions.has("OMI_physics_shape")) { @@ -105,6 +108,7 @@ Error GLTFDocumentExtensionPhysics::parse_node_extensions(Ref<GLTFState> p_state Array state_shapes = p_state->get_additional_data(StringName("GLTFPhysicsShapes")); ERR_FAIL_INDEX_V_MSG(node_shape_index, state_shapes.size(), Error::ERR_FILE_CORRUPT, "glTF Physics: On node " + p_gltf_node->get_name() + ", the shape index " + itos(node_shape_index) + " is not in the state shapes (size: " + itos(state_shapes.size()) + ")."); p_gltf_node->set_additional_data(StringName("GLTFPhysicsColliderShape"), state_shapes[node_shape_index]); + p_gltf_node->set_additional_data(StringName("GLTFPhysicsColliderShapeIndex"), node_shape_index); } else { // If this node is a collider but does not have a collider // shape, then it only serves to combine together shapes. @@ -119,6 +123,7 @@ Error GLTFDocumentExtensionPhysics::parse_node_extensions(Ref<GLTFState> p_state Array state_shapes = p_state->get_additional_data(StringName("GLTFPhysicsShapes")); ERR_FAIL_INDEX_V_MSG(node_shape_index, state_shapes.size(), Error::ERR_FILE_CORRUPT, "glTF Physics: On node " + p_gltf_node->get_name() + ", the shape index " + itos(node_shape_index) + " is not in the state shapes (size: " + itos(state_shapes.size()) + ")."); p_gltf_node->set_additional_data(StringName("GLTFPhysicsTriggerShape"), state_shapes[node_shape_index]); + p_gltf_node->set_additional_data(StringName("GLTFPhysicsTriggerShapeIndex"), node_shape_index); } else { // If this node is a trigger but does not have a trigger shape, // then it's a trigger body, what Godot calls an Area3D node. @@ -129,8 +134,8 @@ Error GLTFDocumentExtensionPhysics::parse_node_extensions(Ref<GLTFState> p_state } // If this node defines explicit member shape nodes, save this information. if (node_trigger.has("nodes")) { - Array node_trigger_nodes = node_trigger["nodes"]; - p_gltf_node->set_additional_data(StringName("GLTFPhysicsCompoundTriggerNodes"), node_trigger_nodes); + Array compound_trigger_nodes = node_trigger["nodes"]; + p_gltf_node->set_additional_data(StringName("GLTFPhysicsCompoundTriggerNodes"), compound_trigger_nodes); } } if (physics_body_ext.has("motion") || physics_body_ext.has("type")) { @@ -140,6 +145,144 @@ Error GLTFDocumentExtensionPhysics::parse_node_extensions(Ref<GLTFState> p_state return OK; } +bool _will_gltf_shape_become_subnode(Ref<GLTFState> p_state, const Ref<GLTFNode> p_gltf_node, GLTFNodeIndex p_gltf_node_index) { + if (p_gltf_node->has_additional_data(StringName("GLTFPhysicsBody"))) { + return true; + } + const TypedArray<GLTFNode> state_gltf_nodes = p_state->get_nodes(); + const GLTFNodeIndex parent_index = p_gltf_node->get_parent(); + if (parent_index == -1 || parent_index >= state_gltf_nodes.size()) { + return true; + } + const Ref<GLTFNode> parent_gltf_node = state_gltf_nodes[parent_index]; + const Variant parent_body_maybe = parent_gltf_node->get_additional_data(StringName("GLTFPhysicsBody")); + if (parent_body_maybe.get_type() != Variant::NIL) { + Ref<GLTFPhysicsBody> parent_body = parent_body_maybe; + // If the parent matches the triggerness, then this node will be generated as a shape (CollisionShape3D). + // Otherwise, if there is a mismatch, a body will be generated for this node, and a subnode will also be generated for the shape. + if (parent_body->get_body_type() == "trigger") { + return p_gltf_node->has_additional_data(StringName("GLTFPhysicsColliderShape")); + } else { + return p_gltf_node->has_additional_data(StringName("GLTFPhysicsTriggerShape")); + } + } + if (parent_gltf_node->has_additional_data(StringName("GLTFPhysicsColliderShape"))) { + return false; + } + if (parent_gltf_node->has_additional_data(StringName("GLTFPhysicsTriggerShape"))) { + return false; + } + Variant compound_trigger_maybe = parent_gltf_node->has_additional_data(StringName("GLTFPhysicsCompoundTriggerNodes")); + if (compound_trigger_maybe.get_type() != Variant::NIL) { + Array compound_trigger_nodes = compound_trigger_maybe; + // Remember, JSON only has numbers, not integers, so must cast to double. + return !compound_trigger_nodes.has((double)p_gltf_node_index); + } + return true; +} + +NodePath _get_scene_node_path_for_shape_index(Ref<GLTFState> p_state, const GLTFNodeIndex p_shape_index) { + TypedArray<GLTFNode> state_gltf_nodes = p_state->get_nodes(); + for (GLTFNodeIndex node_index = 0; node_index < state_gltf_nodes.size(); node_index++) { + const Ref<GLTFNode> gltf_node = state_gltf_nodes[node_index]; + ERR_CONTINUE(gltf_node.is_null()); + // Check if this node has a shape index and if it matches the one we are looking for. + Variant shape_index_maybe = gltf_node->get_additional_data(StringName("GLTFPhysicsColliderShapeIndex")); + if (shape_index_maybe.get_type() != Variant::INT) { + shape_index_maybe = gltf_node->get_additional_data(StringName("GLTFPhysicsTriggerShapeIndex")); + if (shape_index_maybe.get_type() != Variant::INT) { + continue; + } + } + const GLTFShapeIndex shape_index = shape_index_maybe; + if (shape_index != p_shape_index) { + continue; + } + NodePath node_path = gltf_node->get_scene_node_path(p_state); + // At this point, we have found a node with the shape index we were looking for. + if (_will_gltf_shape_become_subnode(p_state, gltf_node, node_index)) { + Vector<StringName> sname_path = node_path.get_names(); + sname_path.append(gltf_node->get_name() + "Shape"); + node_path = NodePath(sname_path, false); + } + return node_path; + } + return NodePath(); +} + +Ref<GLTFObjectModelProperty> GLTFDocumentExtensionPhysics::import_object_model_property(Ref<GLTFState> p_state, const PackedStringArray &p_split_json_pointer, const TypedArray<NodePath> &p_partial_paths) { + Ref<GLTFObjectModelProperty> ret; + if (p_split_json_pointer.size() != 6) { + // The only properties this class cares about are exactly 6 levels deep. + return ret; + } + ret.instantiate(); + const String &prop_name = p_split_json_pointer[5]; + if (p_split_json_pointer[0] == "extensions" && p_split_json_pointer[2] == "shapes") { + if (p_split_json_pointer[1] == "OMI_physics_shape" || p_split_json_pointer[1] == "KHR_collision_shapes") { + const GLTFNodeIndex shape_index = p_split_json_pointer[3].to_int(); + NodePath node_path = _get_scene_node_path_for_shape_index(p_state, shape_index); + if (node_path.is_empty()) { + return ret; + } + String godot_prop_name = prop_name; + if (prop_name == "size") { + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (prop_name == "height" || prop_name == "radius") { + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (prop_name == "radiusBottom" || prop_name == "radiusTop") { + godot_prop_name = "radius"; + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else { + // Not something we handle, return without appending a NodePath. + return ret; + } + // Example: `A/B/C/CollisionShape3D:shape:radius`. + Vector<StringName> subnames; + subnames.append("shape"); + subnames.append(godot_prop_name); + node_path = NodePath(node_path.get_names(), subnames, false); + ret->append_node_path(node_path); + } + } else if (p_split_json_pointer[0] == "nodes" && p_split_json_pointer[2] == "extensions" && p_split_json_pointer[4] == "motion") { + if (p_split_json_pointer[3] == "OMI_physics_body" || p_split_json_pointer[3] == "KHR_physics_rigid_bodies") { + const GLTFNodeIndex node_index = p_split_json_pointer[1].to_int(); + const TypedArray<GLTFNode> all_gltf_nodes = p_state->get_nodes(); + ERR_FAIL_INDEX_V_MSG(node_index, all_gltf_nodes.size(), ret, "GLTF Physics: The node index " + itos(node_index) + " is not in the state nodes (size: " + itos(all_gltf_nodes.size()) + ")."); + const Ref<GLTFNode> gltf_node = all_gltf_nodes[node_index]; + NodePath node_path; + if (p_partial_paths.is_empty()) { + node_path = gltf_node->get_scene_node_path(p_state); + } else { + // The path is already computed for us, just grab it. + node_path = p_partial_paths[0]; + } + if (prop_name == "mass") { + ret->append_path_to_property(node_path, "mass"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (prop_name == "linearVelocity") { + ret->append_path_to_property(node_path, "linear_velocity"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (prop_name == "angularVelocity") { + ret->append_path_to_property(node_path, "angular_velocity"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (prop_name == "centerOfMass") { + ret->append_path_to_property(node_path, "center_of_mass"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (prop_name == "inertiaDiagonal") { + ret->append_path_to_property(node_path, "inertia"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (prop_name == "inertiaOrientation") { + WARN_PRINT("GLTF Physics: The 'inertiaOrientation' property is not supported by Godot."); + } else { + // Not something we handle, return without appending a NodePath. + return ret; + } + } + } + return ret; +} + void _setup_shape_mesh_resource_from_index_if_needed(Ref<GLTFState> p_state, Ref<GLTFPhysicsShape> p_gltf_shape) { GLTFMeshIndex shape_mesh_index = p_gltf_shape->get_mesh_index(); if (shape_mesh_index == -1) { @@ -434,24 +577,126 @@ Array _get_or_create_state_shapes_in_state(Ref<GLTFState> p_state) { return state_shapes; } -Dictionary _export_node_shape(Ref<GLTFState> p_state, Ref<GLTFPhysicsShape> p_physics_shape) { +GLTFShapeIndex _export_node_shape(Ref<GLTFState> p_state, Ref<GLTFPhysicsShape> p_physics_shape) { Array state_shapes = _get_or_create_state_shapes_in_state(p_state); - int size = state_shapes.size(); + GLTFShapeIndex size = state_shapes.size(); Dictionary shape_property; Dictionary shape_dict = p_physics_shape->to_dictionary(); - for (int i = 0; i < size; i++) { + for (GLTFShapeIndex i = 0; i < size; i++) { Dictionary other = state_shapes[i]; if (other == shape_dict) { // De-duplication: If we already have an identical shape, // set the shape index to the existing one and return. - shape_property["shape"] = i; - return shape_property; + return i; } } // If we don't have an identical shape, add it to the array. state_shapes.push_back(shape_dict); - shape_property["shape"] = size; - return shape_property; + return size; +} + +Error GLTFDocumentExtensionPhysics::export_preserialize(Ref<GLTFState> p_state) { + // Note: Need to do _export_node_shape before exporting animations, so export_node is too late. + TypedArray<GLTFNode> state_gltf_nodes = p_state->get_nodes(); + for (Ref<GLTFNode> gltf_node : state_gltf_nodes) { + Ref<GLTFPhysicsShape> collider_shape = gltf_node->get_additional_data(StringName("GLTFPhysicsColliderShape")); + if (collider_shape.is_valid()) { + GLTFShapeIndex collider_shape_index = _export_node_shape(p_state, collider_shape); + gltf_node->set_additional_data(StringName("GLTFPhysicsColliderShapeIndex"), collider_shape_index); + } + Ref<GLTFPhysicsShape> trigger_shape = gltf_node->get_additional_data(StringName("GLTFPhysicsTriggerShape")); + if (trigger_shape.is_valid()) { + GLTFShapeIndex trigger_shape_index = _export_node_shape(p_state, trigger_shape); + gltf_node->set_additional_data(StringName("GLTFPhysicsTriggerShapeIndex"), trigger_shape_index); + } + } + return OK; +} + +Ref<GLTFObjectModelProperty> GLTFDocumentExtensionPhysics::export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index, const Object *p_target_object, int p_target_depth) { + Ref<GLTFObjectModelProperty> ret; + const Vector<StringName> &path_subnames = p_node_path.get_subnames(); + if (path_subnames.is_empty()) { + return ret; + } + ret.instantiate(); + const StringName &node_prop = path_subnames[0]; + if (Object::cast_to<RigidBody3D>(p_target_object)) { + if (path_subnames.size() != 1) { + return ret; + } + // Example: `/nodes/0/extensions/OMI_physics_body/motion/mass` + PackedStringArray split_json_pointer; + split_json_pointer.append("nodes"); + split_json_pointer.append(itos(p_gltf_node_index)); + split_json_pointer.append("extensions"); + split_json_pointer.append("OMI_physics_body"); + split_json_pointer.append("motion"); + if (node_prop == StringName("mass")) { + split_json_pointer.append("mass"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (node_prop == StringName("linear_velocity")) { + split_json_pointer.append("linearVelocity"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (node_prop == StringName("angular_velocity")) { + split_json_pointer.append("angularVelocity"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (node_prop == StringName("center_of_mass")) { + split_json_pointer.append("centerOfMass"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (node_prop == StringName("inertia")) { + split_json_pointer.append("inertiaDiagonal"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else { + // Not something we handle, return without setting the JSON pointer. + return ret; + } + ret->set_json_pointers({ split_json_pointer }); + } else if (Object::cast_to<CollisionShape3D>(p_godot_node)) { + if (path_subnames.size() != 2) { + return ret; + } + // Example: `/extensions/OMI_physics_shape/shapes/0/box/size` + PackedStringArray split_json_pointer; + split_json_pointer.append("extensions"); + split_json_pointer.append("OMI_physics_shape"); + split_json_pointer.append("shapes"); + TypedArray<GLTFNode> state_gltf_nodes = p_state->get_nodes(); + ERR_FAIL_INDEX_V(p_gltf_node_index, state_gltf_nodes.size(), ret); + Ref<GLTFNode> gltf_node = state_gltf_nodes[p_gltf_node_index]; + Variant shape_index_maybe = gltf_node->get_additional_data(StringName("GLTFPhysicsColliderShapeIndex")); + String shape_type; + if (shape_index_maybe.get_type() == Variant::INT) { + Ref<GLTFPhysicsShape> collider_shape = gltf_node->get_additional_data(StringName("GLTFPhysicsColliderShape")); + shape_type = collider_shape->get_shape_type(); + } else { + shape_index_maybe = gltf_node->get_additional_data(StringName("GLTFPhysicsTriggerShapeIndex")); + if (shape_index_maybe.get_type() == Variant::INT) { + Ref<GLTFPhysicsShape> trigger_shape = gltf_node->get_additional_data(StringName("GLTFPhysicsTriggerShape")); + shape_type = trigger_shape->get_shape_type(); + } + } + ERR_FAIL_COND_V(shape_index_maybe.get_type() != Variant::INT, ret); + GLTFShapeIndex shape_index = shape_index_maybe; + split_json_pointer.append(itos(shape_index)); + split_json_pointer.append(shape_type); + const StringName &shape_prop = path_subnames[1]; + if (shape_prop == StringName("size")) { + split_json_pointer.append("size"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (shape_prop == StringName("radius")) { + split_json_pointer.append("radius"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (shape_prop == StringName("height")) { + split_json_pointer.append("height"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else { + // Not something we handle, return without setting the JSON pointer. + return ret; + } + ret->set_json_pointers({ split_json_pointer }); + } + return ret; } Error GLTFDocumentExtensionPhysics::export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_node_json, Node *p_node) { @@ -465,13 +710,16 @@ Error GLTFDocumentExtensionPhysics::export_node(Ref<GLTFState> p_state, Ref<GLTF trigger_property["nodes"] = compound_trigger_nodes; } } - Ref<GLTFPhysicsShape> collider_shape = p_gltf_node->get_additional_data(StringName("GLTFPhysicsColliderShape")); - if (collider_shape.is_valid()) { - physics_body_ext["collider"] = _export_node_shape(p_state, collider_shape); + Variant collider_shape_index = p_gltf_node->get_additional_data(StringName("GLTFPhysicsColliderShapeIndex")); + if (collider_shape_index.get_type() == Variant::INT) { + Dictionary collider_dict; + collider_dict["shape"] = collider_shape_index; + physics_body_ext["collider"] = collider_dict; } - Ref<GLTFPhysicsShape> trigger_shape = p_gltf_node->get_additional_data(StringName("GLTFPhysicsTriggerShape")); - if (trigger_shape.is_valid()) { - physics_body_ext["trigger"] = _export_node_shape(p_state, trigger_shape); + Variant trigger_shape_index = p_gltf_node->get_additional_data(StringName("GLTFPhysicsTriggerShapeIndex")); + if (trigger_shape_index.get_type() == Variant::INT) { + Dictionary trigger_dict = physics_body_ext.get_or_add("trigger", {}); + trigger_dict["shape"] = trigger_shape_index; } if (!physics_body_ext.is_empty()) { Dictionary node_extensions = r_node_json["extensions"]; diff --git a/modules/gltf/extensions/physics/gltf_document_extension_physics.h b/modules/gltf/extensions/physics/gltf_document_extension_physics.h index 3d5027c0df..76a60a6375 100644 --- a/modules/gltf/extensions/physics/gltf_document_extension_physics.h +++ b/modules/gltf/extensions/physics/gltf_document_extension_physics.h @@ -43,9 +43,12 @@ public: Error import_preflight(Ref<GLTFState> p_state, Vector<String> p_extensions) override; Vector<String> get_supported_extensions() override; Error parse_node_extensions(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &p_extensions) override; + Ref<GLTFObjectModelProperty> import_object_model_property(Ref<GLTFState> p_state, const PackedStringArray &p_split_json_pointer, const TypedArray<NodePath> &p_partial_paths) override; Node3D *generate_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) override; // Export process. void convert_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_node) override; + Error export_preserialize(Ref<GLTFState> p_state) override; + Ref<GLTFObjectModelProperty> export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index, const Object *p_target_object, int p_target_depth) override; Error export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_node_json, Node *p_scene_node) override; }; diff --git a/modules/gltf/extensions/physics/gltf_physics_body.cpp b/modules/gltf/extensions/physics/gltf_physics_body.cpp index c11aa5d2ff..7c40f96e0a 100644 --- a/modules/gltf/extensions/physics/gltf_physics_body.cpp +++ b/modules/gltf/extensions/physics/gltf_physics_body.cpp @@ -193,9 +193,6 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_ physics_body->angular_velocity = body->get_angular_velocity(); physics_body->center_of_mass = body->get_center_of_mass(); physics_body->inertia_diagonal = body->get_inertia(); - if (body->get_center_of_mass() != Vector3()) { - WARN_PRINT("GLTFPhysicsBody: This rigid body has a center of mass offset from the origin, which will be ignored when exporting to glTF."); - } if (cast_to<VehicleBody3D>(p_body_node)) { physics_body->body_type = PhysicsBodyType::VEHICLE; } else { diff --git a/modules/gltf/gltf_defines.h b/modules/gltf/gltf_defines.h index c1918e5908..4d88f7c342 100644 --- a/modules/gltf/gltf_defines.h +++ b/modules/gltf/gltf_defines.h @@ -43,6 +43,7 @@ class GLTFDocumentExtension; class GLTFLight; class GLTFMesh; class GLTFNode; +class GLTFObjectModelProperty; class GLTFSkeleton; class GLTFSkin; class GLTFSpecGloss; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 0a487430a3..aa482615da 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -69,6 +69,10 @@ #include <stdlib.h> #include <cstdint> +constexpr int COMPONENT_COUNT_FOR_ACCESSOR_TYPE[7] = { + 1, 2, 3, 4, 4, 9, 16 +}; + static void _attach_extras_to_meta(const Dictionary &p_extras, Ref<Resource> p_node) { if (!p_extras.is_empty()) { p_node->set_meta("extras", p_extras); @@ -1013,7 +1017,7 @@ Error GLTFDocument::_parse_accessors(Ref<GLTFState> p_state) { accessor.instantiate(); ERR_FAIL_COND_V(!d.has("componentType"), ERR_PARSE_ERROR); - accessor->component_type = d["componentType"]; + accessor->component_type = (GLTFAccessor::GLTFComponentType)(int32_t)d["componentType"]; ERR_FAIL_COND_V(!d.has("count"), ERR_PARSE_ERROR); accessor->count = d["count"]; ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR); @@ -1050,7 +1054,7 @@ Error GLTFDocument::_parse_accessors(Ref<GLTFState> p_state) { ERR_FAIL_COND_V(!si.has("bufferView"), ERR_PARSE_ERROR); accessor->sparse_indices_buffer_view = si["bufferView"]; ERR_FAIL_COND_V(!si.has("componentType"), ERR_PARSE_ERROR); - accessor->sparse_indices_component_type = si["componentType"]; + accessor->sparse_indices_component_type = (GLTFAccessor::GLTFComponentType)(int32_t)si["componentType"]; if (si.has("byteOffset")) { accessor->sparse_indices_byte_offset = si["byteOffset"]; @@ -1082,31 +1086,39 @@ double GLTFDocument::_filter_number(double p_float) { return (double)(float)p_float; } -String GLTFDocument::_get_component_type_name(const uint32_t p_component) { +String GLTFDocument::_get_component_type_name(const GLTFAccessor::GLTFComponentType p_component) { switch (p_component) { - case GLTFDocument::COMPONENT_TYPE_BYTE: + case GLTFAccessor::COMPONENT_TYPE_NONE: + return "None"; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: return "Byte"; - case GLTFDocument::COMPONENT_TYPE_UNSIGNED_BYTE: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: return "UByte"; - case GLTFDocument::COMPONENT_TYPE_SHORT: + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: return "Short"; - case GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: return "UShort"; - case GLTFDocument::COMPONENT_TYPE_INT: + case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: return "Int"; - case GLTFDocument::COMPONENT_TYPE_FLOAT: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: + return "UInt"; + case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: return "Float"; + case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: + return "Double"; + case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: + return "Half"; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: + return "Long"; + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: + return "ULong"; } return "<Error>"; } -Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { - const int component_count_for_type[7] = { - 1, 2, 3, 4, 4, 9, 16 - }; - - const int component_count = component_count_for_type[p_accessor_type]; +Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const GLTFAccessor::GLTFComponentType p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { + const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type]; const int component_size = _get_component_type_size(p_component_type); ERR_FAIL_COND_V(component_size == 0, FAILED); @@ -1114,8 +1126,8 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ int skip_bytes = 0; //special case of alignments, as described in spec switch (p_component_type) { - case COMPONENT_TYPE_BYTE: - case COMPONENT_TYPE_UNSIGNED_BYTE: { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: { if (p_accessor_type == GLTFAccessor::TYPE_MAT2) { skip_every = 2; skip_bytes = 2; @@ -1125,8 +1137,8 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ skip_bytes = 1; } } break; - case COMPONENT_TYPE_SHORT: - case COMPONENT_TYPE_UNSIGNED_SHORT: { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { if (p_accessor_type == GLTFAccessor::TYPE_MAT3) { skip_every = 6; skip_bytes = 4; @@ -1161,7 +1173,10 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ } switch (p_component_type) { - case COMPONENT_TYPE_BYTE: { + case GLTFAccessor::COMPONENT_TYPE_NONE: { + ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to encode buffer view, component type not set."); + } + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: { Vector<int8_t> buffer; buffer.resize(p_count * component_count); int32_t dst_i = 0; @@ -1185,7 +1200,7 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int8_t)); bv->byte_length = buffer.size() * sizeof(int8_t); } break; - case COMPONENT_TYPE_UNSIGNED_BYTE: { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: { Vector<uint8_t> buffer; buffer.resize(p_count * component_count); int32_t dst_i = 0; @@ -1207,7 +1222,7 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ gltf_buffer.append_array(buffer); bv->byte_length = buffer.size() * sizeof(uint8_t); } break; - case COMPONENT_TYPE_SHORT: { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: { Vector<int16_t> buffer; buffer.resize(p_count * component_count); int32_t dst_i = 0; @@ -1231,7 +1246,7 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int16_t)); bv->byte_length = buffer.size() * sizeof(int16_t); } break; - case COMPONENT_TYPE_UNSIGNED_SHORT: { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { Vector<uint16_t> buffer; buffer.resize(p_count * component_count); int32_t dst_i = 0; @@ -1255,8 +1270,28 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(uint16_t)); bv->byte_length = buffer.size() * sizeof(uint16_t); } break; - case COMPONENT_TYPE_INT: { - Vector<int> buffer; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: { + Vector<int32_t> buffer; + buffer.resize(p_count * component_count); + int32_t dst_i = 0; + for (int i = 0; i < p_count; i++) { + for (int j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + double d = *p_src; + buffer.write[dst_i] = d; + p_src++; + dst_i++; + } + } + int64_t old_size = gltf_buffer.size(); + gltf_buffer.resize(old_size + (buffer.size() * sizeof(uint32_t))); + memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(uint32_t)); + bv->byte_length = buffer.size() * sizeof(uint32_t); + } break; + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: { + Vector<uint32_t> buffer; buffer.resize(p_count * component_count); int32_t dst_i = 0; for (int i = 0; i < p_count; i++) { @@ -1271,11 +1306,11 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ } } int64_t old_size = gltf_buffer.size(); - gltf_buffer.resize(old_size + (buffer.size() * sizeof(int32_t))); - memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int32_t)); - bv->byte_length = buffer.size() * sizeof(int32_t); + gltf_buffer.resize(old_size + (buffer.size() * sizeof(uint32_t))); + memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(uint32_t)); + bv->byte_length = buffer.size() * sizeof(uint32_t); } break; - case COMPONENT_TYPE_FLOAT: { + case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: { Vector<float> buffer; buffer.resize(p_count * component_count); int32_t dst_i = 0; @@ -1295,6 +1330,71 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(float)); bv->byte_length = buffer.size() * sizeof(float); } break; + case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: { + Vector<double> buffer; + buffer.resize(p_count * component_count); + int32_t dst_i = 0; + for (int i = 0; i < p_count; i++) { + for (int j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + double d = *p_src; + buffer.write[dst_i] = d; + p_src++; + dst_i++; + } + } + int64_t old_size = gltf_buffer.size(); + gltf_buffer.resize(old_size + (buffer.size() * sizeof(double))); + memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(double)); + bv->byte_length = buffer.size() * sizeof(double); + } break; + case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: { + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "glTF: Half float not supported yet."); + } break; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: { + Vector<int64_t> buffer; + buffer.resize(p_count * component_count); + int32_t dst_i = 0; + for (int i = 0; i < p_count; i++) { + for (int j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + // FIXME: This can result in precision loss because int64_t can store some values that double can't. + double d = *p_src; + buffer.write[dst_i] = d; + p_src++; + dst_i++; + } + } + int64_t old_size = gltf_buffer.size(); + gltf_buffer.resize(old_size + (buffer.size() * sizeof(int64_t))); + memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int64_t)); + bv->byte_length = buffer.size() * sizeof(int64_t); + } break; + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: { + Vector<uint64_t> buffer; + buffer.resize(p_count * component_count); + int32_t dst_i = 0; + for (int i = 0; i < p_count; i++) { + for (int j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + // FIXME: This can result in precision loss because int64_t can store some values that double can't. + double d = *p_src; + buffer.write[dst_i] = d; + p_src++; + dst_i++; + } + } + int64_t old_size = gltf_buffer.size(); + gltf_buffer.resize(old_size + (buffer.size() * sizeof(uint64_t))); + memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(uint64_t)); + bv->byte_length = buffer.size() * sizeof(uint64_t); + } break; } ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_INVALID_DATA); @@ -1309,7 +1409,7 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ return OK; } -Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_count, const int p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex) { +Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_count, const GLTFAccessor::GLTFComponentType p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex) { const Ref<GLTFBufferView> bv = p_state->buffer_views[p_buffer_view]; int stride = p_element_size; @@ -1348,7 +1448,10 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c double d = 0; switch (p_component_type) { - case COMPONENT_TYPE_BYTE: { + case GLTFAccessor::COMPONENT_TYPE_NONE: { + ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to decode buffer view, component type not set."); + } break; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: { int8_t b = int8_t(*src); if (p_normalized) { d = (double(b) / 128.0); @@ -1356,7 +1459,7 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c d = double(b); } } break; - case COMPONENT_TYPE_UNSIGNED_BYTE: { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: { uint8_t b = *src; if (p_normalized) { d = (double(b) / 255.0); @@ -1364,7 +1467,7 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c d = double(b); } } break; - case COMPONENT_TYPE_SHORT: { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: { int16_t s = *(int16_t *)src; if (p_normalized) { d = (double(s) / 32768.0); @@ -1372,7 +1475,7 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c d = double(s); } } break; - case COMPONENT_TYPE_UNSIGNED_SHORT: { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { uint16_t s = *(uint16_t *)src; if (p_normalized) { d = (double(s) / 65535.0); @@ -1380,12 +1483,27 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c d = double(s); } } break; - case COMPONENT_TYPE_INT: { - d = *(int *)src; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: { + d = *(int32_t *)src; + } break; + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: { + d = *(uint32_t *)src; } break; - case COMPONENT_TYPE_FLOAT: { + case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: { d = *(float *)src; } break; + case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: { + d = *(double *)src; + } break; + case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: { + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "glTF: Half float not supported yet."); + } break; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: { + d = *(int64_t *)src; + } break; + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: { + d = *(uint64_t *)src; + } break; } *p_dst++ = d; @@ -1396,25 +1514,27 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c return OK; } -int GLTFDocument::_get_component_type_size(const int p_component_type) { +int GLTFDocument::_get_component_type_size(const GLTFAccessor::GLTFComponentType p_component_type) { switch (p_component_type) { - case COMPONENT_TYPE_BYTE: - case COMPONENT_TYPE_UNSIGNED_BYTE: + case GLTFAccessor::COMPONENT_TYPE_NONE: + ERR_FAIL_V(0); + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: return 1; - break; - case COMPONENT_TYPE_SHORT: - case COMPONENT_TYPE_UNSIGNED_SHORT: + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: + case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: return 2; - break; - case COMPONENT_TYPE_INT: - case COMPONENT_TYPE_FLOAT: + case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: + case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: return 4; - break; - default: { - ERR_FAIL_V(0); - } + case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: + case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: + return 8; } - return 0; + ERR_FAIL_V(0); } Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) { @@ -1425,11 +1545,7 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF const Ref<GLTFAccessor> a = p_state->accessors[p_accessor]; - const int component_count_for_type[7] = { - 1, 2, 3, 4, 4, 9, 16 - }; - - const int component_count = component_count_for_type[a->accessor_type]; + const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[a->accessor_type]; const int component_size = _get_component_type_size(a->component_type); ERR_FAIL_COND_V(component_size == 0, Vector<double>()); int element_size = component_count * component_size; @@ -1438,8 +1554,8 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF int skip_bytes = 0; //special case of alignments, as described in spec switch (a->component_type) { - case COMPONENT_TYPE_BYTE: - case COMPONENT_TYPE_UNSIGNED_BYTE: { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: { if (a->accessor_type == GLTFAccessor::TYPE_MAT2) { skip_every = 2; skip_bytes = 2; @@ -1451,8 +1567,8 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF element_size = 12; //override for this case } } break; - case COMPONENT_TYPE_SHORT: - case COMPONENT_TYPE_UNSIGNED_SHORT: { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { if (a->accessor_type == GLTFAccessor::TYPE_MAT3) { skip_every = 6; skip_bytes = 4; @@ -1550,11 +1666,11 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state, } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_SCALAR; - int component_type; + GLTFAccessor::GLTFComponentType component_type; if (max_index > 65535 || p_for_vertex) { - component_type = GLTFDocument::COMPONENT_TYPE_INT; + component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT; } else { - component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; + component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT; } accessor->max = type_max; @@ -1664,7 +1780,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state, } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC2; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -1717,7 +1833,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -1784,7 +1900,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_sta } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -1835,7 +1951,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_stat } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4; - const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT; accessor->max = type_max; accessor->min = type_min; @@ -1888,7 +2004,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC4; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -1932,7 +2048,7 @@ Vector<Vector2> GLTFDocument::_decode_accessor_as_vec2(Ref<GLTFState> p_state, c return ret; } -GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_state, const Vector<real_t> p_attribs, const bool p_for_vertex) { +GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_state, const Vector<double> p_attribs, const bool p_for_vertex) { if (p_attribs.size() == 0) { return -1; } @@ -1963,7 +2079,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_stat } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_SCALAR; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -2013,7 +2129,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state, } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC3; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -2089,7 +2205,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_VEC3; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; sparse_accessor->normalized = false; sparse_accessor->count = p_attribs.size(); @@ -2112,9 +2228,9 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p GLTFBufferIndex buffer_view_i_indices = -1; GLTFBufferIndex buffer_view_i_values = -1; if (sparse_accessor_index_stride == 4) { - sparse_accessor->sparse_indices_component_type = GLTFDocument::COMPONENT_TYPE_INT; + sparse_accessor->sparse_indices_component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT; } else { - sparse_accessor->sparse_indices_component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; + sparse_accessor->sparse_indices_component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT; } if (_encode_buffer_view(p_state, changed_indices.ptr(), changed_indices.size(), GLTFAccessor::TYPE_SCALAR, sparse_accessor->sparse_indices_component_type, sparse_accessor->normalized, sparse_accessor->sparse_indices_byte_offset, false, buffer_view_i_indices) != OK) { return -1; @@ -2194,7 +2310,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state } int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_MAT4; - const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; + const GLTFAccessor::GLTFComponentType component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT; accessor->max = type_max; accessor->min = type_min; @@ -2343,6 +2459,325 @@ Vector<Transform3D> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> p_sta return ret; } +Vector<Variant> GLTFDocument::_decode_accessor_as_variant(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, Variant::Type p_variant_type, GLTFAccessor::GLTFAccessorType p_accessor_type) { + const Vector<double> attribs = _decode_accessor(p_state, p_accessor, false); + Vector<Variant> ret; + ERR_FAIL_COND_V_MSG(attribs.is_empty(), ret, "glTF: The accessor was empty."); + const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type]; + ERR_FAIL_COND_V_MSG(attribs.size() % component_count != 0, ret, "glTF: The accessor size was not a multiple of the component count."); + const int ret_size = attribs.size() / component_count; + ret.resize(ret_size); + for (int i = 0; i < ret_size; i++) { + switch (p_variant_type) { + case Variant::BOOL: { + ret.write[i] = attribs[i * component_count] != 0.0; + } break; + case Variant::INT: { + ret.write[i] = (int64_t)attribs[i * component_count]; + } break; + case Variant::FLOAT: { + ret.write[i] = attribs[i * component_count]; + } break; + case Variant::VECTOR2: + case Variant::RECT2: + case Variant::VECTOR3: + case Variant::VECTOR4: + case Variant::PLANE: + case Variant::QUATERNION: { + // General-purpose code for importing glTF accessor data with any component count into structs up to 4 `real_t`s in size. + Variant v; + switch (component_count) { + case 1: { + v = Vector4(attribs[i * component_count], 0.0f, 0.0f, 0.0f); + } break; + case 2: { + v = Vector4(attribs[i * component_count], attribs[i * component_count + 1], 0.0f, 0.0f); + } break; + case 3: { + v = Vector4(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], 0.0f); + } break; + default: { + v = Vector4(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], attribs[i * component_count + 3]); + } break; + } + // Evil hack that relies on the structure of Variant, but it's the + // only way to accomplish this without a ton of code duplication. + *(Variant::Type *)&v = p_variant_type; + ret.write[i] = v; + } break; + case Variant::VECTOR2I: + case Variant::RECT2I: + case Variant::VECTOR3I: + case Variant::VECTOR4I: { + // General-purpose code for importing glTF accessor data with any component count into structs up to 4 `int32_t`s in size. + Variant v; + switch (component_count) { + case 1: { + v = Vector4i((int32_t)attribs[i * component_count], 0, 0, 0); + } break; + case 2: { + v = Vector4i((int32_t)attribs[i * component_count], (int32_t)attribs[i * component_count + 1], 0, 0); + } break; + case 3: { + v = Vector4i((int32_t)attribs[i * component_count], (int32_t)attribs[i * component_count + 1], (int32_t)attribs[i * component_count + 2], 0); + } break; + default: { + v = Vector4i((int32_t)attribs[i * component_count], (int32_t)attribs[i * component_count + 1], (int32_t)attribs[i * component_count + 2], (int32_t)attribs[i * component_count + 3]); + } break; + } + // Evil hack that relies on the structure of Variant, but it's the + // only way to accomplish this without a ton of code duplication. + *(Variant::Type *)&v = p_variant_type; + ret.write[i] = v; + } break; + // No more generalized hacks, each of the below types needs a lot of repetitive code. + case Variant::COLOR: { + Variant v; + switch (component_count) { + case 1: { + v = Color(attribs[i * component_count], 0.0f, 0.0f, 1.0f); + } break; + case 2: { + v = Color(attribs[i * component_count], attribs[i * component_count + 1], 0.0f, 1.0f); + } break; + case 3: { + v = Color(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], 1.0f); + } break; + default: { + v = Color(attribs[i * component_count], attribs[i * component_count + 1], attribs[i * component_count + 2], attribs[i * component_count + 3]); + } break; + } + ret.write[i] = v; + } break; + case Variant::TRANSFORM2D: { + Transform2D t; + switch (component_count) { + case 4: { + t.columns[0] = Vector2(attribs[i * component_count + 0], attribs[i * component_count + 1]); + t.columns[1] = Vector2(attribs[i * component_count + 2], attribs[i * component_count + 3]); + } break; + case 9: { + t.columns[0] = Vector2(attribs[i * component_count + 0], attribs[i * component_count + 1]); + t.columns[1] = Vector2(attribs[i * component_count + 3], attribs[i * component_count + 4]); + t.columns[2] = Vector2(attribs[i * component_count + 6], attribs[i * component_count + 7]); + } break; + case 16: { + t.columns[0] = Vector2(attribs[i * component_count + 0], attribs[i * component_count + 1]); + t.columns[1] = Vector2(attribs[i * component_count + 4], attribs[i * component_count + 5]); + t.columns[2] = Vector2(attribs[i * component_count + 12], attribs[i * component_count + 13]); + } break; + } + ret.write[i] = t; + } break; + case Variant::BASIS: { + Basis b; + switch (component_count) { + case 4: { + b.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 2], 0.0f); + b.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 3], 0.0f); + } break; + case 9: { + b.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 3], attribs[i * component_count + 6]); + b.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 4], attribs[i * component_count + 7]); + b.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 5], attribs[i * component_count + 8]); + } break; + case 16: { + b.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 4], attribs[i * component_count + 8]); + b.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 5], attribs[i * component_count + 9]); + b.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 6], attribs[i * component_count + 10]); + } break; + } + ret.write[i] = b; + } break; + case Variant::TRANSFORM3D: { + Transform3D t; + switch (component_count) { + case 4: { + t.basis.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 2], 0.0f); + t.basis.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 3], 0.0f); + } break; + case 9: { + t.basis.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 3], attribs[i * component_count + 6]); + t.basis.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 4], attribs[i * component_count + 7]); + t.basis.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 5], attribs[i * component_count + 8]); + } break; + case 16: { + t.basis.rows[0] = Vector3(attribs[i * component_count + 0], attribs[i * component_count + 4], attribs[i * component_count + 8]); + t.basis.rows[1] = Vector3(attribs[i * component_count + 1], attribs[i * component_count + 5], attribs[i * component_count + 9]); + t.basis.rows[2] = Vector3(attribs[i * component_count + 2], attribs[i * component_count + 6], attribs[i * component_count + 10]); + t.origin = Vector3(attribs[i * component_count + 12], attribs[i * component_count + 13], attribs[i * component_count + 14]); + } break; + } + ret.write[i] = t; + } break; + case Variant::PROJECTION: { + Projection p; + switch (component_count) { + case 4: { + p.columns[0] = Vector4(attribs[i * component_count + 0], attribs[i * component_count + 1], 0.0f, 0.0f); + p.columns[1] = Vector4(attribs[i * component_count + 4], attribs[i * component_count + 5], 0.0f, 0.0f); + } break; + case 9: { + p.columns[0] = Vector4(attribs[i * component_count + 0], attribs[i * component_count + 1], attribs[i * component_count + 2], 0.0f); + p.columns[1] = Vector4(attribs[i * component_count + 4], attribs[i * component_count + 5], attribs[i * component_count + 6], 0.0f); + p.columns[2] = Vector4(attribs[i * component_count + 8], attribs[i * component_count + 9], attribs[i * component_count + 10], 0.0f); + } break; + case 16: { + p.columns[0] = Vector4(attribs[i * component_count + 0], attribs[i * component_count + 1], attribs[i * component_count + 2], attribs[i * component_count + 3]); + p.columns[1] = Vector4(attribs[i * component_count + 4], attribs[i * component_count + 5], attribs[i * component_count + 6], attribs[i * component_count + 7]); + p.columns[2] = Vector4(attribs[i * component_count + 8], attribs[i * component_count + 9], attribs[i * component_count + 10], attribs[i * component_count + 11]); + p.columns[3] = Vector4(attribs[i * component_count + 12], attribs[i * component_count + 13], attribs[i * component_count + 14], attribs[i * component_count + 15]); + } break; + } + ret.write[i] = p; + } break; + default: { + ERR_FAIL_V_MSG(ret, "glTF: Cannot decode accessor as Variant of type " + Variant::get_type_name(p_variant_type) + "."); + } + } + } + return ret; +} + +GLTFAccessorIndex GLTFDocument::_encode_accessor_as_variant(Ref<GLTFState> p_state, Vector<Variant> p_attribs, Variant::Type p_variant_type, GLTFAccessor::GLTFAccessorType p_accessor_type, GLTFAccessor::GLTFComponentType p_component_type) { + const int accessor_component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type]; + Vector<double> encoded_attribs; + for (const Variant &v : p_attribs) { + switch (p_variant_type) { + case Variant::NIL: + case Variant::BOOL: + case Variant::INT: + case Variant::FLOAT: { + // For scalar values, just append them. Variant can convert all of these to double. Some padding may also be needed. + encoded_attribs.append(v); + if (unlikely(accessor_component_count > 1)) { + for (int i = 1; i < accessor_component_count; i++) { + encoded_attribs.append(0.0); + } + } + } break; + case Variant::VECTOR2: + case Variant::VECTOR2I: + case Variant::VECTOR3: + case Variant::VECTOR3I: + case Variant::VECTOR4: + case Variant::VECTOR4I: { + // Variant can handle converting Vector2/2i/3/3i/4/4i to Vector4 for us. + Vector4 vec = v; + if (likely(accessor_component_count < 5)) { + for (int i = 0; i < accessor_component_count; i++) { + encoded_attribs.append(vec[i]); + } + } + } break; + case Variant::PLANE: { + Plane p = v; + if (likely(accessor_component_count == 4)) { + encoded_attribs.append(p.normal.x); + encoded_attribs.append(p.normal.y); + encoded_attribs.append(p.normal.z); + encoded_attribs.append(p.d); + } + } break; + case Variant::QUATERNION: { + Quaternion q = v; + if (likely(accessor_component_count < 5)) { + for (int i = 0; i < accessor_component_count; i++) { + encoded_attribs.append(q[i]); + } + } + } break; + case Variant::COLOR: { + Color c = v; + if (likely(accessor_component_count < 5)) { + for (int i = 0; i < accessor_component_count; i++) { + encoded_attribs.append(c[i]); + } + } + } break; + case Variant::RECT2: + case Variant::RECT2I: { + // Variant can handle converting Rect2i to Rect2 for us. + Rect2 r = v; + if (likely(accessor_component_count == 4)) { + encoded_attribs.append(r.position.x); + encoded_attribs.append(r.position.y); + encoded_attribs.append(r.size.x); + encoded_attribs.append(r.size.y); + } + } break; + case Variant::TRANSFORM2D: + case Variant::BASIS: + case Variant::TRANSFORM3D: + case Variant::PROJECTION: { + // Variant can handle converting Transform2D/Transform3D/Basis to Projection for us. + Projection p = v; + if (accessor_component_count == 16) { + for (int i = 0; i < 4; i++) { + encoded_attribs.append(p.columns[i][0]); + encoded_attribs.append(p.columns[i][1]); + encoded_attribs.append(p.columns[i][2]); + encoded_attribs.append(p.columns[i][3]); + } + } else if (accessor_component_count == 9) { + for (int i = 0; i < 3; i++) { + encoded_attribs.append(p.columns[i][0]); + encoded_attribs.append(p.columns[i][1]); + encoded_attribs.append(p.columns[i][2]); + } + } else if (accessor_component_count == 4) { + encoded_attribs.append(p.columns[0][0]); + encoded_attribs.append(p.columns[0][1]); + encoded_attribs.append(p.columns[1][0]); + encoded_attribs.append(p.columns[1][1]); + } + } break; + default: { + ERR_FAIL_V_MSG(-1, "glTF: Cannot encode accessor from Variant of type " + Variant::get_type_name(p_variant_type) + "."); + } + } + } + // Determine the min and max values for the accessor. + Vector<double> type_max; + type_max.resize(accessor_component_count); + Vector<double> type_min; + type_min.resize(accessor_component_count); + for (int i = 0; i < encoded_attribs.size(); i++) { + if (Math::is_zero_approx(encoded_attribs[i])) { + encoded_attribs.write[i] = 0.0; + } else { + encoded_attribs.write[i] = _filter_number(encoded_attribs[i]); + } + } + for (int i = 0; i < p_attribs.size(); i++) { + _calc_accessor_min_max(i, accessor_component_count, type_max, encoded_attribs, type_min); + } + _round_min_max_components(type_min, type_max); + // Encode the data in a buffer view. + GLTFBufferIndex buffer_view_index = 0; + if (p_state->buffers.is_empty()) { + p_state->buffers.push_back(Vector<uint8_t>()); + } + const int64_t buffer_size = p_state->buffers[buffer_view_index].size(); + Error err = _encode_buffer_view(p_state, encoded_attribs.ptr(), p_attribs.size(), p_accessor_type, p_component_type, false, buffer_size, false, buffer_view_index); + if (err != OK) { + return -1; + } + // Create the accessor and fill it with the data. + Ref<GLTFAccessor> accessor; + accessor.instantiate(); + accessor->max = type_max; + accessor->min = type_min; + accessor->count = p_attribs.size(); + accessor->accessor_type = p_accessor_type; + accessor->component_type = p_component_type; + accessor->byte_offset = 0; + accessor->buffer_view = buffer_view_index; + const GLTFAccessorIndex new_accessor_index = p_state->accessors.size(); + p_state->accessors.push_back(accessor); + return new_accessor_index; +} + Error GLTFDocument::_serialize_meshes(Ref<GLTFState> p_state) { Array meshes; for (GLTFMeshIndex gltf_mesh_i = 0; gltf_mesh_i < p_state->meshes.size(); gltf_mesh_i++) { @@ -2778,41 +3213,42 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { Array meshes = p_state->json["meshes"]; for (GLTFMeshIndex i = 0; i < meshes.size(); i++) { print_verbose("glTF: Parsing mesh: " + itos(i)); - Dictionary d = meshes[i]; + Dictionary mesh_dict = meshes[i]; Ref<GLTFMesh> mesh; mesh.instantiate(); bool has_vertex_color = false; - ERR_FAIL_COND_V(!d.has("primitives"), ERR_PARSE_ERROR); + ERR_FAIL_COND_V(!mesh_dict.has("primitives"), ERR_PARSE_ERROR); - Array primitives = d["primitives"]; - const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary(); + Array primitives = mesh_dict["primitives"]; + const Dictionary &extras = mesh_dict.has("extras") ? (Dictionary)mesh_dict["extras"] : Dictionary(); _attach_extras_to_meta(extras, mesh); Ref<ImporterMesh> import_mesh; import_mesh.instantiate(); String mesh_name = "mesh"; - if (d.has("name") && !String(d["name"]).is_empty()) { - mesh_name = d["name"]; + if (mesh_dict.has("name") && !String(mesh_dict["name"]).is_empty()) { + mesh_name = mesh_dict["name"]; mesh->set_original_name(mesh_name); } import_mesh->set_name(_gen_unique_name(p_state, vformat("%s_%s", p_state->scene_name, mesh_name))); mesh->set_name(import_mesh->get_name()); + TypedArray<Material> instance_materials; for (int j = 0; j < primitives.size(); j++) { uint64_t flags = RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; - Dictionary p = primitives[j]; + Dictionary mesh_prim = primitives[j]; Array array; array.resize(Mesh::ARRAY_MAX); - ERR_FAIL_COND_V(!p.has("attributes"), ERR_PARSE_ERROR); + ERR_FAIL_COND_V(!mesh_prim.has("attributes"), ERR_PARSE_ERROR); - Dictionary a = p["attributes"]; + Dictionary a = mesh_prim["attributes"]; Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES; - if (p.has("mode")) { - const int mode = p["mode"]; + if (mesh_prim.has("mode")) { + const int mode = mesh_prim["mode"]; ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT); // Convert mesh.primitive.mode to Godot Mesh enum. See: // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode @@ -2843,8 +3279,8 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { Vector<int> indices_mapping; Vector<int> indices_rev_mapping; Vector<int> indices_vec4_mapping; - if (p.has("indices")) { - indices = _decode_accessor_as_ints(p_state, p["indices"], false); + if (mesh_prim.has("indices")) { + indices = _decode_accessor_as_ints(p_state, mesh_prim["indices"], false); const int is = indices.size(); if (primitive == Mesh::PRIMITIVE_TRIANGLES) { @@ -3046,6 +3482,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { } } array[Mesh::ARRAY_WEIGHTS] = weights; + flags |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; } if (!indices.is_empty()) { @@ -3102,7 +3539,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { } } - if (p_state->force_disable_compression || is_mesh_2d || !a.has("POSITION") || !a.has("NORMAL") || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) { + if (p_state->force_disable_compression || is_mesh_2d || !a.has("POSITION") || !a.has("NORMAL") || mesh_prim.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) { flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; } @@ -3134,9 +3571,9 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { Array morphs; // Blend shapes - if (p.has("targets")) { + if (mesh_prim.has("targets")) { print_verbose("glTF: Mesh has targets"); - const Array &targets = p["targets"]; + const Array &targets = mesh_prim["targets"]; import_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); @@ -3267,8 +3704,8 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { Ref<Material> mat; String mat_name; if (!p_state->discard_meshes_and_materials) { - if (p.has("material")) { - const int material = p["material"]; + if (mesh_prim.has("material")) { + const int material = mesh_prim["material"]; ERR_FAIL_INDEX_V(material, p_state->materials.size(), ERR_FILE_CORRUPT); Ref<Material> mat3d = p_state->materials[material]; ERR_FAIL_COND_V(mat3d.is_null(), ERR_FILE_CORRUPT); @@ -3288,6 +3725,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { mat = mat3d; } ERR_FAIL_COND_V(mat.is_null(), ERR_FILE_CORRUPT); + instance_materials.append(mat); mat_name = mat->get_name(); } import_mesh->add_surface(primitive, array, morphs, @@ -3300,8 +3738,8 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { blend_weights.write[weight_i] = 0.0f; } - if (d.has("weights")) { - const Array &weights = d["weights"]; + if (mesh_dict.has("weights")) { + const Array &weights = mesh_dict["weights"]; for (int j = 0; j < weights.size(); j++) { if (j >= blend_weights.size()) { break; @@ -3310,6 +3748,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { } } mesh->set_blend_weights(blend_weights); + mesh->set_instance_materials(instance_materials); mesh->set_mesh(import_mesh); p_state->meshes.push_back(mesh); @@ -3501,18 +3940,19 @@ void GLTFDocument::_parse_image_save_image(Ref<GLTFState> p_state, const Vector< } #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EXTRACT_TEXTURES) { - if (p_state->base_path.is_empty()) { - p_state->images.push_back(Ref<Texture2D>()); - p_state->source_images.push_back(Ref<Image>()); - } else if (p_image->get_name().is_empty()) { - WARN_PRINT(vformat("glTF: Image index '%d' couldn't be named. Skipping it.", p_index)); - p_state->images.push_back(Ref<Texture2D>()); - p_state->source_images.push_back(Ref<Image>()); + if (p_state->extract_path.is_empty()) { + WARN_PRINT("glTF: Couldn't extract image because the base and extract paths are empty. It will be loaded directly instead, uncompressed."); + } else if (p_state->extract_path.begins_with("res://.godot/imported")) { + WARN_PRINT(vformat("glTF: Extract path is in the imported directory. Image index '%d' will be loaded directly, uncompressed.", p_index)); } else { + if (p_image->get_name().is_empty()) { + WARN_PRINT(vformat("glTF: Image index '%d' did not have a name. It will be automatically given a name based on its index.", p_index)); + p_image->set_name(itos(p_index)); + } bool must_import = true; Vector<uint8_t> img_data = p_image->get_data(); Dictionary generator_parameters; - String file_path = p_state->get_base_path().path_join(p_state->filename.get_basename() + "_" + p_image->get_name()); + String file_path = p_state->get_extract_path().path_join(p_state->get_extract_prefix() + "_" + p_image->get_name()); file_path += p_file_extension.is_empty() ? ".png" : p_file_extension; if (FileAccess::exists(file_path + ".import")) { Ref<ConfigFile> config; @@ -3559,14 +3999,11 @@ void GLTFDocument::_parse_image_save_image(Ref<GLTFState> p_state, const Vector< if (saved_image.is_valid()) { p_state->images.push_back(saved_image); p_state->source_images.push_back(saved_image->get_image()); + return; } else { - WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded with the name: %s. Skipping it.", p_index, p_image->get_name())); - // Placeholder to keep count. - p_state->images.push_back(Ref<Texture2D>()); - p_state->source_images.push_back(Ref<Image>()); + WARN_PRINT(vformat("glTF: Image index '%d' with the name '%s' couldn't be imported. It will be loaded directly instead, uncompressed.", p_index, p_image->get_name())); } } - return; } #endif // TOOLS_ENABLED if (handling == GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_BASISU) { @@ -3649,16 +4086,19 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER); uri = uri.uri_decode(); uri = p_base_path.path_join(uri).replace("\\", "/"); // Fix for Windows. - // ResourceLoader will rely on the file extension to use the relevant loader. - // The spec says that if mimeType is defined, it should take precedence (e.g. - // there could be a `.png` image which is actually JPEG), but there's no easy - // API for that in Godot, so we'd have to load as a buffer (i.e. embedded in - // the material), so we only do that only as fallback. - Ref<Texture2D> texture = ResourceLoader::load(uri); - if (texture.is_valid()) { - p_state->images.push_back(texture); - p_state->source_images.push_back(texture->get_image()); - continue; + // If the image is in the .godot/imported directory, we can't use ResourceLoader. + if (!p_base_path.begins_with("res://.godot/imported")) { + // ResourceLoader will rely on the file extension to use the relevant loader. + // The spec says that if mimeType is defined, it should take precedence (e.g. + // there could be a `.png` image which is actually JPEG), but there's no easy + // API for that in Godot, so we'd have to load as a buffer (i.e. embedded in + // the material), so we only do that only as fallback. + Ref<Texture2D> texture = ResourceLoader::load(uri, "Texture2D"); + if (texture.is_valid()) { + p_state->images.push_back(texture); + p_state->source_images.push_back(texture->get_image()); + continue; + } } // mimeType is optional, but if we have it in the file extension, let's use it. // If the mimeType does not match with the file extension, either it should be @@ -4781,7 +5221,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { for (GLTFAnimationIndex animation_i = 0; animation_i < p_state->animations.size(); animation_i++) { Dictionary d; Ref<GLTFAnimation> gltf_animation = p_state->animations[animation_i]; - if (!gltf_animation->get_tracks().size()) { + if (gltf_animation->is_empty_of_tracks()) { continue; } @@ -4790,18 +5230,18 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { } Array channels; Array samplers; - - for (KeyValue<int, GLTFAnimation::Track> &track_i : gltf_animation->get_tracks()) { - GLTFAnimation::Track track = track_i.value; + // Serialize glTF node tracks with the vanilla glTF animation system. + for (KeyValue<int, GLTFAnimation::NodeTrack> &track_i : gltf_animation->get_node_tracks()) { + GLTFAnimation::NodeTrack track = track_i.value; if (track.position_track.times.size()) { Dictionary t; t["sampler"] = samplers.size(); Dictionary s; s["interpolation"] = interpolation_to_string(track.position_track.interpolation); - Vector<real_t> times = Variant(track.position_track.times); + Vector<double> times = track.position_track.times; s["input"] = _encode_accessor_as_floats(p_state, times, false); - Vector<Vector3> values = Variant(track.position_track.values); + Vector<Vector3> values = track.position_track.values; s["output"] = _encode_accessor_as_vec3(p_state, values, false); samplers.push_back(s); @@ -4819,7 +5259,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { Dictionary s; s["interpolation"] = interpolation_to_string(track.rotation_track.interpolation); - Vector<real_t> times = Variant(track.rotation_track.times); + Vector<double> times = track.rotation_track.times; s["input"] = _encode_accessor_as_floats(p_state, times, false); Vector<Quaternion> values = track.rotation_track.values; s["output"] = _encode_accessor_as_quaternions(p_state, values, false); @@ -4839,9 +5279,9 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { Dictionary s; s["interpolation"] = interpolation_to_string(track.scale_track.interpolation); - Vector<real_t> times = Variant(track.scale_track.times); + Vector<double> times = track.scale_track.times; s["input"] = _encode_accessor_as_floats(p_state, times, false); - Vector<Vector3> values = Variant(track.scale_track.values); + Vector<Vector3> values = track.scale_track.values; s["output"] = _encode_accessor_as_vec3(p_state, values, false); samplers.push_back(s); @@ -4864,7 +5304,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { Dictionary t; t["sampler"] = samplers.size(); Dictionary s; - Vector<real_t> times; + Vector<double> times; const double increment = 1.0 / p_state->get_bake_fps(); { double time = 0.0; @@ -4905,8 +5345,8 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { track.weight_tracks.write[track_idx].values = weight_track; } - Vector<real_t> all_track_times = times; - Vector<real_t> all_track_values; + Vector<double> all_track_times = times; + Vector<double> all_track_values; int32_t values_size = track.weight_tracks[0].values.size(); int32_t weight_tracks_size = track.weight_tracks.size(); all_track_values.resize(weight_tracks_size * values_size); @@ -4933,6 +5373,33 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) { channels.push_back(t); } } + if (!gltf_animation->get_pointer_tracks().is_empty()) { + // Serialize glTF pointer tracks with the KHR_animation_pointer extension. + if (!p_state->extensions_used.has("KHR_animation_pointer")) { + p_state->extensions_used.push_back("KHR_animation_pointer"); + } + for (KeyValue<String, GLTFAnimation::Channel<Variant>> &pointer_track_iter : gltf_animation->get_pointer_tracks()) { + const String &json_pointer = pointer_track_iter.key; + const GLTFAnimation::Channel<Variant> &pointer_track = pointer_track_iter.value; + const Ref<GLTFObjectModelProperty> &obj_model_prop = p_state->object_model_properties[json_pointer]; + Dictionary channel; + channel["sampler"] = samplers.size(); + Dictionary channel_target; + channel_target["path"] = "pointer"; + Dictionary channel_target_ext; + Dictionary channel_target_ext_khr_anim_ptr; + channel_target_ext_khr_anim_ptr["pointer"] = json_pointer; + channel_target_ext["KHR_animation_pointer"] = channel_target_ext_khr_anim_ptr; + channel_target["extensions"] = channel_target_ext; + channel["target"] = channel_target; + channels.push_back(channel); + Dictionary sampler; + sampler["input"] = _encode_accessor_as_floats(p_state, pointer_track.times, false); + sampler["interpolation"] = interpolation_to_string(pointer_track.interpolation); + sampler["output"] = _encode_accessor_as_variant(p_state, pointer_track.values, obj_model_prop->get_variant_type(), obj_model_prop->get_accessor_type()); + samplers.push_back(sampler); + } + } if (channels.size() && samplers.size()) { d["channels"] = channels; d["samplers"] = samplers; @@ -4957,21 +5424,21 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) { const Array &animations = p_state->json["animations"]; - for (GLTFAnimationIndex i = 0; i < animations.size(); i++) { - const Dictionary &d = animations[i]; + for (GLTFAnimationIndex anim_index = 0; anim_index < animations.size(); anim_index++) { + const Dictionary &anim_dict = animations[anim_index]; Ref<GLTFAnimation> animation; animation.instantiate(); - if (!d.has("channels") || !d.has("samplers")) { + if (!anim_dict.has("channels") || !anim_dict.has("samplers")) { continue; } - Array channels = d["channels"]; - Array samplers = d["samplers"]; + Array channels = anim_dict["channels"]; + Array samplers = anim_dict["samplers"]; - if (d.has("name")) { - const String anim_name = d["name"]; + if (anim_dict.has("name")) { + const String anim_name = anim_dict["name"]; const String anim_name_lower = anim_name.to_lower(); if (anim_name_lower.begins_with("loop") || anim_name_lower.ends_with("loop") || anim_name_lower.begins_with("cycle") || anim_name_lower.ends_with("cycle")) { animation->set_loop(true); @@ -4980,46 +5447,22 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) { animation->set_name(_gen_unique_animation_name(p_state, anim_name)); } - for (int j = 0; j < channels.size(); j++) { - const Dictionary &c = channels[j]; - if (!c.has("target")) { - continue; - } - - const Dictionary &t = c["target"]; - if (!t.has("node") || !t.has("path")) { - continue; - } - - ERR_FAIL_COND_V(!c.has("sampler"), ERR_PARSE_ERROR); - const int sampler = c["sampler"]; - ERR_FAIL_INDEX_V(sampler, samplers.size(), ERR_PARSE_ERROR); - - GLTFNodeIndex node = t["node"]; - String path = t["path"]; - - ERR_FAIL_INDEX_V(node, p_state->nodes.size(), ERR_PARSE_ERROR); - - GLTFAnimation::Track *track = nullptr; - - if (!animation->get_tracks().has(node)) { - animation->get_tracks()[node] = GLTFAnimation::Track(); - } - - track = &animation->get_tracks()[node]; - - const Dictionary &s = samplers[sampler]; - - ERR_FAIL_COND_V(!s.has("input"), ERR_PARSE_ERROR); - ERR_FAIL_COND_V(!s.has("output"), ERR_PARSE_ERROR); - - const int input = s["input"]; - const int output = s["output"]; - + for (int channel_index = 0; channel_index < channels.size(); channel_index++) { + const Dictionary &anim_channel = channels[channel_index]; + ERR_FAIL_COND_V_MSG(!anim_channel.has("sampler"), ERR_PARSE_ERROR, "glTF: Animation channel missing required 'sampler' property."); + ERR_FAIL_COND_V_MSG(!anim_channel.has("target"), ERR_PARSE_ERROR, "glTF: Animation channel missing required 'target' property."); + // Parse sampler. + const int sampler_index = anim_channel["sampler"]; + ERR_FAIL_INDEX_V(sampler_index, samplers.size(), ERR_PARSE_ERROR); + const Dictionary &sampler_dict = samplers[sampler_index]; + ERR_FAIL_COND_V(!sampler_dict.has("input"), ERR_PARSE_ERROR); + ERR_FAIL_COND_V(!sampler_dict.has("output"), ERR_PARSE_ERROR); + const int input_time_accessor_index = sampler_dict["input"]; + const int output_value_accessor_index = sampler_dict["output"]; GLTFAnimation::Interpolation interp = GLTFAnimation::INTERP_LINEAR; int output_count = 1; - if (s.has("interpolation")) { - const String &in = s["interpolation"]; + if (sampler_dict.has("interpolation")) { + const String &in = sampler_dict["interpolation"]; if (in == "STEP") { interp = GLTFAnimation::INTERP_STEP; } else if (in == "LINEAR") { @@ -5032,52 +5475,83 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) { output_count = 3; } } + const Vector<double> times = _decode_accessor(p_state, input_time_accessor_index, false); + // Parse target. + const Dictionary &anim_target = anim_channel["target"]; + ERR_FAIL_COND_V_MSG(!anim_target.has("path"), ERR_PARSE_ERROR, "glTF: Animation channel target missing required 'path' property."); + String path = anim_target["path"]; + if (path == "pointer") { + ERR_FAIL_COND_V(!anim_target.has("extensions"), ERR_PARSE_ERROR); + Dictionary target_extensions = anim_target["extensions"]; + ERR_FAIL_COND_V(!target_extensions.has("KHR_animation_pointer"), ERR_PARSE_ERROR); + Dictionary khr_anim_ptr = target_extensions["KHR_animation_pointer"]; + ERR_FAIL_COND_V(!khr_anim_ptr.has("pointer"), ERR_PARSE_ERROR); + String anim_json_ptr = khr_anim_ptr["pointer"]; + _parse_animation_pointer(p_state, anim_json_ptr, animation, interp, times, output_value_accessor_index); + } else { + // If it's not a pointer, it's a regular animation channel from vanilla glTF (pos/rot/scale/weights). + if (!anim_target.has("node")) { + WARN_PRINT("glTF: Animation channel target missing 'node' property. Ignoring this channel."); + continue; + } - const Vector<float> times = _decode_accessor_as_floats(p_state, input, false); - if (path == "translation") { - const Vector<Vector3> positions = _decode_accessor_as_vec3(p_state, output, false); - track->position_track.interpolation = interp; - track->position_track.times = Variant(times); //convert via variant - track->position_track.values = Variant(positions); //convert via variant - } else if (path == "rotation") { - const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(p_state, output, false); - track->rotation_track.interpolation = interp; - track->rotation_track.times = Variant(times); //convert via variant - track->rotation_track.values = rotations; - } else if (path == "scale") { - const Vector<Vector3> scales = _decode_accessor_as_vec3(p_state, output, false); - track->scale_track.interpolation = interp; - track->scale_track.times = Variant(times); //convert via variant - track->scale_track.values = Variant(scales); //convert via variant - } else if (path == "weights") { - const Vector<float> weights = _decode_accessor_as_floats(p_state, output, false); - - ERR_FAIL_INDEX_V(p_state->nodes[node]->mesh, p_state->meshes.size(), ERR_PARSE_ERROR); - Ref<GLTFMesh> mesh = p_state->meshes[p_state->nodes[node]->mesh]; - ERR_CONTINUE(!mesh->get_blend_weights().size()); - const int wc = mesh->get_blend_weights().size(); - - track->weight_tracks.resize(wc); - - const int expected_value_count = times.size() * output_count * wc; - ERR_CONTINUE_MSG(weights.size() != expected_value_count, "Invalid weight data, expected " + itos(expected_value_count) + " weight values, got " + itos(weights.size()) + " instead."); - - const int wlen = weights.size() / wc; - for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea - GLTFAnimation::Channel<real_t> cf; - cf.interpolation = interp; - cf.times = Variant(times); - Vector<real_t> wdata; - wdata.resize(wlen); - for (int l = 0; l < wlen; l++) { - wdata.write[l] = weights[l * wc + k]; - } + GLTFNodeIndex node = anim_target["node"]; + + ERR_FAIL_INDEX_V(node, p_state->nodes.size(), ERR_PARSE_ERROR); - cf.values = wdata; - track->weight_tracks.write[k] = cf; + GLTFAnimation::NodeTrack *track = nullptr; + + if (!animation->get_node_tracks().has(node)) { + animation->get_node_tracks()[node] = GLTFAnimation::NodeTrack(); + } + + track = &animation->get_node_tracks()[node]; + + if (path == "translation") { + const Vector<Vector3> positions = _decode_accessor_as_vec3(p_state, output_value_accessor_index, false); + track->position_track.interpolation = interp; + track->position_track.times = times; + track->position_track.values = positions; + } else if (path == "rotation") { + const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(p_state, output_value_accessor_index, false); + track->rotation_track.interpolation = interp; + track->rotation_track.times = times; + track->rotation_track.values = rotations; + } else if (path == "scale") { + const Vector<Vector3> scales = _decode_accessor_as_vec3(p_state, output_value_accessor_index, false); + track->scale_track.interpolation = interp; + track->scale_track.times = times; + track->scale_track.values = scales; + } else if (path == "weights") { + const Vector<float> weights = _decode_accessor_as_floats(p_state, output_value_accessor_index, false); + + ERR_FAIL_INDEX_V(p_state->nodes[node]->mesh, p_state->meshes.size(), ERR_PARSE_ERROR); + Ref<GLTFMesh> mesh = p_state->meshes[p_state->nodes[node]->mesh]; + const int wc = mesh->get_blend_weights().size(); + ERR_CONTINUE_MSG(wc == 0, "glTF: Animation tried to animate weights, but mesh has no weights."); + + track->weight_tracks.resize(wc); + + const int expected_value_count = times.size() * output_count * wc; + ERR_CONTINUE_MSG(weights.size() != expected_value_count, "Invalid weight data, expected " + itos(expected_value_count) + " weight values, got " + itos(weights.size()) + " instead."); + + const int wlen = weights.size() / wc; + for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea + GLTFAnimation::Channel<real_t> cf; + cf.interpolation = interp; + cf.times = Variant(times); + Vector<real_t> wdata; + wdata.resize(wlen); + for (int l = 0; l < wlen; l++) { + wdata.write[l] = weights[l * wc + k]; + } + + cf.values = wdata; + track->weight_tracks.write[k] = cf; + } + } else { + WARN_PRINT("Invalid path '" + path + "'."); } - } else { - WARN_PRINT("Invalid path '" + path + "'."); } } @@ -5089,6 +5563,96 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> p_state) { return OK; } +void GLTFDocument::_parse_animation_pointer(Ref<GLTFState> p_state, const String &p_animation_json_pointer, const Ref<GLTFAnimation> p_gltf_animation, const GLTFAnimation::Interpolation p_interp, const Vector<double> &p_times, const int p_output_value_accessor_index) { + // Special case: Convert TRS animation pointers to node track pos/rot/scale. + // This is required to handle skeleton bones, and improves performance for regular nodes. + // Mark this as unlikely because TRS animation pointers are not recommended, + // since vanilla glTF animations can already animate TRS properties directly. + // But having this code exist is required to be spec-compliant and handle all test files. + // Note that TRS still needs to be handled in the general case as well, for KHR_interactivity. + const PackedStringArray split = p_animation_json_pointer.split("/", false, 3); + if (unlikely(split.size() == 3 && split[0] == "nodes" && (split[2] == "translation" || split[2] == "rotation" || split[2] == "scale" || split[2] == "matrix" || split[2] == "weights"))) { + const GLTFNodeIndex node_index = split[1].to_int(); + HashMap<int, GLTFAnimation::NodeTrack> &node_tracks = p_gltf_animation->get_node_tracks(); + if (!node_tracks.has(node_index)) { + node_tracks[node_index] = GLTFAnimation::NodeTrack(); + } + GLTFAnimation::NodeTrack *track = &node_tracks[node_index]; + if (split[2] == "translation") { + const Vector<Vector3> positions = _decode_accessor_as_vec3(p_state, p_output_value_accessor_index, false); + track->position_track.interpolation = p_interp; + track->position_track.times = p_times; + track->position_track.values = positions; + } else if (split[2] == "rotation") { + const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(p_state, p_output_value_accessor_index, false); + track->rotation_track.interpolation = p_interp; + track->rotation_track.times = p_times; + track->rotation_track.values = rotations; + } else if (split[2] == "scale") { + const Vector<Vector3> scales = _decode_accessor_as_vec3(p_state, p_output_value_accessor_index, false); + track->scale_track.interpolation = p_interp; + track->scale_track.times = p_times; + track->scale_track.values = scales; + } else if (split[2] == "matrix") { + const Vector<Transform3D> transforms = _decode_accessor_as_xform(p_state, p_output_value_accessor_index, false); + track->position_track.interpolation = p_interp; + track->position_track.times = p_times; + track->position_track.values.resize(transforms.size()); + track->rotation_track.interpolation = p_interp; + track->rotation_track.times = p_times; + track->rotation_track.values.resize(transforms.size()); + track->scale_track.interpolation = p_interp; + track->scale_track.times = p_times; + track->scale_track.values.resize(transforms.size()); + for (int i = 0; i < transforms.size(); i++) { + track->position_track.values.write[i] = transforms[i].get_origin(); + track->rotation_track.values.write[i] = transforms[i].basis.get_rotation_quaternion(); + track->scale_track.values.write[i] = transforms[i].basis.get_scale(); + } + } else { // if (split[2] == "weights") + const Vector<float> accessor_weights = _decode_accessor_as_floats(p_state, p_output_value_accessor_index, false); + const GLTFMeshIndex mesh_index = p_state->nodes[node_index]->mesh; + ERR_FAIL_INDEX(mesh_index, p_state->meshes.size()); + const Ref<GLTFMesh> gltf_mesh = p_state->meshes[mesh_index]; + const Vector<float> &blend_weights = gltf_mesh->get_blend_weights(); + const int blend_weight_count = gltf_mesh->get_blend_weights().size(); + const int anim_weights_size = accessor_weights.size(); + // For example, if a mesh has 2 blend weights, and the accessor provides 10 values, then there are 5 frames of animation, each with 2 blend weights. + ERR_FAIL_COND_MSG(blend_weight_count == 0 || ((anim_weights_size % blend_weight_count) != 0), "glTF: Cannot apply " + itos(accessor_weights.size()) + " weights to a mesh with " + itos(blend_weights.size()) + " blend weights."); + const int frame_count = anim_weights_size / blend_weight_count; + track->weight_tracks.resize(blend_weight_count); + for (int blend_weight_index = 0; blend_weight_index < blend_weight_count; blend_weight_index++) { + GLTFAnimation::Channel<real_t> weight_track; + weight_track.interpolation = p_interp; + weight_track.times = p_times; + weight_track.values.resize(frame_count); + for (int frame_index = 0; frame_index < frame_count; frame_index++) { + // For example, if a mesh has 2 blend weights, and the accessor provides 10 values, + // then the first frame has indices [0, 1], the second frame has [2, 3], and so on. + // Here we process all frames of one blend weight, so we want [0, 2, 4, 6, 8] or [1, 3, 5, 7, 9]. + // For the fist one we calculate 0 * 2 + 0, 1 * 2 + 0, 2 * 2 + 0, etc, then for the second 0 * 2 + 1, 1 * 2 + 1, 2 * 2 + 1, etc. + weight_track.values.write[frame_index] = accessor_weights[frame_index * blend_weight_count + blend_weight_index]; + } + track->weight_tracks.write[blend_weight_index] = weight_track; + } + } + // The special case was handled, return to skip the general case. + return; + } + // General case: Convert animation pointers to Variant value pointer tracks. + Ref<GLTFObjectModelProperty> obj_model_prop = import_object_model_property(p_state, p_animation_json_pointer); + if (obj_model_prop.is_null() || !obj_model_prop->has_node_paths()) { + // Exit quietly, `import_object_model_property` already prints a warning if the property is not found. + return; + } + HashMap<String, GLTFAnimation::Channel<Variant>> &anim_ptr_map = p_gltf_animation->get_pointer_tracks(); + GLTFAnimation::Channel<Variant> channel; + channel.interpolation = p_interp; + channel.times = p_times; + channel.values = _decode_accessor_as_variant(p_state, p_output_value_accessor_index, obj_model_prop->get_variant_type(), obj_model_prop->get_accessor_type()); + anim_ptr_map[p_animation_json_pointer] = channel; +} + void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) { for (int i = 0; i < p_state->nodes.size(); i++) { Ref<GLTFNode> gltf_node = p_state->nodes[i]; @@ -5254,46 +5818,46 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> p_state, Node *p_current, gltf_node->set_original_name(p_current->get_name()); gltf_node->set_name(_gen_unique_name(p_state, p_current->get_name())); gltf_node->merge_meta_from(p_current); - if (cast_to<Node3D>(p_current)) { - Node3D *spatial = cast_to<Node3D>(p_current); + if (Object::cast_to<Node3D>(p_current)) { + Node3D *spatial = Object::cast_to<Node3D>(p_current); _convert_spatial(p_state, spatial, gltf_node); } - if (cast_to<MeshInstance3D>(p_current)) { - MeshInstance3D *mi = cast_to<MeshInstance3D>(p_current); + if (Object::cast_to<MeshInstance3D>(p_current)) { + MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_current); _convert_mesh_instance_to_gltf(mi, p_state, gltf_node); - } else if (cast_to<BoneAttachment3D>(p_current)) { - BoneAttachment3D *bone = cast_to<BoneAttachment3D>(p_current); + } else if (Object::cast_to<BoneAttachment3D>(p_current)) { + BoneAttachment3D *bone = Object::cast_to<BoneAttachment3D>(p_current); _convert_bone_attachment_to_gltf(bone, p_state, p_gltf_parent, p_gltf_root, gltf_node); return; - } else if (cast_to<Skeleton3D>(p_current)) { - Skeleton3D *skel = cast_to<Skeleton3D>(p_current); + } else if (Object::cast_to<Skeleton3D>(p_current)) { + Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_current); _convert_skeleton_to_gltf(skel, p_state, p_gltf_parent, p_gltf_root, gltf_node); // We ignore the Godot Engine node that is the skeleton. return; - } else if (cast_to<MultiMeshInstance3D>(p_current)) { - MultiMeshInstance3D *multi = cast_to<MultiMeshInstance3D>(p_current); + } else if (Object::cast_to<MultiMeshInstance3D>(p_current)) { + MultiMeshInstance3D *multi = Object::cast_to<MultiMeshInstance3D>(p_current); _convert_multi_mesh_instance_to_gltf(multi, p_gltf_parent, p_gltf_root, gltf_node, p_state); #ifdef MODULE_CSG_ENABLED - } else if (cast_to<CSGShape3D>(p_current)) { - CSGShape3D *shape = cast_to<CSGShape3D>(p_current); + } else if (Object::cast_to<CSGShape3D>(p_current)) { + CSGShape3D *shape = Object::cast_to<CSGShape3D>(p_current); if (shape->get_parent() && shape->is_root_shape()) { _convert_csg_shape_to_gltf(shape, p_gltf_parent, gltf_node, p_state); } #endif // MODULE_CSG_ENABLED #ifdef MODULE_GRIDMAP_ENABLED - } else if (cast_to<GridMap>(p_current)) { + } else if (Object::cast_to<GridMap>(p_current)) { GridMap *gridmap = Object::cast_to<GridMap>(p_current); _convert_grid_map_to_gltf(gridmap, p_gltf_parent, p_gltf_root, gltf_node, p_state); #endif // MODULE_GRIDMAP_ENABLED - } else if (cast_to<Camera3D>(p_current)) { + } else if (Object::cast_to<Camera3D>(p_current)) { Camera3D *camera = Object::cast_to<Camera3D>(p_current); _convert_camera_to_gltf(camera, p_state, gltf_node); - } else if (cast_to<Light3D>(p_current)) { + } else if (Object::cast_to<Light3D>(p_current)) { Light3D *light = Object::cast_to<Light3D>(p_current); _convert_light_to_gltf(light, p_state, gltf_node); - } else if (cast_to<AnimationPlayer>(p_current)) { + } else if (Object::cast_to<AnimationPlayer>(p_current)) { AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current); - _convert_animation_player_to_gltf(animation_player, p_state, p_gltf_parent, p_gltf_root, gltf_node, p_current); + p_state->animation_players.push_back(animation_player); } for (Ref<GLTFDocumentExtension> ext : document_extensions) { ERR_CONTINUE(ext.is_null()); @@ -5371,12 +5935,6 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd } #endif // MODULE_CSG_ENABLED -void GLTFDocument::_convert_animation_player_to_gltf(AnimationPlayer *p_animation_player, Ref<GLTFState> p_state, GLTFNodeIndex p_gltf_current, GLTFNodeIndex p_gltf_root_index, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) { - ERR_FAIL_NULL(p_animation_player); - p_state->animation_players.push_back(p_animation_player); - print_verbose(String("glTF: Converting animation player: ") + p_animation_player->get_name()); -} - void GLTFDocument::_check_visibility(Node *p_node, bool &r_retflag) { r_retflag = true; Node3D *spatial = Object::cast_to<Node3D>(p_node); @@ -5569,9 +6127,9 @@ void GLTFDocument::_convert_bone_attachment_to_gltf(BoneAttachment3D *p_bone_att Skeleton3D *skeleton; // Note that relative transforms to external skeletons and pose overrides are not supported. if (p_bone_attachment->get_use_external_skeleton()) { - skeleton = cast_to<Skeleton3D>(p_bone_attachment->get_node_or_null(p_bone_attachment->get_external_skeleton())); + skeleton = Object::cast_to<Skeleton3D>(p_bone_attachment->get_node_or_null(p_bone_attachment->get_external_skeleton())); } else { - skeleton = cast_to<Skeleton3D>(p_bone_attachment->get_parent()); + skeleton = Object::cast_to<Skeleton3D>(p_bone_attachment->get_parent()); } GLTFSkeletonIndex skel_gltf_i = -1; if (skeleton != nullptr && p_state->skeleton3d_to_gltf_skeleton.has(skeleton->get_instance_id())) { @@ -5854,7 +6412,7 @@ struct SceneFormatImporterGLTFInterpolate<Quaternion> { }; template <typename T> -T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { +T GLTFDocument::_interpolate_track(const Vector<double> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { ERR_FAIL_COND_V(p_values.is_empty(), T()); if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) { ERR_PRINT_ONCE("The interpolated values are not corresponding to its times."); @@ -5925,8 +6483,433 @@ T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T ERR_FAIL_V(p_values[0]); } +NodePath GLTFDocument::_find_material_node_path(Ref<GLTFState> p_state, Ref<Material> p_material) { + int mesh_index = 0; + for (Ref<GLTFMesh> gltf_mesh : p_state->meshes) { + TypedArray<Material> materials = gltf_mesh->get_instance_materials(); + for (int mat_index = 0; mat_index < materials.size(); mat_index++) { + if (materials[mat_index] == p_material) { + for (Ref<GLTFNode> gltf_node : p_state->nodes) { + if (gltf_node->mesh == mesh_index) { + NodePath node_path = gltf_node->get_scene_node_path(p_state); + // Example: MyNode:mesh:surface_0/material:albedo_color, so we want the mesh:surface_0/material part. + Vector<StringName> subpath; + subpath.append("mesh"); + subpath.append("surface_" + itos(mat_index) + "/material"); + return NodePath(node_path.get_names(), subpath, false); + } + } + } + } + mesh_index++; + } + return NodePath(); +} + +Ref<GLTFObjectModelProperty> GLTFDocument::import_object_model_property(Ref<GLTFState> p_state, const String &p_json_pointer) { + if (p_state->object_model_properties.has(p_json_pointer)) { + return p_state->object_model_properties[p_json_pointer]; + } + Ref<GLTFObjectModelProperty> ret; + // Split the JSON pointer into its components. + const PackedStringArray split = p_json_pointer.split("/", false); + ERR_FAIL_COND_V_MSG(split.size() < 3, ret, "glTF: Cannot use JSON pointer '" + p_json_pointer + "' because it does not contain enough elements. The only animatable properties are at least 3 levels deep (ex: '/nodes/0/translation' or '/materials/0/emissiveFactor')."); + ret.instantiate(); + ret->set_json_pointers({ split }); + // Partial paths are passed to GLTFDocumentExtension classes if GLTFDocument cannot handle a given JSON pointer. + TypedArray<NodePath> partial_paths; + // Note: This might not be an integer, but in that case, we don't use this value anyway. + const int top_level_index = split[1].to_int(); + // For JSON pointers present in the core glTF Object Model, hard-code them in GLTFDocument. + // https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc + if (split[0] == "nodes") { + ERR_FAIL_INDEX_V_MSG(top_level_index, p_state->nodes.size(), ret, vformat("glTF: Unable to find node %d for JSON pointer '%s'.", top_level_index, p_json_pointer)); + Ref<GLTFNode> pointed_gltf_node = p_state->nodes[top_level_index]; + NodePath node_path = pointed_gltf_node->get_scene_node_path(p_state); + partial_paths.append(node_path); + // Check if it's something we should be able to handle. + const String &node_prop = split[2]; + if (node_prop == "translation") { + ret->append_path_to_property(node_path, "position"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (node_prop == "rotation") { + ret->append_path_to_property(node_path, "quaternion"); + ret->set_types(Variant::QUATERNION, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4); + } else if (node_prop == "scale") { + ret->append_path_to_property(node_path, "scale"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (node_prop == "matrix") { + ret->append_path_to_property(node_path, "transform"); + ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4); + } else if (node_prop == "globalMatrix") { + ret->append_path_to_property(node_path, "global_transform"); + ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4); + } else if (node_prop == "weights") { + if (split.size() > 3) { + const String &weight_index_string = split[3]; + ret->append_path_to_property(node_path, "blend_shapes/morph_" + weight_index_string); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } + // Else, Godot's MeshInstance3D does not expose the blend shape weights as one property. + // But that's fine, we handle this case in _parse_animation_pointer instead. + } + } else if (split[0] == "cameras") { + const String &camera_prop = split[2]; + for (Ref<GLTFNode> gltf_node : p_state->nodes) { + if (gltf_node->camera == top_level_index) { + NodePath node_path = gltf_node->get_scene_node_path(p_state); + partial_paths.append(node_path); + // Check if it's something we should be able to handle. + if (camera_prop == "orthographic" || camera_prop == "perspective") { + ERR_FAIL_COND_V(split.size() < 4, ret); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + const String &sub_prop = split[3]; + if (sub_prop == "xmag" || sub_prop == "ymag") { + ret->append_path_to_property(node_path, "size"); + } else if (sub_prop == "yfov") { + ret->append_path_to_property(node_path, "fov"); + GLTFCamera::set_fov_conversion_expressions(ret); + } else if (sub_prop == "zfar") { + ret->append_path_to_property(node_path, "far"); + } else if (sub_prop == "znear") { + ret->append_path_to_property(node_path, "near"); + } + } + } + } + } else if (split[0] == "materials") { + ERR_FAIL_INDEX_V_MSG(top_level_index, p_state->materials.size(), ret, vformat("glTF: Unable to find material %d for JSON pointer '%s'.", top_level_index, p_json_pointer)); + Ref<Material> pointed_material = p_state->materials[top_level_index]; + NodePath mat_path = _find_material_node_path(p_state, pointed_material); + if (mat_path.is_empty()) { + WARN_PRINT(vformat("glTF: Unable to find a path to the material %d for JSON pointer '%s'. This is likely bad data but it's also possible this is intentional. Continuing anyway.", top_level_index, p_json_pointer)); + } else { + partial_paths.append(mat_path); + const String &mat_prop = split[2]; + if (mat_prop == "alphaCutoff") { + ret->append_path_to_property(mat_path, "alpha_scissor_threshold"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (mat_prop == "emissiveFactor") { + ret->append_path_to_property(mat_path, "emission"); + ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (mat_prop == "extensions") { + ERR_FAIL_COND_V(split.size() < 5, ret); + const String &ext_name = split[3]; + const String &ext_prop = split[4]; + if (ext_name == "KHR_materials_emissive_strength" && ext_prop == "emissiveStrength") { + ret->append_path_to_property(mat_path, "emission_energy_multiplier"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } + } else { + ERR_FAIL_COND_V(split.size() < 4, ret); + const String &sub_prop = split[3]; + if (mat_prop == "normalTexture") { + if (sub_prop == "scale") { + ret->append_path_to_property(mat_path, "normal_scale"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } + } else if (mat_prop == "occlusionTexture") { + if (sub_prop == "strength") { + // This is the closest thing Godot has to an occlusion strength property. + ret->append_path_to_property(mat_path, "ao_light_affect"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } + } else if (mat_prop == "pbrMetallicRoughness") { + if (sub_prop == "baseColorFactor") { + ret->append_path_to_property(mat_path, "albedo_color"); + ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4); + } else if (sub_prop == "metallicFactor") { + ret->append_path_to_property(mat_path, "metallic"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (sub_prop == "roughnessFactor") { + ret->append_path_to_property(mat_path, "roughness"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (sub_prop == "baseColorTexture") { + ERR_FAIL_COND_V(split.size() < 6, ret); + const String &tex_ext_dict = split[4]; + const String &tex_ext_name = split[5]; + const String &tex_ext_prop = split[6]; + if (tex_ext_dict == "extensions" && tex_ext_name == "KHR_texture_transform") { + // Godot only supports UVs for the whole material, not per texture. + // We treat the albedo texture as the main texture, and import as UV1. + // Godot does not support texture rotation, only offset and scale. + if (tex_ext_prop == "offset") { + ret->append_path_to_property(mat_path, "uv1_offset"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT2); + } else if (tex_ext_prop == "scale") { + ret->append_path_to_property(mat_path, "uv1_scale"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT2); + } + } + } + } + } + } + } else if (split[0] == "meshes") { + for (Ref<GLTFNode> gltf_node : p_state->nodes) { + if (gltf_node->mesh == top_level_index) { + NodePath node_path = gltf_node->get_scene_node_path(p_state); + Vector<StringName> subpath; + subpath.append("mesh"); + partial_paths.append(NodePath(node_path.get_names(), subpath, false)); + break; + } + } + } else if (split[0] == "extensions") { + if (split[1] == "KHR_lights_punctual" && split[2] == "lights" && split.size() > 4) { + const int light_index = split[3].to_int(); + ERR_FAIL_INDEX_V_MSG(light_index, p_state->lights.size(), ret, vformat("glTF: Unable to find light %d for JSON pointer '%s'.", light_index, p_json_pointer)); + const String &light_prop = split[4]; + const Ref<GLTFLight> pointed_light = p_state->lights[light_index]; + for (Ref<GLTFNode> gltf_node : p_state->nodes) { + if (gltf_node->light == light_index) { + NodePath node_path = gltf_node->get_scene_node_path(p_state); + partial_paths.append(node_path); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + // Check if it's something we should be able to handle. + if (light_prop == "color") { + ret->append_path_to_property(node_path, "light_color"); + ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (light_prop == "intensity") { + ret->append_path_to_property(node_path, "light_energy"); + } else if (light_prop == "range") { + const String &light_type = p_state->lights[light_index]->light_type; + if (light_type == "spot") { + ret->append_path_to_property(node_path, "spot_range"); + } else { + ret->append_path_to_property(node_path, "omni_range"); + } + } else if (light_prop == "spot") { + ERR_FAIL_COND_V(split.size() < 6, ret); + const String &sub_prop = split[5]; + if (sub_prop == "innerConeAngle") { + ret->append_path_to_property(node_path, "spot_angle_attenuation"); + GLTFLight::set_cone_inner_attenuation_conversion_expressions(ret); + } else if (sub_prop == "outerConeAngle") { + ret->append_path_to_property(node_path, "spot_angle"); + } + } + } + } + } + } + // Additional JSON pointers can be added by GLTFDocumentExtension classes. + // We only need this if no mapping has been found yet from GLTFDocument's internal code. + // When available, we pass the partial paths to the extension to help it generate the full path. + // For example, for `/nodes/3/extensions/MY_ext/prop`, we pass a NodePath that leads to node 3, + // so the GLTFDocumentExtension class only needs to resolve the last `MY_ext/prop` part of the path. + // It should check `split.size() > 4 and split[0] == "nodes" and split[2] == "extensions" and split[3] == "MY_ext"` + // at the start of the function to check if this JSON pointer applies to it, then it can handle `split[4]`. + if (!ret->has_node_paths()) { + for (Ref<GLTFDocumentExtension> ext : all_document_extensions) { + ret = ext->import_object_model_property(p_state, split, partial_paths); + if (ret.is_valid() && ret->has_node_paths()) { + if (!ret->has_json_pointers()) { + ret->set_json_pointers({ split }); + } + break; + } + } + if (ret.is_null() || !ret->has_node_paths()) { + if (split.has("KHR_texture_transform")) { + WARN_VERBOSE(vformat("glTF: Texture transforms are only supported per material in Godot. All KHR_texture_transform properties will be ignored except for the albedo texture. Ignoring JSON pointer '%s'.", p_json_pointer)); + } else { + WARN_PRINT(vformat("glTF: Animation contained JSON pointer '%s' which could not be resolved. This property will not be animated.", p_json_pointer)); + } + } + } + p_state->object_model_properties[p_json_pointer] = ret; + return ret; +} + +Ref<GLTFObjectModelProperty> GLTFDocument::export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index) { + Ref<GLTFObjectModelProperty> ret; + const Object *target_object = p_godot_node; + const Vector<StringName> subpath = p_node_path.get_subnames(); + ERR_FAIL_COND_V_MSG(subpath.is_empty(), ret, "glTF: Cannot export empty property. No property was specified in the NodePath: " + p_node_path); + int target_prop_depth = 0; + for (StringName subname : subpath) { + Variant target_property = target_object->get(subname); + if (target_property.get_type() == Variant::OBJECT) { + target_object = target_property; + if (target_object) { + target_prop_depth++; + continue; + } + } + break; + } + const String &target_prop = subpath[target_prop_depth]; + ret.instantiate(); + ret->set_node_paths({ p_node_path }); + Vector<PackedStringArray> split_json_pointers; + PackedStringArray split_json_pointer; + if (Object::cast_to<BaseMaterial3D>(target_object)) { + for (int i = 0; i < p_state->materials.size(); i++) { + if (p_state->materials[i].ptr() == target_object) { + split_json_pointer.append("materials"); + split_json_pointer.append(itos(i)); + if (target_prop == "alpha_scissor_threshold") { + split_json_pointer.append("alphaCutoff"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (target_prop == "emission") { + split_json_pointer.append("emissiveFactor"); + ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (target_prop == "emission_energy_multiplier") { + split_json_pointer.append("extensions"); + split_json_pointer.append("KHR_materials_emissive_strength"); + split_json_pointer.append("emissiveStrength"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (target_prop == "normal_scale") { + split_json_pointer.append("normalTexture"); + split_json_pointer.append("scale"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (target_prop == "ao_light_affect") { + split_json_pointer.append("occlusionTexture"); + split_json_pointer.append("strength"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (target_prop == "albedo_color") { + split_json_pointer.append("pbrMetallicRoughness"); + split_json_pointer.append("baseColorFactor"); + ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4); + } else if (target_prop == "metallic") { + split_json_pointer.append("pbrMetallicRoughness"); + split_json_pointer.append("metallicFactor"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (target_prop == "roughness") { + split_json_pointer.append("pbrMetallicRoughness"); + split_json_pointer.append("roughnessFactor"); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + } else if (target_prop == "uv1_offset" || target_prop == "uv1_scale") { + split_json_pointer.append("pbrMetallicRoughness"); + split_json_pointer.append("baseColorTexture"); + split_json_pointer.append("extensions"); + split_json_pointer.append("KHR_texture_transform"); + if (target_prop == "uv1_offset") { + split_json_pointer.append("offset"); + } else { + split_json_pointer.append("scale"); + } + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT2); + } else { + split_json_pointer.clear(); + } + break; + } + } + } else { + // Properties directly on Godot nodes. + Ref<GLTFNode> gltf_node = p_state->nodes[p_gltf_node_index]; + if (Object::cast_to<Camera3D>(target_object) && gltf_node->camera >= 0) { + split_json_pointer.append("cameras"); + split_json_pointer.append(itos(gltf_node->camera)); + const Camera3D *camera_node = Object::cast_to<Camera3D>(target_object); + const Camera3D::ProjectionType projection_type = camera_node->get_projection(); + if (projection_type == Camera3D::PROJECTION_PERSPECTIVE) { + split_json_pointer.append("perspective"); + } else { + split_json_pointer.append("orthographic"); + } + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + if (target_prop == "size") { + PackedStringArray xmag = split_json_pointer.duplicate(); + xmag.append("xmag"); + split_json_pointers.append(xmag); + split_json_pointer.append("ymag"); + } else if (target_prop == "fov") { + split_json_pointer.append("yfov"); + GLTFCamera::set_fov_conversion_expressions(ret); + } else if (target_prop == "far") { + split_json_pointer.append("zfar"); + } else if (target_prop == "near") { + split_json_pointer.append("znear"); + } else { + split_json_pointer.clear(); + } + } else if (Object::cast_to<Light3D>(target_object) && gltf_node->light >= 0) { + split_json_pointer.append("extensions"); + split_json_pointer.append("KHR_lights_punctual"); + split_json_pointer.append("lights"); + split_json_pointer.append(itos(gltf_node->light)); + ret->set_types(Variant::FLOAT, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT); + if (target_prop == "light_color") { + split_json_pointer.append("color"); + ret->set_types(Variant::COLOR, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (target_prop == "light_energy") { + split_json_pointer.append("intensity"); + } else if (target_prop == "spot_range") { + split_json_pointer.append("range"); + } else if (target_prop == "omni_range") { + split_json_pointer.append("range"); + } else if (target_prop == "spot_angle") { + split_json_pointer.append("spot"); + split_json_pointer.append("outerConeAngle"); + } else if (target_prop == "spot_angle_attenuation") { + split_json_pointer.append("spot"); + split_json_pointer.append("innerConeAngle"); + GLTFLight::set_cone_inner_attenuation_conversion_expressions(ret); + } else { + split_json_pointer.clear(); + } + } else if (Object::cast_to<MeshInstance3D>(target_object) && target_prop.begins_with("blend_shapes/morph_")) { + const String &weight_index_string = target_prop.trim_prefix("blend_shapes/morph_"); + split_json_pointer.append("nodes"); + split_json_pointer.append(itos(p_gltf_node_index)); + split_json_pointer.append("weights"); + split_json_pointer.append(weight_index_string); + } + // Transform properties. Check for all 3D nodes if we haven't resolved the JSON pointer yet. + // Note: Do not put this in an `else`, because otherwise this will not be reached. + if (split_json_pointer.is_empty() && Object::cast_to<Node3D>(target_object)) { + split_json_pointer.append("nodes"); + split_json_pointer.append(itos(p_gltf_node_index)); + if (target_prop == "position") { + split_json_pointer.append("translation"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (target_prop == "quaternion") { + // Note: Only Quaternion rotation can be converted from Godot in this mapping. + // Struct methods like from_euler are not accessible from the Expression class. :( + split_json_pointer.append("rotation"); + ret->set_types(Variant::QUATERNION, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4); + } else if (target_prop == "scale") { + split_json_pointer.append("scale"); + ret->set_types(Variant::VECTOR3, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT3); + } else if (target_prop == "transform") { + split_json_pointer.append("matrix"); + ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4); + } else if (target_prop == "global_transform") { + split_json_pointer.append("globalMatrix"); + ret->set_types(Variant::TRANSFORM3D, GLTFObjectModelProperty::GLTF_OBJECT_MODEL_TYPE_FLOAT4X4); + } else { + split_json_pointer.clear(); + } + } + } + // Additional JSON pointers can be added by GLTFDocumentExtension classes. + // We only need this if no mapping has been found yet from GLTFDocument's internal code. + // We pass as many pieces of information as we can to the extension to give it lots of context. + if (split_json_pointer.is_empty()) { + for (Ref<GLTFDocumentExtension> ext : all_document_extensions) { + ret = ext->export_object_model_property(p_state, p_node_path, p_godot_node, p_gltf_node_index, target_object, target_prop_depth); + if (ret.is_valid() && ret->has_json_pointers()) { + if (!ret->has_node_paths()) { + ret->set_node_paths({ p_node_path }); + } + break; + } + } + } else { + // GLTFDocument's internal code found a mapping, so set it and return it. + split_json_pointers.append(split_json_pointer); + ret->set_json_pointers(split_json_pointers); + } + return ret; +} + void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks) { ERR_FAIL_COND(p_state.is_null()); + Node *scene_root = p_animation_player->get_parent(); + ERR_FAIL_NULL(scene_root); Ref<GLTFAnimation> anim = p_state->animations[p_index]; String anim_name = anim->get_name(); @@ -5947,8 +6930,8 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_ double anim_start = p_trimming ? INFINITY : 0.0; double anim_end = 0.0; - for (const KeyValue<int, GLTFAnimation::Track> &track_i : anim->get_tracks()) { - const GLTFAnimation::Track &track = track_i.value; + for (const KeyValue<int, GLTFAnimation::NodeTrack> &track_i : anim->get_node_tracks()) { + const GLTFAnimation::NodeTrack &track = track_i.value; //need to find the path: for skeletons, weight tracks will affect the mesh NodePath node_path; //for skeletons, transform tracks always affect bones @@ -5960,14 +6943,12 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_ const Ref<GLTFNode> gltf_node = p_state->nodes[track_i.key]; - Node *root = p_animation_player->get_parent(); - ERR_FAIL_NULL(root); HashMap<GLTFNodeIndex, Node *>::Iterator node_element = p_state->scene_nodes.find(node_index); ERR_CONTINUE_MSG(!node_element, vformat("Unable to find node %d for animation.", node_index)); - node_path = root->get_path_to(node_element->value); + node_path = scene_root->get_path_to(node_element->value); HashMap<GLTFNodeIndex, ImporterMeshInstance3D *>::Iterator mesh_instance_element = p_state->scene_mesh_instances.find(node_index); if (mesh_instance_element) { - mesh_instance_node_path = root->get_path_to(mesh_instance_element->value); + mesh_instance_node_path = scene_root->get_path_to(mesh_instance_element->value); } else { mesh_instance_node_path = node_path; } @@ -6201,6 +7182,56 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_ } } + for (const KeyValue<String, GLTFAnimation::Channel<Variant>> &track_iter : anim->get_pointer_tracks()) { + // Determine the property to animate. + const String json_pointer = track_iter.key; + const Ref<GLTFObjectModelProperty> prop = import_object_model_property(p_state, json_pointer); + ERR_FAIL_COND(prop.is_null()); + // Adjust the animation duration to encompass all keyframes. + const GLTFAnimation::Channel<Variant> &channel = track_iter.value; + ERR_CONTINUE_MSG(channel.times.size() != channel.values.size(), vformat("glTF: Animation pointer '%s' has mismatched keyframe times and values.", json_pointer)); + if (p_trimming) { + for (int i = 0; i < channel.times.size(); i++) { + anim_start = MIN(anim_start, channel.times[i]); + anim_end = MAX(anim_end, channel.times[i]); + } + } else { + for (int i = 0; i < channel.times.size(); i++) { + anim_end = MAX(anim_end, channel.times[i]); + } + } + // Begin converting the glTF animation to a Godot animation. + const Ref<Expression> gltf_to_godot_expr = prop->get_gltf_to_godot_expression(); + const bool is_gltf_to_godot_expr_valid = gltf_to_godot_expr.is_valid(); + for (const NodePath node_path : prop->get_node_paths()) { + // If using an expression, determine the base instance to pass to the expression. + Object *base_instance = nullptr; + if (is_gltf_to_godot_expr_valid) { + Ref<Resource> resource; + Vector<StringName> leftover_subpath; + base_instance = scene_root->get_node_and_resource(node_path, resource, leftover_subpath); + if (resource.is_valid()) { + base_instance = resource.ptr(); + } + } + // Add a track and insert all keys and values. + const int track_index = animation->get_track_count(); + animation->add_track(Animation::TYPE_VALUE); + animation->track_set_interpolation_type(track_index, GLTFAnimation::gltf_to_godot_interpolation(channel.interpolation)); + animation->track_set_path(track_index, node_path); + for (int i = 0; i < channel.times.size(); i++) { + const double time = channel.times[i]; + Variant value = channel.values[i]; + if (is_gltf_to_godot_expr_valid) { + Array inputs; + inputs.append(value); + value = gltf_to_godot_expr->execute(inputs, base_instance); + } + animation->track_insert_key(track_index, time, value); + } + } + } + animation->set_length(anim_end - anim_start); Ref<AnimationLibrary> library; @@ -6371,41 +7402,56 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene } } -GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, int32_t p_track_i, GLTFNodeIndex p_node_i) { - Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i); - - GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - if (interpolation == Animation::InterpolationType::INTERPOLATION_LINEAR) { - gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - } else if (interpolation == Animation::InterpolationType::INTERPOLATION_NEAREST) { - gltf_interpolation = GLTFAnimation::INTERP_STEP; - } else if (interpolation == Animation::InterpolationType::INTERPOLATION_CUBIC) { - gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE; +GLTFNodeIndex GLTFDocument::_node_and_or_bone_to_gltf_node_index(Ref<GLTFState> p_state, const Vector<StringName> &p_node_subpath, const Node *p_godot_node) { + const Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_godot_node); + if (skeleton && p_node_subpath.size() == 1) { + // Special case: Handle skeleton bone TRS tracks. They use the format `A/B/C/Skeleton3D:bone_name`. + // We have a Skeleton3D, check if it has a bone with the same name as this subpath. + const String &bone_name = p_node_subpath[0]; + const int32_t bone_index = skeleton->find_bone(bone_name); + if (bone_index != -1) { + // A bone was found! But we still need to figure out which glTF node it corresponds to. + for (GLTFSkeletonIndex skeleton_i = 0; skeleton_i < p_state->skeletons.size(); skeleton_i++) { + const Ref<GLTFSkeleton> &skeleton_gltf = p_state->skeletons[skeleton_i]; + if (skeleton == skeleton_gltf->godot_skeleton) { + GLTFNodeIndex node_i = skeleton_gltf->godot_bone_node[bone_index]; + return node_i; + } + } + ERR_FAIL_V_MSG(-1, vformat("glTF: Found a bone %s in a Skeleton3D that wasn't in the GLTFState. Ensure that all nodes referenced by the AnimationPlayer are in the scene you are exporting.", bone_name)); + } } - Animation::TrackType track_type = p_animation->track_get_type(p_track_i); - int32_t key_count = p_animation->track_get_key_count(p_track_i); - Vector<real_t> times; - times.resize(key_count); - String path = p_animation->track_get_path(p_track_i); - for (int32_t key_i = 0; key_i < key_count; key_i++) { - times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i); + // General case: Not a skeleton bone, usually this means a normal node, or it could be the Skeleton3D itself. + for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : p_state->scene_nodes) { + if (scene_node_i.value == p_godot_node) { + return scene_node_i.key; + } } - double anim_end = p_animation->get_length(); + ERR_FAIL_V_MSG(-1, vformat("glTF: A node was animated, but it wasn't found in the GLTFState. Ensure that all nodes referenced by the AnimationPlayer are in the scene you are exporting.")); +} + +bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAnimation::NodeTrack &p_gltf_node_track, const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index, Vector<double> &p_times) { + GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::godot_to_gltf_interpolation(p_godot_animation, p_godot_anim_track_index); + const Animation::TrackType track_type = p_godot_animation->track_get_type(p_godot_anim_track_index); + const int32_t key_count = p_godot_animation->track_get_key_count(p_godot_anim_track_index); + const NodePath node_path = p_godot_animation->track_get_path(p_godot_anim_track_index); + const Vector<StringName> subpath = node_path.get_subnames(); + double anim_end = p_godot_animation->get_length(); if (track_type == Animation::TYPE_SCALE_3D) { if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - p_track.scale_track.times.clear(); - p_track.scale_track.values.clear(); + p_gltf_node_track.scale_track.times.clear(); + p_gltf_node_track.scale_track.values.clear(); // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. const double increment = 1.0 / p_state->get_bake_fps(); double time = 0.0; bool last = false; while (true) { Vector3 scale; - Error err = p_animation->try_scale_track_interpolate(p_track_i, time, &scale); + Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); ERR_CONTINUE(err != OK); - p_track.scale_track.values.push_back(scale); - p_track.scale_track.times.push_back(time); + p_gltf_node_track.scale_track.values.push_back(scale); + p_gltf_node_track.scale_track.times.push_back(time); if (last) { break; } @@ -6416,31 +7462,31 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta } } } else { - p_track.scale_track.times = times; - p_track.scale_track.interpolation = gltf_interpolation; - p_track.scale_track.values.resize(key_count); + p_gltf_node_track.scale_track.times = p_times; + p_gltf_node_track.scale_track.interpolation = gltf_interpolation; + p_gltf_node_track.scale_track.values.resize(key_count); for (int32_t key_i = 0; key_i < key_count; key_i++) { Vector3 scale; - Error err = p_animation->scale_track_get_key(p_track_i, key_i, &scale); + Error err = p_godot_animation->scale_track_get_key(p_godot_anim_track_index, key_i, &scale); ERR_CONTINUE(err != OK); - p_track.scale_track.values.write[key_i] = scale; + p_gltf_node_track.scale_track.values.write[key_i] = scale; } } } else if (track_type == Animation::TYPE_POSITION_3D) { if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - p_track.position_track.times.clear(); - p_track.position_track.values.clear(); + p_gltf_node_track.position_track.times.clear(); + p_gltf_node_track.position_track.values.clear(); // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. const double increment = 1.0 / p_state->get_bake_fps(); double time = 0.0; bool last = false; while (true) { Vector3 scale; - Error err = p_animation->try_position_track_interpolate(p_track_i, time, &scale); + Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &scale); ERR_CONTINUE(err != OK); - p_track.position_track.values.push_back(scale); - p_track.position_track.times.push_back(time); + p_gltf_node_track.position_track.values.push_back(scale); + p_gltf_node_track.position_track.times.push_back(time); if (last) { break; } @@ -6451,31 +7497,31 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta } } } else { - p_track.position_track.times = times; - p_track.position_track.values.resize(key_count); - p_track.position_track.interpolation = gltf_interpolation; + p_gltf_node_track.position_track.times = p_times; + p_gltf_node_track.position_track.values.resize(key_count); + p_gltf_node_track.position_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { Vector3 position; - Error err = p_animation->position_track_get_key(p_track_i, key_i, &position); + Error err = p_godot_animation->position_track_get_key(p_godot_anim_track_index, key_i, &position); ERR_CONTINUE(err != OK); - p_track.position_track.values.write[key_i] = position; + p_gltf_node_track.position_track.values.write[key_i] = position; } } } else if (track_type == Animation::TYPE_ROTATION_3D) { if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - p_track.rotation_track.times.clear(); - p_track.rotation_track.values.clear(); + p_gltf_node_track.rotation_track.times.clear(); + p_gltf_node_track.rotation_track.values.clear(); // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. const double increment = 1.0 / p_state->get_bake_fps(); double time = 0.0; bool last = false; while (true) { Quaternion rotation; - Error err = p_animation->try_rotation_track_interpolate(p_track_i, time, &rotation); + Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); ERR_CONTINUE(err != OK); - p_track.rotation_track.values.push_back(rotation); - p_track.rotation_track.times.push_back(time); + p_gltf_node_track.rotation_track.values.push_back(rotation); + p_gltf_node_track.rotation_track.times.push_back(time); if (last) { break; } @@ -6486,306 +7532,326 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta } } } else { - p_track.rotation_track.times = times; - p_track.rotation_track.values.resize(key_count); - p_track.rotation_track.interpolation = gltf_interpolation; + p_gltf_node_track.rotation_track.times = p_times; + p_gltf_node_track.rotation_track.values.resize(key_count); + p_gltf_node_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { Quaternion rotation; - Error err = p_animation->rotation_track_get_key(p_track_i, key_i, &rotation); + Error err = p_godot_animation->rotation_track_get_key(p_godot_anim_track_index, key_i, &rotation); ERR_CONTINUE(err != OK); - p_track.rotation_track.values.write[key_i] = rotation; - } - } - } else if (track_type == Animation::TYPE_VALUE) { - if (path.contains(":position")) { - p_track.position_track.interpolation = gltf_interpolation; - p_track.position_track.times = times; - p_track.position_track.values.resize(key_count); - - if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { - gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - p_track.position_track.times.clear(); - p_track.position_track.values.clear(); - // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. - const double increment = 1.0 / p_state->get_bake_fps(); - double time = 0.0; - bool last = false; - while (true) { - Vector3 position; - Error err = p_animation->try_position_track_interpolate(p_track_i, time, &position); - ERR_CONTINUE(err != OK); - p_track.position_track.values.push_back(position); - p_track.position_track.times.push_back(time); - if (last) { - break; + p_gltf_node_track.rotation_track.values.write[key_i] = rotation; + } + } + } else if (subpath.size() > 0) { + const StringName &node_prop = subpath[0]; + if (track_type == Animation::TYPE_VALUE) { + if (node_prop == "position") { + p_gltf_node_track.position_track.interpolation = gltf_interpolation; + p_gltf_node_track.position_track.times = p_times; + p_gltf_node_track.position_track.values.resize(key_count); + + if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { + gltf_interpolation = GLTFAnimation::INTERP_LINEAR; + p_gltf_node_track.position_track.times.clear(); + p_gltf_node_track.position_track.values.clear(); + // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. + const double increment = 1.0 / p_state->get_bake_fps(); + double time = 0.0; + bool last = false; + while (true) { + Vector3 position; + Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position); + ERR_CONTINUE(err != OK); + p_gltf_node_track.position_track.values.push_back(position); + p_gltf_node_track.position_track.times.push_back(time); + if (last) { + break; + } + time += increment; + if (time >= anim_end) { + last = true; + time = anim_end; + } } - time += increment; - if (time >= anim_end) { - last = true; - time = anim_end; + } else { + for (int32_t key_i = 0; key_i < key_count; key_i++) { + Vector3 position = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i); + p_gltf_node_track.position_track.values.write[key_i] = position; } } - } else { - for (int32_t key_i = 0; key_i < key_count; key_i++) { - Vector3 position = p_animation->track_get_key_value(p_track_i, key_i); - p_track.position_track.values.write[key_i] = position; - } - } - } else if (path.contains(":rotation")) { - p_track.rotation_track.interpolation = gltf_interpolation; - p_track.rotation_track.times = times; - p_track.rotation_track.values.resize(key_count); - if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { - gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - p_track.rotation_track.times.clear(); - p_track.rotation_track.values.clear(); - // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. - const double increment = 1.0 / p_state->get_bake_fps(); - double time = 0.0; - bool last = false; - while (true) { - Quaternion rotation; - Error err = p_animation->try_rotation_track_interpolate(p_track_i, time, &rotation); - ERR_CONTINUE(err != OK); - p_track.rotation_track.values.push_back(rotation); - p_track.rotation_track.times.push_back(time); - if (last) { - break; + } else if (node_prop == "rotation" || node_prop == "rotation_degrees" || node_prop == "quaternion") { + p_gltf_node_track.rotation_track.interpolation = gltf_interpolation; + p_gltf_node_track.rotation_track.times = p_times; + p_gltf_node_track.rotation_track.values.resize(key_count); + if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { + gltf_interpolation = GLTFAnimation::INTERP_LINEAR; + p_gltf_node_track.rotation_track.times.clear(); + p_gltf_node_track.rotation_track.values.clear(); + // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. + const double increment = 1.0 / p_state->get_bake_fps(); + double time = 0.0; + bool last = false; + while (true) { + Quaternion rotation; + Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); + ERR_CONTINUE(err != OK); + p_gltf_node_track.rotation_track.values.push_back(rotation); + p_gltf_node_track.rotation_track.times.push_back(time); + if (last) { + break; + } + time += increment; + if (time >= anim_end) { + last = true; + time = anim_end; + } } - time += increment; - if (time >= anim_end) { - last = true; - time = anim_end; + } else { + for (int32_t key_i = 0; key_i < key_count; key_i++) { + Quaternion rotation_quaternion; + if (node_prop == "quaternion") { + rotation_quaternion = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i); + } else { + Vector3 rotation_euler = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i); + if (node_prop == "rotation_degrees") { + rotation_euler *= Math_TAU / 360.0; + } + rotation_quaternion = Quaternion::from_euler(rotation_euler); + } + p_gltf_node_track.rotation_track.values.write[key_i] = rotation_quaternion; } } - } else { - for (int32_t key_i = 0; key_i < key_count; key_i++) { - Vector3 rotation_radian = p_animation->track_get_key_value(p_track_i, key_i); - p_track.rotation_track.values.write[key_i] = Quaternion::from_euler(rotation_radian); + } else if (node_prop == "scale") { + p_gltf_node_track.scale_track.interpolation = gltf_interpolation; + p_gltf_node_track.scale_track.times = p_times; + p_gltf_node_track.scale_track.values.resize(key_count); + + if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { + gltf_interpolation = GLTFAnimation::INTERP_LINEAR; + p_gltf_node_track.scale_track.times.clear(); + p_gltf_node_track.scale_track.values.clear(); + // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. + const double increment = 1.0 / p_state->get_bake_fps(); + double time = 0.0; + bool last = false; + while (true) { + Vector3 scale; + Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); + ERR_CONTINUE(err != OK); + p_gltf_node_track.scale_track.values.push_back(scale); + p_gltf_node_track.scale_track.times.push_back(time); + if (last) { + break; + } + time += increment; + if (time >= anim_end) { + last = true; + time = anim_end; + } + } + } else { + for (int32_t key_i = 0; key_i < key_count; key_i++) { + Vector3 scale_track = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i); + p_gltf_node_track.scale_track.values.write[key_i] = scale_track; + } } - } - } else if (path.contains(":scale")) { - p_track.scale_track.times = times; - p_track.scale_track.interpolation = gltf_interpolation; - - p_track.scale_track.values.resize(key_count); - p_track.scale_track.interpolation = gltf_interpolation; - - if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { - gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - p_track.scale_track.times.clear(); - p_track.scale_track.values.clear(); - // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. - const double increment = 1.0 / p_state->get_bake_fps(); - double time = 0.0; - bool last = false; - while (true) { - Vector3 scale; - Error err = p_animation->try_scale_track_interpolate(p_track_i, time, &scale); - ERR_CONTINUE(err != OK); - p_track.scale_track.values.push_back(scale); - p_track.scale_track.times.push_back(time); - if (last) { - break; + } else if (node_prop == "transform") { + p_gltf_node_track.position_track.interpolation = gltf_interpolation; + p_gltf_node_track.position_track.times = p_times; + p_gltf_node_track.position_track.values.resize(key_count); + p_gltf_node_track.rotation_track.interpolation = gltf_interpolation; + p_gltf_node_track.rotation_track.times = p_times; + p_gltf_node_track.rotation_track.values.resize(key_count); + p_gltf_node_track.scale_track.interpolation = gltf_interpolation; + p_gltf_node_track.scale_track.times = p_times; + p_gltf_node_track.scale_track.values.resize(key_count); + if (gltf_interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE) { + gltf_interpolation = GLTFAnimation::INTERP_LINEAR; + p_gltf_node_track.position_track.times.clear(); + p_gltf_node_track.position_track.values.clear(); + p_gltf_node_track.rotation_track.times.clear(); + p_gltf_node_track.rotation_track.values.clear(); + p_gltf_node_track.scale_track.times.clear(); + p_gltf_node_track.scale_track.values.clear(); + // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies. + const double increment = 1.0 / p_state->get_bake_fps(); + double time = 0.0; + bool last = false; + while (true) { + Vector3 position; + Quaternion rotation; + Vector3 scale; + Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position); + ERR_CONTINUE(err != OK); + err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); + ERR_CONTINUE(err != OK); + err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); + ERR_CONTINUE(err != OK); + p_gltf_node_track.position_track.values.push_back(position); + p_gltf_node_track.position_track.times.push_back(time); + p_gltf_node_track.rotation_track.values.push_back(rotation); + p_gltf_node_track.rotation_track.times.push_back(time); + p_gltf_node_track.scale_track.values.push_back(scale); + p_gltf_node_track.scale_track.times.push_back(time); + if (last) { + break; + } + time += increment; + if (time >= anim_end) { + last = true; + time = anim_end; + } } - time += increment; - if (time >= anim_end) { - last = true; - time = anim_end; + } else { + for (int32_t key_i = 0; key_i < key_count; key_i++) { + Transform3D transform = p_godot_animation->track_get_key_value(p_godot_anim_track_index, key_i); + p_gltf_node_track.position_track.values.write[key_i] = transform.get_origin(); + p_gltf_node_track.rotation_track.values.write[key_i] = transform.basis.get_rotation_quaternion(); + p_gltf_node_track.scale_track.values.write[key_i] = transform.basis.get_scale(); } } } else { - for (int32_t key_i = 0; key_i < key_count; key_i++) { - Vector3 scale_track = p_animation->track_get_key_value(p_track_i, key_i); - p_track.scale_track.values.write[key_i] = scale_track; - } - } - } - } else if (track_type == Animation::TYPE_BEZIER) { - const int32_t keys = anim_end * p_state->get_bake_fps(); - if (path.contains(":scale")) { - if (!p_track.scale_track.times.size()) { - p_track.scale_track.interpolation = gltf_interpolation; - Vector<real_t> new_times; - new_times.resize(keys); - for (int32_t key_i = 0; key_i < keys; key_i++) { - new_times.write[key_i] = key_i / p_state->get_bake_fps(); - } - p_track.scale_track.times = new_times; + // This is a Value track animating a property, but not a TRS property, so it can't be converted into a node track. + return false; + } + } else if (track_type == Animation::TYPE_BEZIER) { + const int32_t keys = anim_end * p_state->get_bake_fps(); + if (node_prop == "scale") { + if (p_gltf_node_track.scale_track.times.is_empty()) { + p_gltf_node_track.scale_track.interpolation = gltf_interpolation; + Vector<double> new_times; + new_times.resize(keys); + for (int32_t key_i = 0; key_i < keys; key_i++) { + new_times.write[key_i] = key_i / p_state->get_bake_fps(); + } + p_gltf_node_track.scale_track.times = new_times; - p_track.scale_track.values.resize(keys); + p_gltf_node_track.scale_track.values.resize(keys); - for (int32_t key_i = 0; key_i < keys; key_i++) { - p_track.scale_track.values.write[key_i] = Vector3(1.0f, 1.0f, 1.0f); - } + for (int32_t key_i = 0; key_i < keys; key_i++) { + p_gltf_node_track.scale_track.values.write[key_i] = Vector3(1.0f, 1.0f, 1.0f); + } - for (int32_t key_i = 0; key_i < keys; key_i++) { - Vector3 bezier_track = p_track.scale_track.values[key_i]; - if (path.contains(":scale:x")) { - bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":scale:y")) { - bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":scale:z")) { - bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); + for (int32_t key_i = 0; key_i < keys; key_i++) { + Vector3 bezier_track = p_gltf_node_track.scale_track.values[key_i]; + if (subpath.size() == 2) { + if (subpath[1] == StringName("x")) { + bezier_track.x = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("y")) { + bezier_track.y = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("z")) { + bezier_track.z = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } + } + p_gltf_node_track.scale_track.values.write[key_i] = bezier_track; } - p_track.scale_track.values.write[key_i] = bezier_track; } - } - } else if (path.contains(":position")) { - if (!p_track.position_track.times.size()) { - p_track.position_track.interpolation = gltf_interpolation; - Vector<real_t> new_times; - new_times.resize(keys); - for (int32_t key_i = 0; key_i < keys; key_i++) { - new_times.write[key_i] = key_i / p_state->get_bake_fps(); + } else if (node_prop == "position") { + if (p_gltf_node_track.position_track.times.is_empty()) { + p_gltf_node_track.position_track.interpolation = gltf_interpolation; + Vector<double> new_times; + new_times.resize(keys); + for (int32_t key_i = 0; key_i < keys; key_i++) { + new_times.write[key_i] = key_i / p_state->get_bake_fps(); + } + p_gltf_node_track.position_track.times = new_times; + + p_gltf_node_track.position_track.values.resize(keys); } - p_track.position_track.times = new_times; - p_track.position_track.values.resize(keys); - } + for (int32_t key_i = 0; key_i < keys; key_i++) { + Vector3 bezier_track = p_gltf_node_track.position_track.values[key_i]; + if (subpath.size() == 2) { + if (subpath[1] == StringName("x")) { + bezier_track.x = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("y")) { + bezier_track.y = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("z")) { + bezier_track.z = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } + } + p_gltf_node_track.position_track.values.write[key_i] = bezier_track; + } + } else if (node_prop == "quaternion") { + if (p_gltf_node_track.rotation_track.times.is_empty()) { + p_gltf_node_track.rotation_track.interpolation = gltf_interpolation; + Vector<double> new_times; + new_times.resize(keys); + for (int32_t key_i = 0; key_i < keys; key_i++) { + new_times.write[key_i] = key_i / p_state->get_bake_fps(); + } + p_gltf_node_track.rotation_track.times = new_times; - for (int32_t key_i = 0; key_i < keys; key_i++) { - Vector3 bezier_track = p_track.position_track.values[key_i]; - if (path.contains(":position:x")) { - bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":position:y")) { - bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":position:z")) { - bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); + p_gltf_node_track.rotation_track.values.resize(keys); } - p_track.position_track.values.write[key_i] = bezier_track; - } - } else if (path.contains(":rotation")) { - if (!p_track.rotation_track.times.size()) { - p_track.rotation_track.interpolation = gltf_interpolation; - Vector<real_t> new_times; - new_times.resize(keys); for (int32_t key_i = 0; key_i < keys; key_i++) { - new_times.write[key_i] = key_i / p_state->get_bake_fps(); - } - p_track.rotation_track.times = new_times; - - p_track.rotation_track.values.resize(keys); - } - for (int32_t key_i = 0; key_i < keys; key_i++) { - Quaternion bezier_track = p_track.rotation_track.values[key_i]; - if (path.contains(":rotation:x")) { - bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":rotation:y")) { - bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":rotation:z")) { - bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); - } else if (path.contains(":rotation:w")) { - bezier_track.w = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps()); + Quaternion bezier_track = p_gltf_node_track.rotation_track.values[key_i]; + if (subpath.size() == 2) { + if (subpath[1] == StringName("x")) { + bezier_track.x = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("y")) { + bezier_track.y = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("z")) { + bezier_track.z = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } else if (subpath[1] == StringName("w")) { + bezier_track.w = p_godot_animation->bezier_track_interpolate(p_godot_anim_track_index, key_i / p_state->get_bake_fps()); + } + } + p_gltf_node_track.rotation_track.values.write[key_i] = bezier_track; } - p_track.rotation_track.values.write[key_i] = bezier_track; + } else { + // This is a Bezier track animating a property, but not a TRS property, so it can't be converted into a node track. + return false; } + } else { + // This property track isn't a Value track or Bezier track, so it can't be converted into a node track. + return false; } + } else { + // This isn't a TRS track or a property track, so it can't be converted into a node track. + return false; } - return p_track; + // If we reached this point, the track was some kind of TRS track and was successfully converted. + // All failure paths should return false before this point to indicate this + // isn't a node track so it can be handled by KHR_animation_pointer instead. + return true; } -void GLTFDocument::_convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, String p_animation_track_name) { +void GLTFDocument::_convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const String &p_animation_track_name) { Ref<Animation> animation = p_animation_player->get_animation(p_animation_track_name); Ref<GLTFAnimation> gltf_animation; gltf_animation.instantiate(); gltf_animation->set_original_name(p_animation_track_name); gltf_animation->set_name(_gen_unique_name(p_state, p_animation_track_name)); - for (int32_t track_i = 0; track_i < animation->get_track_count(); track_i++) { - if (!animation->track_is_enabled(track_i)) { + HashMap<int, GLTFAnimation::NodeTrack> &node_tracks = gltf_animation->get_node_tracks(); + for (int32_t track_index = 0; track_index < animation->get_track_count(); track_index++) { + if (!animation->track_is_enabled(track_index)) { continue; } - String final_track_path = animation->track_get_path(track_i); - Node *animation_base_node = p_animation_player->get_parent(); - ERR_CONTINUE_MSG(!animation_base_node, "Cannot get the parent of the animation player."); - if (String(final_track_path).contains(":position")) { - const Vector<String> node_suffix = String(final_track_path).split(":position"); - const NodePath path = node_suffix[0]; - const Node *node = animation_base_node->get_node_or_null(path); - ERR_CONTINUE_MSG(!node, "Cannot get the node from a position path."); - for (const KeyValue<GLTFNodeIndex, Node *> &position_scene_node_i : p_state->scene_nodes) { - if (position_scene_node_i.value == node) { - GLTFNodeIndex node_index = position_scene_node_i.key; - HashMap<int, GLTFAnimation::Track>::Iterator position_track_i = gltf_animation->get_tracks().find(node_index); - GLTFAnimation::Track track; - if (position_track_i) { - track = position_track_i->value; - } - track = _convert_animation_track(p_state, track, animation, track_i, node_index); - gltf_animation->get_tracks().insert(node_index, track); - } - } - } else if (String(final_track_path).contains(":rotation_degrees")) { - const Vector<String> node_suffix = String(final_track_path).split(":rotation_degrees"); - const NodePath path = node_suffix[0]; - const Node *node = animation_base_node->get_node_or_null(path); - ERR_CONTINUE_MSG(!node, "Cannot get the node from a rotation degrees path."); - for (const KeyValue<GLTFNodeIndex, Node *> &rotation_degree_scene_node_i : p_state->scene_nodes) { - if (rotation_degree_scene_node_i.value == node) { - GLTFNodeIndex node_index = rotation_degree_scene_node_i.key; - HashMap<int, GLTFAnimation::Track>::Iterator rotation_degree_track_i = gltf_animation->get_tracks().find(node_index); - GLTFAnimation::Track track; - if (rotation_degree_track_i) { - track = rotation_degree_track_i->value; - } - track = _convert_animation_track(p_state, track, animation, track_i, node_index); - gltf_animation->get_tracks().insert(node_index, track); - } - } - } else if (String(final_track_path).contains(":scale")) { - const Vector<String> node_suffix = String(final_track_path).split(":scale"); - const NodePath path = node_suffix[0]; - const Node *node = animation_base_node->get_node_or_null(path); - ERR_CONTINUE_MSG(!node, "Cannot get the node from a scale path."); - for (const KeyValue<GLTFNodeIndex, Node *> &scale_scene_node_i : p_state->scene_nodes) { - if (scale_scene_node_i.value == node) { - GLTFNodeIndex node_index = scale_scene_node_i.key; - HashMap<int, GLTFAnimation::Track>::Iterator scale_track_i = gltf_animation->get_tracks().find(node_index); - GLTFAnimation::Track track; - if (scale_track_i) { - track = scale_track_i->value; - } - track = _convert_animation_track(p_state, track, animation, track_i, node_index); - gltf_animation->get_tracks().insert(node_index, track); - } - } - } else if (String(final_track_path).contains(":transform")) { - const Vector<String> node_suffix = String(final_track_path).split(":transform"); - const NodePath path = node_suffix[0]; - const Node *node = animation_base_node->get_node_or_null(path); - ERR_CONTINUE_MSG(!node, "Cannot get the node from a transform path."); - for (const KeyValue<GLTFNodeIndex, Node *> &transform_track_i : p_state->scene_nodes) { - if (transform_track_i.value == node) { - GLTFAnimation::Track track; - track = _convert_animation_track(p_state, track, animation, track_i, transform_track_i.key); - gltf_animation->get_tracks().insert(transform_track_i.key, track); - } - } - } else if (String(final_track_path).contains(":") && animation->track_get_type(track_i) == Animation::TYPE_BLEND_SHAPE) { - const Vector<String> node_suffix = String(final_track_path).split(":"); - const NodePath path = node_suffix[0]; - const String suffix = node_suffix[1]; - Node *node = animation_base_node->get_node_or_null(path); - ERR_CONTINUE_MSG(!node, "Cannot get the node from a blend shape path."); - MeshInstance3D *mi = cast_to<MeshInstance3D>(node); - if (!mi) { - continue; - } - Ref<Mesh> mesh = mi->get_mesh(); + // Get the Godot node and the glTF node index for the animation track. + const NodePath track_path = animation->track_get_path(track_index); + const Node *anim_player_parent = p_animation_player->get_parent(); + const Node *animated_node = anim_player_parent->get_node_or_null(track_path); + ERR_CONTINUE_MSG(!animated_node, "glTF: Cannot get node for animated track using path: " + String(track_path)); + const GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::godot_to_gltf_interpolation(animation, track_index); + // First, check if it's a Blend Shape track. + if (animation->track_get_type(track_index) == Animation::TYPE_BLEND_SHAPE) { + const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(animated_node); + ERR_CONTINUE_MSG(!mesh_instance, "glTF: Animation had a Blend Shape track, but the node wasn't a MeshInstance3D. Ignoring this track."); + Ref<Mesh> mesh = mesh_instance->get_mesh(); ERR_CONTINUE(mesh.is_null()); int32_t mesh_index = -1; for (const KeyValue<GLTFNodeIndex, Node *> &mesh_track_i : p_state->scene_nodes) { - if (mesh_track_i.value == node) { + if (mesh_track_i.value == animated_node) { mesh_index = mesh_track_i.key; } } ERR_CONTINUE(mesh_index == -1); - HashMap<int, GLTFAnimation::Track> &tracks = gltf_animation->get_tracks(); - GLTFAnimation::Track track = gltf_animation->get_tracks().has(mesh_index) ? gltf_animation->get_tracks()[mesh_index] : GLTFAnimation::Track(); - if (!tracks.has(mesh_index)) { + GLTFAnimation::NodeTrack track = node_tracks.has(mesh_index) ? node_tracks[mesh_index] : GLTFAnimation::NodeTrack(); + if (!node_tracks.has(mesh_index)) { for (int32_t shape_i = 0; shape_i < mesh->get_blend_shape_count(); shape_i++) { String shape_name = mesh->get_blend_shape_name(shape_i); - NodePath shape_path = String(path) + ":" + shape_name; + NodePath shape_path = NodePath(track_path.get_names(), { shape_name }, false); int32_t shape_track_i = animation->find_track(shape_path, Animation::TYPE_BLEND_SHAPE); if (shape_track_i == -1) { GLTFAnimation::Channel<real_t> weight; @@ -6797,15 +7863,6 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p track.weight_tracks.push_back(weight); continue; } - Animation::InterpolationType interpolation = animation->track_get_interpolation_type(track_i); - GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - if (interpolation == Animation::InterpolationType::INTERPOLATION_LINEAR) { - gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - } else if (interpolation == Animation::InterpolationType::INTERPOLATION_NEAREST) { - gltf_interpolation = GLTFAnimation::INTERP_STEP; - } else if (interpolation == Animation::InterpolationType::INTERPOLATION_CUBIC) { - gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE; - } int32_t key_count = animation->track_get_key_count(shape_track_i); GLTFAnimation::Channel<real_t> weight; weight.interpolation = gltf_interpolation; @@ -6819,64 +7876,74 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p } track.weight_tracks.push_back(weight); } - tracks[mesh_index] = track; - } - } else if (String(final_track_path).contains(":")) { - //Process skeleton - const Vector<String> node_suffix = String(final_track_path).split(":"); - const String &node = node_suffix[0]; - const NodePath node_path = node; - const String &suffix = node_suffix[1]; - Node *godot_node = animation_base_node->get_node_or_null(node_path); - if (!godot_node) { - continue; - } - Skeleton3D *skeleton = cast_to<Skeleton3D>(animation_base_node->get_node_or_null(node)); - if (!skeleton) { - continue; - } - GLTFSkeletonIndex skeleton_gltf_i = -1; - for (GLTFSkeletonIndex skeleton_i = 0; skeleton_i < p_state->skeletons.size(); skeleton_i++) { - if (p_state->skeletons[skeleton_i]->godot_skeleton == cast_to<Skeleton3D>(godot_node)) { - skeleton = p_state->skeletons[skeleton_i]->godot_skeleton; - skeleton_gltf_i = skeleton_i; - ERR_CONTINUE(!skeleton); - Ref<GLTFSkeleton> skeleton_gltf = p_state->skeletons[skeleton_gltf_i]; - int32_t bone = skeleton->find_bone(suffix); - ERR_CONTINUE_MSG(bone == -1, vformat("Cannot find the bone %s.", suffix)); - if (!skeleton_gltf->godot_bone_node.has(bone)) { - continue; - } - GLTFNodeIndex node_i = skeleton_gltf->godot_bone_node[bone]; - HashMap<int, GLTFAnimation::Track>::Iterator property_track_i = gltf_animation->get_tracks().find(node_i); - GLTFAnimation::Track track; - if (property_track_i) { - track = property_track_i->value; - } - track = _convert_animation_track(p_state, track, animation, track_i, node_i); - gltf_animation->get_tracks()[node_i] = track; - } - } - } else if (!String(final_track_path).contains(":")) { - ERR_CONTINUE(!animation_base_node); - Node *godot_node = animation_base_node->get_node_or_null(final_track_path); - ERR_CONTINUE_MSG(!godot_node, vformat("Cannot get the node from a skeleton path %s.", final_track_path)); - for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : p_state->scene_nodes) { - if (scene_node_i.value == godot_node) { - GLTFNodeIndex node_i = scene_node_i.key; - HashMap<int, GLTFAnimation::Track>::Iterator node_track_i = gltf_animation->get_tracks().find(node_i); - GLTFAnimation::Track track; - if (node_track_i) { - track = node_track_i->value; - } - track = _convert_animation_track(p_state, track, animation, track_i, node_i); - gltf_animation->get_tracks()[node_i] = track; - break; - } + node_tracks[mesh_index] = track; } + continue; } - } - if (gltf_animation->get_tracks().size()) { + // If it's not a Blend Shape track, it must either be a TRS track, a property Value track, or something we can't handle. + // For the cases we can handle, we will need to know the glTF node index, glTF interpolation, and the times of the track. + const Vector<StringName> subnames = track_path.get_subnames(); + const GLTFNodeIndex node_i = _node_and_or_bone_to_gltf_node_index(p_state, subnames, animated_node); + ERR_CONTINUE_MSG(node_i == -1, "glTF: Cannot get glTF node index for animated track using path: " + String(track_path)); + const int anim_key_count = animation->track_get_key_count(track_index); + Vector<double> times; + times.resize(anim_key_count); + for (int32_t key_i = 0; key_i < anim_key_count; key_i++) { + times.write[key_i] = animation->track_get_key_time(track_index, key_i); + } + // Try converting the track to a TRS glTF node track. This will only succeed if the Godot animation is a TRS track. + const HashMap<int, GLTFAnimation::NodeTrack>::Iterator node_track_iter = node_tracks.find(node_i); + GLTFAnimation::NodeTrack track; + if (node_track_iter) { + track = node_track_iter->value; + } + if (_convert_animation_node_track(p_state, track, animation, track_index, times)) { + // If the track was successfully converted, save it and continue to the next track. + node_tracks[node_i] = track; + continue; + } + // If the track wasn't a TRS track or Blend Shape track, it might be a Value track animating a property. + // Then this is something that we need to handle with KHR_animation_pointer. + Ref<GLTFObjectModelProperty> obj_model_prop = export_object_model_property(p_state, track_path, animated_node, node_i); + if (obj_model_prop.is_valid() && obj_model_prop->has_json_pointers()) { + // Insert the property track into the KHR_animation_pointer pointer tracks. + GLTFAnimation::Channel<Variant> channel; + channel.interpolation = gltf_interpolation; + channel.times = times; + channel.values.resize(anim_key_count); + // If using an expression, determine the base instance to pass to the expression. + const Ref<Expression> godot_to_gltf_expr = obj_model_prop->get_godot_to_gltf_expression(); + const bool is_godot_to_gltf_expr_valid = godot_to_gltf_expr.is_valid(); + Object *base_instance = nullptr; + if (is_godot_to_gltf_expr_valid) { + Ref<Resource> resource; + Vector<StringName> leftover_subpath; + base_instance = anim_player_parent->get_node_and_resource(track_path, resource, leftover_subpath); + if (resource.is_valid()) { + base_instance = resource.ptr(); + } + } + // Convert the Godot animation values into glTF animation values (still Variant). + for (int32_t key_i = 0; key_i < anim_key_count; key_i++) { + Variant value = animation->track_get_key_value(track_index, key_i); + if (is_godot_to_gltf_expr_valid) { + Array inputs; + inputs.append(value); + value = godot_to_gltf_expr->execute(inputs, base_instance); + } + channel.values.write[key_i] = value; + } + // Use the JSON pointer to insert the property track into the pointer tracks. There will usually be just one JSON pointer. + HashMap<String, GLTFAnimation::Channel<Variant>> &pointer_tracks = gltf_animation->get_pointer_tracks(); + Vector<PackedStringArray> split_json_pointers = obj_model_prop->get_json_pointers(); + for (const PackedStringArray &split_json_pointer : split_json_pointers) { + String json_pointer_str = "/" + String("/").join(split_json_pointer); + p_state->object_model_properties[json_pointer_str] = obj_model_prop; + pointer_tracks[json_pointer_str] = channel; + } + } + } + if (!gltf_animation->is_empty_of_tracks()) { p_state->animations.push_back(gltf_animation); } } @@ -7075,6 +8142,9 @@ void GLTFDocument::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lossy_quality"), "set_lossy_quality", "get_lossy_quality"); ADD_PROPERTY(PropertyInfo(Variant::INT, "root_node_mode"), "set_root_node_mode", "get_root_node_mode"); + ClassDB::bind_static_method("GLTFDocument", D_METHOD("import_object_model_property", "state", "json_pointer"), &GLTFDocument::import_object_model_property); + ClassDB::bind_static_method("GLTFDocument", D_METHOD("export_object_model_property", "state", "node_path", "godot_node", "gltf_node_index"), &GLTFDocument::export_object_model_property); + ClassDB::bind_static_method("GLTFDocument", D_METHOD("register_gltf_document_extension", "extension", "first_priority"), &GLTFDocument::register_gltf_document_extension, DEFVAL(false)); ClassDB::bind_static_method("GLTFDocument", D_METHOD("unregister_gltf_document_extension", "extension"), @@ -7136,6 +8206,7 @@ HashSet<String> GLTFDocument::get_supported_gltf_extensions_hashset() { // If the extension is supported directly in GLTFDocument, list it here. // Other built-in extensions are supported by GLTFDocumentExtension classes. supported_extensions.insert("GODOT_single_root"); + supported_extensions.insert("KHR_animation_pointer"); supported_extensions.insert("KHR_lights_punctual"); supported_extensions.insert("KHR_materials_emissive_strength"); supported_extensions.insert("KHR_materials_pbrSpecularGlossiness"); @@ -7313,6 +8384,10 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_se err = SkinTool::_determine_skeletons(p_state->skins, p_state->nodes, p_state->skeletons, p_state->get_import_as_skeleton_bones() ? p_state->root_nodes : Vector<GLTFNodeIndex>()); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + /* ASSIGN SCENE NODE NAMES */ + // This must be run AFTER determining skeletons, and BEFORE parsing animations. + _assign_node_names(p_state); + /* PARSE MESHES (we have enough info now) */ err = _parse_meshes(p_state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); @@ -7329,9 +8404,6 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> p_state, const String &p_se err = _parse_animations(p_state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* ASSIGN SCENE NAMES */ - _assign_node_names(p_state); - return OK; } @@ -7350,7 +8422,7 @@ PackedByteArray GLTFDocument::generate_buffer(Ref<GLTFState> p_state) { Error GLTFDocument::write_to_filesystem(Ref<GLTFState> p_state, const String &p_path) { Ref<GLTFState> state = p_state; ERR_FAIL_COND_V(state.is_null(), ERR_INVALID_PARAMETER); - state->base_path = p_path.get_base_dir(); + state->set_base_path(p_path.get_base_dir()); state->filename = p_path.get_file(); Error err = _serialize(state); if (err != OK) { @@ -7463,7 +8535,7 @@ Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_pa Ref<FileAccessMemory> file_access; file_access.instantiate(); file_access->open_custom(p_bytes.ptr(), p_bytes.size()); - state->base_path = p_base_path.get_base_dir(); + state->set_base_path(p_base_path.get_base_dir()); err = _parse(p_state, state->base_path, file_access); ERR_FAIL_COND_V(err != OK, err); for (Ref<GLTFDocumentExtension> ext : document_extensions) { @@ -7480,7 +8552,7 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> p_state, uint if (state == Ref<GLTFState>()) { state.instantiate(); } - state->filename = p_path.get_file().get_basename(); + state->set_filename(p_path.get_file().get_basename()); state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS; state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS; state->force_generate_tangents = p_flags & GLTF_IMPORT_GENERATE_TANGENT_ARRAYS; @@ -7494,7 +8566,7 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> p_state, uint if (base_path.is_empty()) { base_path = p_path.get_base_dir(); } - state->base_path = base_path; + state->set_base_path(base_path); err = _parse(p_state, base_path, file); ERR_FAIL_COND_V(err != OK, err); for (Ref<GLTFDocumentExtension> ext : document_extensions) { diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index d347d49102..a6d6caa3f0 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -56,13 +56,6 @@ public: enum { ARRAY_BUFFER = 34962, ELEMENT_ARRAY_BUFFER = 34963, - - COMPONENT_TYPE_BYTE = 5120, - COMPONENT_TYPE_UNSIGNED_BYTE = 5121, - COMPONENT_TYPE_SHORT = 5122, - COMPONENT_TYPE_UNSIGNED_SHORT = 5123, - COMPONENT_TYPE_INT = 5125, - COMPONENT_TYPE_FLOAT = 5126, }; enum { TEXTURE_TYPE_GENERIC = 0, @@ -95,6 +88,10 @@ public: static Vector<String> get_supported_gltf_extensions(); static HashSet<String> get_supported_gltf_extensions_hashset(); + static NodePath _find_material_node_path(Ref<GLTFState> p_state, Ref<Material> p_material); + static Ref<GLTFObjectModelProperty> import_object_model_property(Ref<GLTFState> p_state, const String &p_json_pointer); + static Ref<GLTFObjectModelProperty> export_object_model_property(Ref<GLTFState> p_state, const NodePath &p_node_path, const Node *p_godot_node, GLTFNodeIndex p_gltf_node_index); + void set_naming_version(int p_version); int get_naming_version() const; void set_image_format(const String &p_image_format); @@ -109,8 +106,8 @@ private: void _build_parent_hierachy(Ref<GLTFState> p_state); double _filter_number(double p_float); void _round_min_max_components(Vector<double> &r_type_min, Vector<double> &r_type_max); - String _get_component_type_name(const uint32_t p_component); - int _get_component_type_size(const int p_component_type); + String _get_component_type_name(const GLTFAccessor::GLTFComponentType p_component_type); + int _get_component_type_size(const GLTFAccessor::GLTFComponentType p_component_type); Error _parse_scenes(Ref<GLTFState> p_state); Error _parse_nodes(Ref<GLTFState> p_state); String _get_accessor_type_name(const GLTFAccessor::GLTFAccessorType p_accessor_type); @@ -140,7 +137,7 @@ private: const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_count, - const int p_component_type, const int p_component_size, + const GLTFAccessor::GLTFComponentType p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex); Vector<double> _decode_accessor(Ref<GLTFState> p_state, @@ -178,6 +175,15 @@ private: Vector<Transform3D> _decode_accessor_as_xform(Ref<GLTFState> p_state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex); + Vector<Variant> _decode_accessor_as_variant(Ref<GLTFState> p_state, + const GLTFAccessorIndex p_accessor, + Variant::Type p_variant_type, + GLTFAccessor::GLTFAccessorType p_accessor_type); + GLTFAccessorIndex _encode_accessor_as_variant(Ref<GLTFState> p_state, + Vector<Variant> p_attribs, + Variant::Type p_variant_type, + GLTFAccessor::GLTFAccessorType p_accessor_type, + GLTFAccessor::GLTFComponentType p_component_type = GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT); Error _parse_meshes(Ref<GLTFState> p_state); Error _serialize_textures(Ref<GLTFState> p_state); Error _serialize_texture_samplers(Ref<GLTFState> p_state); @@ -205,6 +211,7 @@ private: Error _parse_cameras(Ref<GLTFState> p_state); Error _parse_lights(Ref<GLTFState> p_state); Error _parse_animations(Ref<GLTFState> p_state); + void _parse_animation_pointer(Ref<GLTFState> p_state, const String &p_animation_json_pointer, const Ref<GLTFAnimation> p_gltf_animation, const GLTFAnimation::Interpolation p_interp, const Vector<double> &p_times, const int p_output_value_accessor_index); Error _serialize_animations(Ref<GLTFState> p_state); BoneAttachment3D *_generate_bone_attachment(Ref<GLTFState> p_state, Skeleton3D *p_skeleton, @@ -216,7 +223,7 @@ private: Node3D *_generate_spatial(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index); void _assign_node_names(Ref<GLTFState> p_state); template <typename T> - T _interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values, + T _interpolate_track(const Vector<double> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp); GLTFAccessorIndex _encode_accessor_as_quaternions(Ref<GLTFState> p_state, @@ -229,7 +236,7 @@ private: const Vector<Color> p_attribs, const bool p_for_vertex); GLTFAccessorIndex _encode_accessor_as_floats(Ref<GLTFState> p_state, - const Vector<real_t> p_attribs, + const Vector<double> p_attribs, const bool p_for_vertex); GLTFAccessorIndex _encode_accessor_as_vec2(Ref<GLTFState> p_state, const Vector<Vector2> p_attribs, @@ -269,7 +276,7 @@ private: const bool p_for_vertex); Error _encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, - const int p_component_type, const bool p_normalized, + const GLTFAccessor::GLTFComponentType p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_indices = false); @@ -280,11 +287,6 @@ private: Error _serialize_nodes(Ref<GLTFState> p_state); Error _serialize_scenes(Ref<GLTFState> p_state); String interpolation_to_string(const GLTFAnimation::Interpolation p_interp); - GLTFAnimation::Track _convert_animation_track(Ref<GLTFState> p_state, - GLTFAnimation::Track p_track, - Ref<Animation> p_animation, - int32_t p_track_i, - GLTFNodeIndex p_node_i); Error _encode_buffer_bins(Ref<GLTFState> p_state, const String &p_path); Error _encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path); PackedByteArray _serialize_glb_buffer(Ref<GLTFState> p_state, Error *r_err); @@ -342,11 +344,6 @@ public: void _convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state); #endif // MODULE_CSG_ENABLED - void _convert_animation_player_to_gltf( - AnimationPlayer *p_animation_player, Ref<GLTFState> p_state, - GLTFNodeIndex p_gltf_current, - GLTFNodeIndex p_gltf_root_index, - Ref<GLTFNode> p_gltf_node, Node *p_scene_parent); void _check_visibility(Node *p_node, bool &r_retflag); void _convert_camera_to_gltf(Camera3D *p_camera, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node); @@ -377,7 +374,15 @@ public: Ref<GLTFNode> p_gltf_node); GLTFMeshIndex _convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshInstance3D *p_mesh_instance); - void _convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, String p_animation_track_name); + + GLTFNodeIndex _node_and_or_bone_to_gltf_node_index(Ref<GLTFState> p_state, const Vector<StringName> &p_node_subpath, const Node *p_godot_node); + bool _convert_animation_node_track(Ref<GLTFState> p_state, + GLTFAnimation::NodeTrack &p_gltf_node_track, + const Ref<Animation> &p_godot_animation, + int32_t p_godot_anim_track_index, + Vector<double> &p_times); + void _convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const String &p_animation_track_name); + Error _serialize(Ref<GLTFState> p_state); Error _parse(Ref<GLTFState> p_state, String p_path, Ref<FileAccess> p_file); }; diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 7763874d02..2488e73d08 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -397,8 +397,27 @@ String GLTFState::get_base_path() { return base_path; } -void GLTFState::set_base_path(String p_base_path) { +void GLTFState::set_base_path(const String &p_base_path) { base_path = p_base_path; + if (extract_path.is_empty()) { + extract_path = p_base_path; + } +} + +String GLTFState::get_extract_path() { + return extract_path; +} + +void GLTFState::set_extract_path(const String &p_extract_path) { + extract_path = p_extract_path; +} + +String GLTFState::get_extract_prefix() { + return extract_prefix; +} + +void GLTFState::set_extract_prefix(const String &p_extract_prefix) { + extract_prefix = p_extract_prefix; } String GLTFState::get_filename() const { @@ -407,6 +426,9 @@ String GLTFState::get_filename() const { void GLTFState::set_filename(const String &p_filename) { filename = p_filename; + if (extract_prefix.is_empty()) { + extract_prefix = p_filename.get_basename(); + } } Variant GLTFState::get_additional_data(const StringName &p_extension_name) { diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 7954049192..d667cf8858 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -38,6 +38,7 @@ #include "structures/gltf_camera.h" #include "structures/gltf_mesh.h" #include "structures/gltf_node.h" +#include "structures/gltf_object_model_property.h" #include "structures/gltf_skeleton.h" #include "structures/gltf_skin.h" #include "structures/gltf_texture.h" @@ -48,9 +49,12 @@ class GLTFState : public Resource { GDCLASS(GLTFState, Resource); friend class GLTFDocument; + friend class GLTFNode; protected: String base_path; + String extract_path; + String extract_prefix; String filename; Dictionary json; int major_version = 0; @@ -100,6 +104,7 @@ protected: Vector<Ref<GLTFAnimation>> animations; HashMap<GLTFNodeIndex, Node *> scene_nodes; HashMap<GLTFNodeIndex, ImporterMeshInstance3D *> scene_mesh_instances; + HashMap<String, Ref<GLTFObjectModelProperty>> object_model_properties; HashMap<ObjectID, GLTFSkeletonIndex> skeleton3d_to_gltf_skeleton; HashMap<ObjectID, HashMap<ObjectID, GLTFSkinIndex>> skin_and_skeleton3d_to_gltf_skin; @@ -186,7 +191,13 @@ public: void set_scene_name(String p_scene_name); String get_base_path(); - void set_base_path(String p_base_path); + void set_base_path(const String &p_base_path); + + String get_extract_path(); + void set_extract_path(const String &p_extract_path); + + String get_extract_prefix(); + void set_extract_prefix(const String &p_extract_prefix); String get_filename() const; void set_filename(const String &p_filename); diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index 53e9f2b84c..fbc3ae611c 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -37,6 +37,7 @@ #include "extensions/physics/gltf_document_extension_physics.h" #include "gltf_document.h" #include "gltf_state.h" +#include "structures/gltf_object_model_property.h" #ifdef TOOLS_ENABLED #include "editor/editor_import_blend_runner.h" @@ -112,6 +113,7 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) { GDREGISTER_CLASS(GLTFLight); GDREGISTER_CLASS(GLTFMesh); GDREGISTER_CLASS(GLTFNode); + GDREGISTER_CLASS(GLTFObjectModelProperty); GDREGISTER_CLASS(GLTFPhysicsBody); GDREGISTER_CLASS(GLTFPhysicsShape); GDREGISTER_CLASS(GLTFSkeleton); diff --git a/modules/gltf/structures/gltf_accessor.cpp b/modules/gltf/structures/gltf_accessor.cpp index 1ebc00a514..300fce09ff 100644 --- a/modules/gltf/structures/gltf_accessor.cpp +++ b/modules/gltf/structures/gltf_accessor.cpp @@ -39,6 +39,19 @@ void GLTFAccessor::_bind_methods() { BIND_ENUM_CONSTANT(TYPE_MAT3); BIND_ENUM_CONSTANT(TYPE_MAT4); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_NONE); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_BYTE); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_BYTE); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_SHORT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_SHORT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_INT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_INT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_SINGLE_FLOAT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_DOUBLE_FLOAT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_HALF_FLOAT); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_LONG); + BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_LONG); + ClassDB::bind_method(D_METHOD("get_buffer_view"), &GLTFAccessor::get_buffer_view); ClassDB::bind_method(D_METHOD("set_buffer_view", "buffer_view"), &GLTFAccessor::set_buffer_view); ClassDB::bind_method(D_METHOD("get_byte_offset"), &GLTFAccessor::get_byte_offset); @@ -108,7 +121,7 @@ int GLTFAccessor::get_component_type() { } void GLTFAccessor::set_component_type(int p_component_type) { - component_type = p_component_type; + component_type = (GLTFComponentType)p_component_type; } bool GLTFAccessor::get_normalized() { @@ -188,7 +201,7 @@ int GLTFAccessor::get_sparse_indices_component_type() { } void GLTFAccessor::set_sparse_indices_component_type(int p_sparse_indices_component_type) { - sparse_indices_component_type = p_sparse_indices_component_type; + sparse_indices_component_type = (GLTFComponentType)p_sparse_indices_component_type; } int GLTFAccessor::get_sparse_values_buffer_view() { diff --git a/modules/gltf/structures/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h index 1a3a2cb494..b00e6a0f92 100644 --- a/modules/gltf/structures/gltf_accessor.h +++ b/modules/gltf/structures/gltf_accessor.h @@ -50,10 +50,25 @@ public: TYPE_MAT4, }; + enum GLTFComponentType { + COMPONENT_TYPE_NONE = 0, + COMPONENT_TYPE_SIGNED_BYTE = 5120, + COMPONENT_TYPE_UNSIGNED_BYTE = 5121, + COMPONENT_TYPE_SIGNED_SHORT = 5122, + COMPONENT_TYPE_UNSIGNED_SHORT = 5123, + COMPONENT_TYPE_SIGNED_INT = 5124, + COMPONENT_TYPE_UNSIGNED_INT = 5125, + COMPONENT_TYPE_SINGLE_FLOAT = 5126, + COMPONENT_TYPE_DOUBLE_FLOAT = 5130, + COMPONENT_TYPE_HALF_FLOAT = 5131, + COMPONENT_TYPE_SIGNED_LONG = 5134, + COMPONENT_TYPE_UNSIGNED_LONG = 5135, + }; + private: GLTFBufferViewIndex buffer_view = -1; int byte_offset = 0; - int component_type = 0; + GLTFComponentType component_type = COMPONENT_TYPE_NONE; bool normalized = false; int count = 0; GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_SCALAR; @@ -62,7 +77,7 @@ private: int sparse_count = 0; int sparse_indices_buffer_view = 0; int sparse_indices_byte_offset = 0; - int sparse_indices_component_type = 0; + GLTFComponentType sparse_indices_component_type = COMPONENT_TYPE_NONE; int sparse_values_buffer_view = 0; int sparse_values_byte_offset = 0; @@ -117,5 +132,6 @@ public: }; VARIANT_ENUM_CAST(GLTFAccessor::GLTFAccessorType); +VARIANT_ENUM_CAST(GLTFAccessor::GLTFComponentType); #endif // GLTF_ACCESSOR_H diff --git a/modules/gltf/structures/gltf_animation.cpp b/modules/gltf/structures/gltf_animation.cpp index 94fda8e2f5..adc0354c4b 100644 --- a/modules/gltf/structures/gltf_animation.cpp +++ b/modules/gltf/structures/gltf_animation.cpp @@ -42,6 +42,34 @@ void GLTFAnimation::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "get_loop"); // bool } +GLTFAnimation::Interpolation GLTFAnimation::godot_to_gltf_interpolation(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index) { + Animation::InterpolationType interpolation = p_godot_animation->track_get_interpolation_type(p_godot_anim_track_index); + switch (interpolation) { + case Animation::INTERPOLATION_LINEAR: + case Animation::INTERPOLATION_LINEAR_ANGLE: + return INTERP_LINEAR; + case Animation::INTERPOLATION_NEAREST: + return INTERP_STEP; + case Animation::INTERPOLATION_CUBIC: + case Animation::INTERPOLATION_CUBIC_ANGLE: + return INTERP_CUBIC_SPLINE; + } + return INTERP_LINEAR; +} + +Animation::InterpolationType GLTFAnimation::gltf_to_godot_interpolation(Interpolation p_gltf_interpolation) { + switch (p_gltf_interpolation) { + case INTERP_LINEAR: + return Animation::INTERPOLATION_LINEAR; + case INTERP_STEP: + return Animation::INTERPOLATION_NEAREST; + case INTERP_CATMULLROMSPLINE: + case INTERP_CUBIC_SPLINE: + return Animation::INTERPOLATION_CUBIC; + } + return Animation::INTERPOLATION_LINEAR; +} + String GLTFAnimation::get_original_name() { return original_name; } @@ -58,8 +86,16 @@ void GLTFAnimation::set_loop(bool p_val) { loop = p_val; } -HashMap<int, GLTFAnimation::Track> &GLTFAnimation::get_tracks() { - return tracks; +HashMap<int, GLTFAnimation::NodeTrack> &GLTFAnimation::get_node_tracks() { + return node_tracks; +} + +HashMap<String, GLTFAnimation::Channel<Variant>> &GLTFAnimation::get_pointer_tracks() { + return pointer_tracks; +} + +bool GLTFAnimation::is_empty_of_tracks() const { + return node_tracks.is_empty() && pointer_tracks.is_empty(); } GLTFAnimation::GLTFAnimation() { diff --git a/modules/gltf/structures/gltf_animation.h b/modules/gltf/structures/gltf_animation.h index afc9784895..6b692d06e6 100644 --- a/modules/gltf/structures/gltf_animation.h +++ b/modules/gltf/structures/gltf_animation.h @@ -50,33 +50,41 @@ public: template <typename T> struct Channel { Interpolation interpolation = INTERP_LINEAR; - Vector<real_t> times; + Vector<double> times; Vector<T> values; }; - struct Track { + struct NodeTrack { Channel<Vector3> position_track; Channel<Quaternion> rotation_track; Channel<Vector3> scale_track; Vector<Channel<real_t>> weight_tracks; }; + String original_name; + bool loop = false; + HashMap<int, NodeTrack> node_tracks; + HashMap<String, Channel<Variant>> pointer_tracks; + Dictionary additional_data; + public: + static Interpolation godot_to_gltf_interpolation(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index); + static Animation::InterpolationType gltf_to_godot_interpolation(Interpolation p_gltf_interpolation); + String get_original_name(); void set_original_name(String p_name); bool get_loop() const; void set_loop(bool p_val); - HashMap<int, GLTFAnimation::Track> &get_tracks(); + + HashMap<int, GLTFAnimation::NodeTrack> &get_node_tracks(); + HashMap<String, GLTFAnimation::Channel<Variant>> &get_pointer_tracks(); + bool is_empty_of_tracks() const; + Variant get_additional_data(const StringName &p_extension_name); void set_additional_data(const StringName &p_extension_name, Variant p_additional_data); - GLTFAnimation(); -private: - String original_name; - bool loop = false; - HashMap<int, Track> tracks; - Dictionary additional_data; + GLTFAnimation(); }; #endif // GLTF_ANIMATION_H diff --git a/modules/gltf/structures/gltf_camera.cpp b/modules/gltf/structures/gltf_camera.cpp index 863e1df967..2960ec351d 100644 --- a/modules/gltf/structures/gltf_camera.cpp +++ b/modules/gltf/structures/gltf_camera.cpp @@ -30,6 +30,7 @@ #include "gltf_camera.h" +#include "gltf_object_model_property.h" #include "scene/3d/camera_3d.h" void GLTFCamera::_bind_methods() { @@ -57,6 +58,21 @@ void GLTFCamera::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth_near"), "set_depth_near", "get_depth_near"); } +void GLTFCamera::set_fov_conversion_expressions(Ref<GLTFObjectModelProperty> &r_obj_model_prop) { + // Expression to convert glTF yfov in radians to Godot fov in degrees. + Ref<Expression> gltf_to_godot_expr; + gltf_to_godot_expr.instantiate(); + PackedStringArray gltf_to_godot_args = { "yfov_rad" }; + gltf_to_godot_expr->parse("rad_to_deg(yfov_rad)", gltf_to_godot_args); + r_obj_model_prop->set_gltf_to_godot_expression(gltf_to_godot_expr); + // Expression to convert Godot fov in degrees to glTF yfov in radians. + Ref<Expression> godot_to_gltf_expr; + godot_to_gltf_expr.instantiate(); + PackedStringArray godot_to_gltf_args = { "fov_deg" }; + godot_to_gltf_expr->parse("deg_to_rad(fov_deg)", godot_to_gltf_args); + r_obj_model_prop->set_godot_to_gltf_expression(godot_to_gltf_expr); +} + Ref<GLTFCamera> GLTFCamera::from_node(const Camera3D *p_camera) { Ref<GLTFCamera> c; c.instantiate(); diff --git a/modules/gltf/structures/gltf_camera.h b/modules/gltf/structures/gltf_camera.h index 1a583c82cc..497b6cd4f1 100644 --- a/modules/gltf/structures/gltf_camera.h +++ b/modules/gltf/structures/gltf_camera.h @@ -34,6 +34,7 @@ #include "core/io/resource.h" class Camera3D; +class GLTFObjectModelProperty; // Reference and test file: // https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_015_SimpleCameras.md @@ -54,6 +55,8 @@ protected: static void _bind_methods(); public: + static void set_fov_conversion_expressions(Ref<GLTFObjectModelProperty> &r_obj_model_prop); + bool get_perspective() const { return perspective; } void set_perspective(bool p_val) { perspective = p_val; } real_t get_fov() const { return fov; } diff --git a/modules/gltf/structures/gltf_node.cpp b/modules/gltf/structures/gltf_node.cpp index ccee5e8ca4..1626313551 100644 --- a/modules/gltf/structures/gltf_node.cpp +++ b/modules/gltf/structures/gltf_node.cpp @@ -30,6 +30,8 @@ #include "gltf_node.h" +#include "../gltf_state.h" + void GLTFNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_original_name"), &GLTFNode::get_original_name); ClassDB::bind_method(D_METHOD("set_original_name", "original_name"), &GLTFNode::set_original_name); @@ -60,6 +62,7 @@ void GLTFNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_light", "light"), &GLTFNode::set_light); ClassDB::bind_method(D_METHOD("get_additional_data", "extension_name"), &GLTFNode::get_additional_data); ClassDB::bind_method(D_METHOD("set_additional_data", "extension_name", "additional_data"), &GLTFNode::set_additional_data); + ClassDB::bind_method(D_METHOD("get_scene_node_path", "gltf_state", "handle_skeletons"), &GLTFNode::get_scene_node_path, DEFVAL(true)); ADD_PROPERTY(PropertyInfo(Variant::STRING, "original_name"), "set_original_name", "get_original_name"); // String ADD_PROPERTY(PropertyInfo(Variant::INT, "parent"), "set_parent", "get_parent"); // GLTFNodeIndex @@ -187,6 +190,48 @@ Variant GLTFNode::get_additional_data(const StringName &p_extension_name) { return additional_data[p_extension_name]; } +bool GLTFNode::has_additional_data(const StringName &p_extension_name) { + return additional_data.has(p_extension_name); +} + void GLTFNode::set_additional_data(const StringName &p_extension_name, Variant p_additional_data) { additional_data[p_extension_name] = p_additional_data; } + +NodePath GLTFNode::get_scene_node_path(Ref<GLTFState> p_state, bool p_handle_skeletons) { + Vector<StringName> path; + Vector<StringName> subpath; + Ref<GLTFNode> current_gltf_node = this; + const int gltf_node_count = p_state->nodes.size(); + if (p_handle_skeletons && skeleton != -1) { + // Special case for skeleton nodes, skip all bones so that the path is to the Skeleton3D node. + // A path that would otherwise be `A/B/C/Bone1/Bone2/Bone3` becomes `A/B/C/Skeleton3D:Bone3`. + subpath.append(get_name()); + // The generated Skeleton3D node will be named Skeleton3D, so add it to the path. + path.append("Skeleton3D"); + do { + const int parent_index = current_gltf_node->get_parent(); + ERR_FAIL_INDEX_V(parent_index, gltf_node_count, NodePath()); + current_gltf_node = p_state->nodes[parent_index]; + } while (current_gltf_node->skeleton != -1); + } + const bool is_godot_single_root = p_state->extensions_used.has("GODOT_single_root"); + while (true) { + const int parent_index = current_gltf_node->get_parent(); + if (is_godot_single_root && parent_index == -1) { + // For GODOT_single_root scenes, the root glTF node becomes the Godot scene root, so it + // should not be included in the path. Ex: A/B/C, A is single root, we want B/C only. + break; + } + path.insert(0, current_gltf_node->get_name()); + if (!is_godot_single_root && parent_index == -1) { + break; + } + ERR_FAIL_INDEX_V(parent_index, gltf_node_count, NodePath()); + current_gltf_node = p_state->nodes[parent_index]; + } + if (unlikely(path.is_empty())) { + path.append("."); + } + return NodePath(path, subpath, false); +} diff --git a/modules/gltf/structures/gltf_node.h b/modules/gltf/structures/gltf_node.h index f3f6bfa2f1..f72b65a003 100644 --- a/modules/gltf/structures/gltf_node.h +++ b/modules/gltf/structures/gltf_node.h @@ -103,7 +103,10 @@ public: void set_light(GLTFLightIndex p_light); Variant get_additional_data(const StringName &p_extension_name); + bool has_additional_data(const StringName &p_extension_name); void set_additional_data(const StringName &p_extension_name, Variant p_additional_data); + + NodePath get_scene_node_path(Ref<GLTFState> p_state, bool p_handle_skeletons = true); }; #endif // GLTF_NODE_H diff --git a/modules/gltf/structures/gltf_object_model_property.cpp b/modules/gltf/structures/gltf_object_model_property.cpp new file mode 100644 index 0000000000..d405c362db --- /dev/null +++ b/modules/gltf/structures/gltf_object_model_property.cpp @@ -0,0 +1,173 @@ +/**************************************************************************/ +/* gltf_object_model_property.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "gltf_object_model_property.h" + +#include "../gltf_template_convert.h" + +void GLTFObjectModelProperty::_bind_methods() { + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_UNKNOWN); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_BOOL); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT_ARRAY); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT2); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT3); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT4); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT2X2); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT3X3); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT4X4); + BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_INT); + + ClassDB::bind_method(D_METHOD("append_node_path", "node_path"), &GLTFObjectModelProperty::append_node_path); + ClassDB::bind_method(D_METHOD("append_path_to_property", "node_path", "prop_name"), &GLTFObjectModelProperty::append_path_to_property); + + ClassDB::bind_method(D_METHOD("get_accessor_type"), &GLTFObjectModelProperty::get_accessor_type); + ClassDB::bind_method(D_METHOD("get_gltf_to_godot_expression"), &GLTFObjectModelProperty::get_gltf_to_godot_expression); + ClassDB::bind_method(D_METHOD("set_gltf_to_godot_expression", "gltf_to_godot_expr"), &GLTFObjectModelProperty::set_gltf_to_godot_expression); + ClassDB::bind_method(D_METHOD("get_godot_to_gltf_expression"), &GLTFObjectModelProperty::get_godot_to_gltf_expression); + ClassDB::bind_method(D_METHOD("set_godot_to_gltf_expression", "godot_to_gltf_expr"), &GLTFObjectModelProperty::set_godot_to_gltf_expression); + ClassDB::bind_method(D_METHOD("get_node_paths"), &GLTFObjectModelProperty::get_node_paths); + ClassDB::bind_method(D_METHOD("has_node_paths"), &GLTFObjectModelProperty::has_node_paths); + ClassDB::bind_method(D_METHOD("set_node_paths", "node_paths"), &GLTFObjectModelProperty::set_node_paths); + ClassDB::bind_method(D_METHOD("get_object_model_type"), &GLTFObjectModelProperty::get_object_model_type); + ClassDB::bind_method(D_METHOD("set_object_model_type", "type"), &GLTFObjectModelProperty::set_object_model_type); + ClassDB::bind_method(D_METHOD("get_json_pointers"), &GLTFObjectModelProperty::get_json_pointers_bind); + ClassDB::bind_method(D_METHOD("has_json_pointers"), &GLTFObjectModelProperty::has_json_pointers); + ClassDB::bind_method(D_METHOD("set_json_pointers", "json_pointers"), &GLTFObjectModelProperty::set_json_pointers_bind); + ClassDB::bind_method(D_METHOD("get_variant_type"), &GLTFObjectModelProperty::get_variant_type); + ClassDB::bind_method(D_METHOD("set_variant_type", "variant_type"), &GLTFObjectModelProperty::set_variant_type); + ClassDB::bind_method(D_METHOD("set_types", "variant_type", "obj_model_type"), &GLTFObjectModelProperty::set_types); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gltf_to_godot_expression", PROPERTY_HINT_RESOURCE_TYPE, "Expression"), "set_gltf_to_godot_expression", "get_gltf_to_godot_expression"); // Ref<Expression> + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "godot_to_gltf_expression", PROPERTY_HINT_RESOURCE_TYPE, "Expression"), "set_godot_to_gltf_expression", "get_godot_to_gltf_expression"); // Ref<Expression> + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "node_paths", PROPERTY_HINT_TYPE_STRING, "NodePath"), "set_node_paths", "get_node_paths"); // TypedArray<NodePath> + ADD_PROPERTY(PropertyInfo(Variant::INT, "object_model_type"), "set_object_model_type", "get_object_model_type"); // GLTFObjectModelType + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "json_pointers"), "set_json_pointers", "get_json_pointers"); // TypedArray<PackedStringArray> + ADD_PROPERTY(PropertyInfo(Variant::INT, "variant_type"), "set_variant_type", "get_variant_type"); // Variant::Type +} + +void GLTFObjectModelProperty::append_node_path(const NodePath &p_node_path) { + node_paths.push_back(p_node_path); +} + +void GLTFObjectModelProperty::append_path_to_property(const NodePath &p_node_path, const StringName &p_prop_name) { + Vector<StringName> node_names = p_node_path.get_names(); + Vector<StringName> subpath = p_node_path.get_subnames(); + subpath.append(p_prop_name); + node_paths.push_back(NodePath(node_names, subpath, false)); +} + +GLTFAccessor::GLTFAccessorType GLTFObjectModelProperty::get_accessor_type() const { + switch (object_model_type) { + case GLTF_OBJECT_MODEL_TYPE_FLOAT2: + return GLTFAccessor::TYPE_VEC2; + case GLTF_OBJECT_MODEL_TYPE_FLOAT3: + return GLTFAccessor::TYPE_VEC3; + case GLTF_OBJECT_MODEL_TYPE_FLOAT4: + return GLTFAccessor::TYPE_VEC4; + case GLTF_OBJECT_MODEL_TYPE_FLOAT2X2: + return GLTFAccessor::TYPE_MAT2; + case GLTF_OBJECT_MODEL_TYPE_FLOAT3X3: + return GLTFAccessor::TYPE_MAT3; + case GLTF_OBJECT_MODEL_TYPE_FLOAT4X4: + return GLTFAccessor::TYPE_MAT4; + default: + return GLTFAccessor::TYPE_SCALAR; + } +} + +Ref<Expression> GLTFObjectModelProperty::get_gltf_to_godot_expression() const { + return gltf_to_godot_expr; +} + +void GLTFObjectModelProperty::set_gltf_to_godot_expression(Ref<Expression> p_gltf_to_godot_expr) { + gltf_to_godot_expr = p_gltf_to_godot_expr; +} + +Ref<Expression> GLTFObjectModelProperty::get_godot_to_gltf_expression() const { + return godot_to_gltf_expr; +} + +void GLTFObjectModelProperty::set_godot_to_gltf_expression(Ref<Expression> p_godot_to_gltf_expr) { + godot_to_gltf_expr = p_godot_to_gltf_expr; +} + +TypedArray<NodePath> GLTFObjectModelProperty::get_node_paths() const { + return node_paths; +} + +bool GLTFObjectModelProperty::has_node_paths() const { + return !node_paths.is_empty(); +} + +void GLTFObjectModelProperty::set_node_paths(TypedArray<NodePath> p_node_paths) { + node_paths = p_node_paths; +} + +GLTFObjectModelProperty::GLTFObjectModelType GLTFObjectModelProperty::get_object_model_type() const { + return object_model_type; +} + +void GLTFObjectModelProperty::set_object_model_type(GLTFObjectModelType p_type) { + object_model_type = p_type; +} + +Vector<PackedStringArray> GLTFObjectModelProperty::get_json_pointers() const { + return json_pointers; +} + +bool GLTFObjectModelProperty::has_json_pointers() const { + return !json_pointers.is_empty(); +} + +void GLTFObjectModelProperty::set_json_pointers(const Vector<PackedStringArray> &p_json_pointers) { + json_pointers = p_json_pointers; +} + +TypedArray<PackedStringArray> GLTFObjectModelProperty::get_json_pointers_bind() const { + return GLTFTemplateConvert::to_array(json_pointers); +} + +void GLTFObjectModelProperty::set_json_pointers_bind(const TypedArray<PackedStringArray> &p_json_pointers) { + GLTFTemplateConvert::set_from_array(json_pointers, p_json_pointers); +} + +Variant::Type GLTFObjectModelProperty::get_variant_type() const { + return variant_type; +} + +void GLTFObjectModelProperty::set_variant_type(Variant::Type p_variant_type) { + variant_type = p_variant_type; +} + +void GLTFObjectModelProperty::set_types(Variant::Type p_variant_type, GLTFObjectModelType p_obj_model_type) { + variant_type = p_variant_type; + object_model_type = p_obj_model_type; +} diff --git a/modules/gltf/structures/gltf_object_model_property.h b/modules/gltf/structures/gltf_object_model_property.h new file mode 100644 index 0000000000..d8a4ed420a --- /dev/null +++ b/modules/gltf/structures/gltf_object_model_property.h @@ -0,0 +1,104 @@ +/**************************************************************************/ +/* gltf_object_model_property.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 GLTF_OBJECT_MODEL_PROPERTY_H +#define GLTF_OBJECT_MODEL_PROPERTY_H + +#include "core/math/expression.h" +#include "core/variant/typed_array.h" +#include "gltf_accessor.h" + +// Object model: https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc +// KHR_animation_pointer: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_animation_pointer + +class GLTFObjectModelProperty : public RefCounted { + GDCLASS(GLTFObjectModelProperty, RefCounted); + +public: + enum GLTFObjectModelType { + GLTF_OBJECT_MODEL_TYPE_UNKNOWN, + GLTF_OBJECT_MODEL_TYPE_BOOL, + GLTF_OBJECT_MODEL_TYPE_FLOAT, + GLTF_OBJECT_MODEL_TYPE_FLOAT_ARRAY, + GLTF_OBJECT_MODEL_TYPE_FLOAT2, + GLTF_OBJECT_MODEL_TYPE_FLOAT3, + GLTF_OBJECT_MODEL_TYPE_FLOAT4, + GLTF_OBJECT_MODEL_TYPE_FLOAT2X2, + GLTF_OBJECT_MODEL_TYPE_FLOAT3X3, + GLTF_OBJECT_MODEL_TYPE_FLOAT4X4, + GLTF_OBJECT_MODEL_TYPE_INT, + }; + +private: + Ref<Expression> gltf_to_godot_expr; + Ref<Expression> godot_to_gltf_expr; + TypedArray<NodePath> node_paths; + GLTFObjectModelType object_model_type = GLTF_OBJECT_MODEL_TYPE_UNKNOWN; + Vector<PackedStringArray> json_pointers; + Variant::Type variant_type = Variant::NIL; + +protected: + static void _bind_methods(); + +public: + void append_node_path(const NodePath &p_node_path); + void append_path_to_property(const NodePath &p_node_path, const StringName &p_prop_name); + + GLTFAccessor::GLTFAccessorType get_accessor_type() const; + + Ref<Expression> get_gltf_to_godot_expression() const; + void set_gltf_to_godot_expression(Ref<Expression> p_gltf_to_godot_expr); + + Ref<Expression> get_godot_to_gltf_expression() const; + void set_godot_to_gltf_expression(Ref<Expression> p_godot_to_gltf_expr); + + TypedArray<NodePath> get_node_paths() const; + bool has_node_paths() const; + void set_node_paths(TypedArray<NodePath> p_node_paths); + + GLTFObjectModelType get_object_model_type() const; + void set_object_model_type(GLTFObjectModelType p_type); + + Vector<PackedStringArray> get_json_pointers() const; + bool has_json_pointers() const; + void set_json_pointers(const Vector<PackedStringArray> &p_json_pointers); + + TypedArray<PackedStringArray> get_json_pointers_bind() const; + void set_json_pointers_bind(const TypedArray<PackedStringArray> &p_json_pointers); + + Variant::Type get_variant_type() const; + void set_variant_type(Variant::Type p_variant_type); + + void set_types(Variant::Type p_variant_type, GLTFObjectModelType p_obj_model_type); +}; + +VARIANT_ENUM_CAST(GLTFObjectModelProperty::GLTFObjectModelType); + +#endif // GLTF_OBJECT_MODEL_PROPERTY_H diff --git a/modules/godot_physics_2d/godot_joints_2d.cpp b/modules/godot_physics_2d/godot_joints_2d.cpp index 5c76eb9dad..d5a779ebb5 100644 --- a/modules/godot_physics_2d/godot_joints_2d.cpp +++ b/modules/godot_physics_2d/godot_joints_2d.cpp @@ -311,7 +311,7 @@ bool GodotPinJoint2D::get_flag(PhysicsServer2D::PinJointFlag p_flag) const { return motor_enabled; } } - ERR_FAIL_V(0); + ERR_FAIL_V(false); } GodotPinJoint2D::GodotPinJoint2D(const Vector2 &p_pos, GodotBody2D *p_body_a, GodotBody2D *p_body_b) : diff --git a/modules/godot_physics_2d/godot_physics_server_2d.cpp b/modules/godot_physics_2d/godot_physics_server_2d.cpp index 71d1d3b6b1..2516ed3616 100644 --- a/modules/godot_physics_2d/godot_physics_server_2d.cpp +++ b/modules/godot_physics_2d/godot_physics_server_2d.cpp @@ -1169,8 +1169,8 @@ void GodotPhysicsServer2D::pin_joint_set_flag(RID p_joint, PinJointFlag p_flag, bool GodotPhysicsServer2D::pin_joint_get_flag(RID p_joint, PinJointFlag p_flag) const { GodotJoint2D *joint = joint_owner.get_or_null(p_joint); - ERR_FAIL_NULL_V(joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); + ERR_FAIL_NULL_V(joint, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, false); GodotPinJoint2D *pin_joint = static_cast<GodotPinJoint2D *>(joint); return pin_joint->get_flag(p_flag); diff --git a/modules/godot_physics_2d/godot_space_2d.cpp b/modules/godot_physics_2d/godot_space_2d.cpp index 2966818beb..df3c9d8265 100644 --- a/modules/godot_physics_2d/godot_space_2d.cpp +++ b/modules/godot_physics_2d/godot_space_2d.cpp @@ -342,7 +342,7 @@ bool GodotPhysicsDirectSpaceState2D::collide_shape(const ShapeParameters &p_para } GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid); - ERR_FAIL_NULL_V(shape, 0); + ERR_FAIL_NULL_V(shape, false); Rect2 aabb = p_parameters.transform.xform(shape->get_aabb()); aabb = aabb.merge(Rect2(aabb.position + p_parameters.motion, aabb.size)); //motion @@ -439,7 +439,7 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, bool GodotPhysicsDirectSpaceState2D::rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) { GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid); - ERR_FAIL_NULL_V(shape, 0); + ERR_FAIL_NULL_V(shape, false); real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE); diff --git a/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp index c53c8481f4..2adbb51297 100644 --- a/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp +++ b/modules/godot_physics_3d/godot_collision_solver_3d_sat.cpp @@ -76,8 +76,9 @@ struct _CollectorCallback { Vector3 *prev_axis = nullptr; _FORCE_INLINE_ void call(const Vector3 &p_point_A, const Vector3 &p_point_B, Vector3 p_normal) { - if (p_normal.dot(p_point_B - p_point_A) < 0) + if (p_normal.dot(p_point_B - p_point_A) < 0) { p_normal = -p_normal; + } if (swap) { callback(p_point_B, 0, p_point_A, 0, -p_normal, userdata); } else { @@ -175,10 +176,11 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_ // The normal should be perpendicular to both edges. Vector3 normal = rel_A.cross(rel_B); real_t normal_len = normal.length(); - if (normal_len > 1e-3) + if (normal_len > 1e-3) { normal /= normal_len; - else + } else { normal = p_callback->normal; + } p_callback->call(closest_A, closest_B, normal); } @@ -784,8 +786,9 @@ static void analytic_sphere_collision(const Vector3 &p_origin_a, real_t p_radius // Calculate the sphere overlap, and bail if not overlapping real_t overlap = p_radius_a + p_radius_b - b_to_a_len; - if (overlap < 0) + if (overlap < 0) { return; + } // Report collision p_collector->collided = true; diff --git a/modules/godot_physics_3d/godot_physics_server_3d.cpp b/modules/godot_physics_3d/godot_physics_server_3d.cpp index 43f8d2658d..ad55e415e6 100644 --- a/modules/godot_physics_3d/godot_physics_server_3d.cpp +++ b/modules/godot_physics_3d/godot_physics_server_3d.cpp @@ -826,7 +826,7 @@ void GodotPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool bool GodotPhysicsServer3D::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { const GodotBody3D *body = body_owner.get_or_null(p_body); - ERR_FAIL_NULL_V(body, 0); + ERR_FAIL_NULL_V(body, false); return body->is_axis_locked(p_axis); } diff --git a/modules/godot_physics_3d/godot_shape_3d.cpp b/modules/godot_physics_3d/godot_shape_3d.cpp index 70b6bcf19e..a7cccc5cb8 100644 --- a/modules/godot_physics_3d/godot_shape_3d.cpp +++ b/modules/godot_physics_3d/godot_shape_3d.cpp @@ -1133,8 +1133,9 @@ void GodotConvexPolygonShape3D::_setup(const Vector<Vector3> &p_vertices) { max_support = s; } } - if (!extreme_vertices.has(best_vertex)) + if (!extreme_vertices.has(best_vertex)) { extreme_vertices.push_back(best_vertex); + } } } } diff --git a/modules/godot_physics_3d/godot_space_3d.cpp b/modules/godot_physics_3d/godot_space_3d.cpp index 9a6ba776b4..9f82a87f85 100644 --- a/modules/godot_physics_3d/godot_space_3d.cpp +++ b/modules/godot_physics_3d/godot_space_3d.cpp @@ -385,7 +385,7 @@ bool GodotPhysicsDirectSpaceState3D::collide_shape(const ShapeParameters &p_para } GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid); - ERR_FAIL_NULL_V(shape, 0); + ERR_FAIL_NULL_V(shape, false); AABB aabb = p_parameters.transform.xform(shape->get_aabb()); aabb = aabb.grow(p_parameters.margin); @@ -511,7 +511,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, int p_index_A, const Vect bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) { GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid); - ERR_FAIL_NULL_V(shape, 0); + ERR_FAIL_NULL_V(shape, false); real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE); diff --git a/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp index 226f8a0f7f..5f9cf9de49 100644 --- a/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp +++ b/modules/godot_physics_3d/joints/godot_generic_6dof_joint_3d.cpp @@ -647,7 +647,7 @@ void GodotGeneric6DOFJoint3D::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6 } bool GodotGeneric6DOFJoint3D::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const { - ERR_FAIL_INDEX_V(p_axis, 3, 0); + ERR_FAIL_INDEX_V(p_axis, 3, false); switch (p_flag) { case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: { return m_linearLimits.enable_limit[p_axis]; diff --git a/modules/interactive_music/doc_classes/AudioStreamInteractive.xml b/modules/interactive_music/doc_classes/AudioStreamInteractive.xml index 17448724d1..d47d6ecde6 100644 --- a/modules/interactive_music/doc_classes/AudioStreamInteractive.xml +++ b/modules/interactive_music/doc_classes/AudioStreamInteractive.xml @@ -119,7 +119,7 @@ <param index="0" name="from_clip" type="int" /> <param index="1" name="to_clip" type="int" /> <description> - Return true if a given transition exists (was added via [method add_transition]). + Returns [code]true[/code] if a given transition exists (was added via [method add_transition]). </description> </method> <method name="is_transition_holding_previous" qualifiers="const"> diff --git a/modules/meshoptimizer/register_types.cpp b/modules/meshoptimizer/register_types.cpp index 781f928f66..ebfe5d9c5b 100644 --- a/modules/meshoptimizer/register_types.cpp +++ b/modules/meshoptimizer/register_types.cpp @@ -40,10 +40,10 @@ void initialize_meshoptimizer_module(ModuleInitializationLevel p_level) { } SurfaceTool::optimize_vertex_cache_func = meshopt_optimizeVertexCache; + SurfaceTool::optimize_vertex_fetch_remap_func = meshopt_optimizeVertexFetchRemap; SurfaceTool::simplify_func = meshopt_simplify; SurfaceTool::simplify_with_attrib_func = meshopt_simplifyWithAttributes; SurfaceTool::simplify_scale_func = meshopt_simplifyScale; - SurfaceTool::simplify_sloppy_func = meshopt_simplifySloppy; SurfaceTool::generate_remap_func = meshopt_generateVertexRemap; SurfaceTool::remap_vertex_func = meshopt_remapVertexBuffer; SurfaceTool::remap_index_func = meshopt_remapIndexBuffer; @@ -55,9 +55,9 @@ void uninitialize_meshoptimizer_module(ModuleInitializationLevel p_level) { } SurfaceTool::optimize_vertex_cache_func = nullptr; + SurfaceTool::optimize_vertex_fetch_remap_func = nullptr; SurfaceTool::simplify_func = nullptr; SurfaceTool::simplify_scale_func = nullptr; - SurfaceTool::simplify_sloppy_func = nullptr; SurfaceTool::generate_remap_func = nullptr; SurfaceTool::remap_vertex_func = nullptr; SurfaceTool::remap_index_func = nullptr; diff --git a/modules/minimp3/doc_classes/ResourceImporterMP3.xml b/modules/minimp3/doc_classes/ResourceImporterMP3.xml index 72868623c7..fc0ec3682b 100644 --- a/modules/minimp3/doc_classes/ResourceImporterMP3.xml +++ b/modules/minimp3/doc_classes/ResourceImporterMP3.xml @@ -13,15 +13,15 @@ </tutorials> <members> <member name="bar_beats" type="int" setter="" getter="" default="4"> - The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects. + The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects. A more convenient editor for [member bar_beats] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio. </member> <member name="beat_count" type="int" setter="" getter="" default="0"> - The beat count of the audio track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects. + The beat count of the audio track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects. A more convenient editor for [member beat_count] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio. </member> <member name="bpm" type="float" setter="" getter="" default="0"> - The Beats Per Minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects. + The beats per minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects. A more convenient editor for [member bpm] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio. </member> <member name="loop" type="bool" setter="" getter="" default="false"> diff --git a/modules/minimp3/resource_importer_mp3.h b/modules/minimp3/resource_importer_mp3.h index 2df44deaea..037756328f 100644 --- a/modules/minimp3/resource_importer_mp3.h +++ b/modules/minimp3/resource_importer_mp3.h @@ -59,6 +59,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterMP3(); }; diff --git a/modules/navigation/3d/nav_mesh_queries_3d.cpp b/modules/navigation/3d/nav_mesh_queries_3d.cpp index 70207f86ce..5acc598d43 100644 --- a/modules/navigation/3d/nav_mesh_queries_3d.cpp +++ b/modules/navigation/3d/nav_mesh_queries_3d.cpp @@ -234,7 +234,7 @@ Vector<Vector3> NavMeshQueries3D::polygons_get_path(const LocalVector<gd::Polygo // Takes the current least_cost_poly neighbors (iterating over its edges) and compute the traveled_distance. for (const gd::Edge &edge : navigation_polys[least_cost_id].poly->edges) { // Iterate over connections in this edge, then compute the new optimized travel distance assigned to this polygon. - for (int connection_index = 0; connection_index < edge.connections.size(); connection_index++) { + for (uint32_t connection_index = 0; connection_index < edge.connections.size(); connection_index++) { const gd::Edge::Connection &connection = edge.connections[connection_index]; // Only consider the connection to another polygon if this polygon is in a region with compatible layers. diff --git a/modules/navigation/nav_agent.h b/modules/navigation/nav_agent.h index e3671504f2..d56e053ac4 100644 --- a/modules/navigation/nav_agent.h +++ b/modules/navigation/nav_agent.h @@ -67,7 +67,7 @@ class NavAgent : public NavRid { uint32_t avoidance_mask = 1; real_t avoidance_priority = 1.0; - Callable avoidance_callback = Callable(); + Callable avoidance_callback; bool agent_dirty = true; diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 8df1db533d..8055dd4bc8 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -427,25 +427,36 @@ void NavMap::sync() { _new_pm_polygon_count = polygon_count; // Group all edges per key. - HashMap<gd::EdgeKey, Vector<gd::Edge::Connection>, gd::EdgeKey> connections; + connection_pairs_map.clear(); + connection_pairs_map.reserve(polygons.size()); + int free_edges_count = 0; // How many ConnectionPairs have only one Connection. + for (gd::Polygon &poly : polygons) { for (uint32_t p = 0; p < poly.points.size(); p++) { - int next_point = (p + 1) % poly.points.size(); - gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key); + const int next_point = (p + 1) % poly.points.size(); + const gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key); - HashMap<gd::EdgeKey, Vector<gd::Edge::Connection>, gd::EdgeKey>::Iterator connection = connections.find(ek); - if (!connection) { - connections[ek] = Vector<gd::Edge::Connection>(); + HashMap<gd::EdgeKey, ConnectionPair, gd::EdgeKey>::Iterator pair_it = connection_pairs_map.find(ek); + if (!pair_it) { + pair_it = connection_pairs_map.insert(ek, ConnectionPair()); _new_pm_edge_count += 1; + ++free_edges_count; } - if (connections[ek].size() <= 1) { + ConnectionPair &pair = pair_it->value; + if (pair.size < 2) { // Add the polygon/edge tuple to this key. gd::Edge::Connection new_connection; new_connection.polygon = &poly; new_connection.edge = p; new_connection.pathway_start = poly.points[p].pos; new_connection.pathway_end = poly.points[next_point].pos; - connections[ek].push_back(new_connection); + + pair.connections[pair.size] = new_connection; + ++pair.size; + if (pair.size == 2) { + --free_edges_count; + } + } else { // The edge is already connected with another edge, skip. ERR_PRINT_ONCE("Navigation map synchronization error. Attempted to merge a navigation mesh polygon edge with another already-merged edge. This is usually caused by crossing edges, overlapping polygons, or a mismatch of the NavigationMesh / NavigationPolygon baked 'cell_size' and navigation map 'cell_size'. If you're certain none of above is the case, change 'navigation/3d/merge_rasterizer_cell_scale' to 0.001."); @@ -453,20 +464,23 @@ void NavMap::sync() { } } - Vector<gd::Edge::Connection> free_edges; - for (KeyValue<gd::EdgeKey, Vector<gd::Edge::Connection>> &E : connections) { - if (E.value.size() == 2) { + free_edges.clear(); + free_edges.reserve(free_edges_count); + + for (const KeyValue<gd::EdgeKey, ConnectionPair> &pair_it : connection_pairs_map) { + const ConnectionPair &pair = pair_it.value; + if (pair.size == 2) { // Connect edge that are shared in different polygons. - gd::Edge::Connection &c1 = E.value.write[0]; - gd::Edge::Connection &c2 = E.value.write[1]; + const gd::Edge::Connection &c1 = pair.connections[0]; + const gd::Edge::Connection &c2 = pair.connections[1]; c1.polygon->edges[c1.edge].connections.push_back(c2); c2.polygon->edges[c2.edge].connections.push_back(c1); // Note: The pathway_start/end are full for those connection and do not need to be modified. _new_pm_edge_merge_count += 1; } else { - CRASH_COND_MSG(E.value.size() != 1, vformat("Number of connection != 1. Found: %d", E.value.size())); - if (use_edge_connections && E.value[0].polygon->owner->get_use_edge_connections()) { - free_edges.push_back(E.value[0]); + CRASH_COND_MSG(pair.size != 1, vformat("Number of connection != 1. Found: %d", pair.size)); + if (use_edge_connections && pair.connections[0].polygon->owner->get_use_edge_connections()) { + free_edges.push_back(pair.connections[0]); } } } @@ -480,14 +494,14 @@ void NavMap::sync() { // connection, integration and path finding. _new_pm_edge_free_count = free_edges.size(); - real_t sqr_edge_connection_margin = edge_connection_margin * edge_connection_margin; + const real_t edge_connection_margin_squared = edge_connection_margin * edge_connection_margin; - for (int i = 0; i < free_edges.size(); i++) { + for (uint32_t i = 0; i < free_edges.size(); i++) { const gd::Edge::Connection &free_edge = free_edges[i]; Vector3 edge_p1 = free_edge.polygon->points[free_edge.edge].pos; Vector3 edge_p2 = free_edge.polygon->points[(free_edge.edge + 1) % free_edge.polygon->points.size()].pos; - for (int j = 0; j < free_edges.size(); j++) { + for (uint32_t j = 0; j < free_edges.size(); j++) { const gd::Edge::Connection &other_edge = free_edges[j]; if (i == j || free_edge.polygon->owner == other_edge.polygon->owner) { continue; @@ -512,7 +526,7 @@ void NavMap::sync() { } else { other1 = other_edge_p1.lerp(other_edge_p2, (1.0 - projected_p1_ratio) / (projected_p2_ratio - projected_p1_ratio)); } - if (other1.distance_squared_to(self1) > sqr_edge_connection_margin) { + if (other1.distance_squared_to(self1) > edge_connection_margin_squared) { continue; } @@ -523,7 +537,7 @@ void NavMap::sync() { } else { other2 = other_edge_p1.lerp(other_edge_p2, (0.0 - projected_p1_ratio) / (projected_p2_ratio - projected_p1_ratio)); } - if (other2.distance_squared_to(self2) > sqr_edge_connection_margin) { + if (other2.distance_squared_to(self2) > edge_connection_margin_squared) { continue; } diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index b9120c04d9..3442b78497 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -128,6 +128,14 @@ class NavMap : public NavRid { HashMap<NavRegion *, LocalVector<gd::Edge::Connection>> region_external_connections; + struct ConnectionPair { + gd::Edge::Connection connections[2]; + int size = 0; + }; + + HashMap<gd::EdgeKey, ConnectionPair, gd::EdgeKey> connection_pairs_map; + LocalVector<gd::Edge::Connection> free_edges; + public: NavMap(); ~NavMap(); diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index ba4c44b748..c466c82fc7 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -94,7 +94,7 @@ struct Edge { }; /// Connections from this edge to other polygons. - Vector<Connection> connections; + LocalVector<Connection> connections; }; struct Polygon { diff --git a/modules/openxr/doc_classes/OpenXRCompositionLayer.xml b/modules/openxr/doc_classes/OpenXRCompositionLayer.xml index 341b50065c..cfc7cd4d97 100644 --- a/modules/openxr/doc_classes/OpenXRCompositionLayer.xml +++ b/modules/openxr/doc_classes/OpenXRCompositionLayer.xml @@ -29,7 +29,7 @@ <method name="is_natively_supported" qualifiers="const"> <return type="bool" /> <description> - Returns true if the OpenXR runtime natively supports this composition layer type. + Returns [code]true[/code] if the OpenXR runtime natively supports this composition layer type. [b]Note:[/b] This will only return an accurate result after the OpenXR session has started. </description> </method> diff --git a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml index 813c9d582e..182fe32f9c 100644 --- a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml +++ b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml @@ -90,6 +90,21 @@ Called right after the main swapchains are (re)created. </description> </method> + <method name="_on_post_draw_viewport" qualifiers="virtual"> + <return type="void" /> + <param index="0" name="viewport" type="RID" /> + <description> + Called right after the given viewport is rendered. + [b]Note:[/b] The draw commands might only be queued at this point, not executed. + </description> + </method> + <method name="_on_pre_draw_viewport" qualifiers="virtual"> + <return type="void" /> + <param index="0" name="viewport" type="RID" /> + <description> + Called right before the given viewport is rendered. + </description> + </method> <method name="_on_pre_render" qualifiers="virtual"> <return type="void" /> <description> diff --git a/modules/openxr/extensions/openxr_composition_layer_extension.cpp b/modules/openxr/extensions/openxr_composition_layer_extension.cpp index dc30b95b27..2d29b8a82c 100644 --- a/modules/openxr/extensions/openxr_composition_layer_extension.cpp +++ b/modules/openxr/extensions/openxr_composition_layer_extension.cpp @@ -341,7 +341,7 @@ XrCompositionLayerBaseHeader *OpenXRViewportCompositionLayerProvider::get_compos } XrSwapchainSubImage subimage = { - 0, // swapchain + 0, // swapchain // NOLINT(modernize-use-nullptr) - 32-bit uses non-pointer uint64 { { 0, 0 }, { 0, 0 } }, // imageRect 0, // imageArrayIndex }; diff --git a/modules/openxr/extensions/openxr_debug_utils_extension.cpp b/modules/openxr/extensions/openxr_debug_utils_extension.cpp index 10dbe629f7..cb7f72d02d 100644 --- a/modules/openxr/extensions/openxr_debug_utils_extension.cpp +++ b/modules/openxr/extensions/openxr_debug_utils_extension.cpp @@ -173,7 +173,7 @@ void OpenXRDebugUtilsExtension::begin_debug_label_region(const char *p_label_nam const XrDebugUtilsLabelEXT session_active_region_label = { XR_TYPE_DEBUG_UTILS_LABEL_EXT, // type - NULL, // next + nullptr, // next p_label_name, // labelName }; @@ -199,7 +199,7 @@ void OpenXRDebugUtilsExtension::insert_debug_label(const char *p_label_name) { const XrDebugUtilsLabelEXT session_active_region_label = { XR_TYPE_DEBUG_UTILS_LABEL_EXT, // type - NULL, // next + nullptr, // next p_label_name, // labelName }; diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp index 07ca476421..fb8d1b9d69 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp +++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.cpp @@ -51,6 +51,8 @@ void OpenXRExtensionWrapperExtension::_bind_methods() { GDVIRTUAL_BIND(_on_process); GDVIRTUAL_BIND(_on_pre_render); GDVIRTUAL_BIND(_on_main_swapchains_created); + GDVIRTUAL_BIND(_on_pre_draw_viewport, "viewport"); + GDVIRTUAL_BIND(_on_post_draw_viewport, "viewport"); GDVIRTUAL_BIND(_on_session_destroyed); GDVIRTUAL_BIND(_on_state_idle); GDVIRTUAL_BIND(_on_state_ready); @@ -208,6 +210,14 @@ void OpenXRExtensionWrapperExtension::on_session_destroyed() { GDVIRTUAL_CALL(_on_session_destroyed); } +void OpenXRExtensionWrapperExtension::on_pre_draw_viewport(RID p_render_target) { + GDVIRTUAL_CALL(_on_pre_draw_viewport, p_render_target); +} + +void OpenXRExtensionWrapperExtension::on_post_draw_viewport(RID p_render_target) { + GDVIRTUAL_CALL(_on_post_draw_viewport, p_render_target); +} + void OpenXRExtensionWrapperExtension::on_state_idle() { GDVIRTUAL_CALL(_on_state_idle); } @@ -298,8 +308,7 @@ void OpenXRExtensionWrapperExtension::register_extension_wrapper() { OpenXRAPI::register_extension_wrapper(this); } -OpenXRExtensionWrapperExtension::OpenXRExtensionWrapperExtension() : - Object(), OpenXRExtensionWrapper() { +OpenXRExtensionWrapperExtension::OpenXRExtensionWrapperExtension() { openxr_api.instantiate(); } diff --git a/modules/openxr/extensions/openxr_extension_wrapper_extension.h b/modules/openxr/extensions/openxr_extension_wrapper_extension.h index 5cdf288c93..8fc6511277 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper_extension.h +++ b/modules/openxr/extensions/openxr_extension_wrapper_extension.h @@ -88,6 +88,8 @@ public: virtual void on_pre_render() override; virtual void on_main_swapchains_created() override; virtual void on_session_destroyed() override; + virtual void on_pre_draw_viewport(RID p_render_target) override; + virtual void on_post_draw_viewport(RID p_render_target) override; GDVIRTUAL0(_on_register_metadata); GDVIRTUAL0(_on_before_instance_created); @@ -98,6 +100,8 @@ public: GDVIRTUAL0(_on_pre_render); GDVIRTUAL0(_on_main_swapchains_created); GDVIRTUAL0(_on_session_destroyed); + GDVIRTUAL1(_on_pre_draw_viewport, RID); + GDVIRTUAL1(_on_post_draw_viewport, RID); virtual void on_state_idle() override; virtual void on_state_ready() override; diff --git a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp index f75da49d87..4fcb3f7b75 100644 --- a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp +++ b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp @@ -193,7 +193,7 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex // spec says to use proper values but runtimes don't care graphics_binding_gl.visualid = 0; - graphics_binding_gl.glxFBConfig = 0; + graphics_binding_gl.glxFBConfig = nullptr; #endif #endif diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 715d24cfd9..a6fd727290 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -2752,8 +2752,9 @@ void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_l } bool OpenXRAPI::xr_result(XrResult result, const char *format, Array args) const { - if (XR_SUCCEEDED(result)) + if (XR_SUCCEEDED(result)) { return true; + } char resultString[XR_MAX_RESULT_STRING_SIZE]; xrResultToString(instance, result, resultString); diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 634c370b05..3609f5a554 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -90,18 +90,11 @@ void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D td.camera_dir = -p_cam_transform.basis.get_column(2); td.camera_orthogonal = p_cam_orthogonal; - Projection inv_camera_matrix = p_cam_projection.inverse(); - Vector3 camera_corner_proj = Vector3(-1.0f, -1.0f, -1.0f); - Vector3 camera_corner_view = inv_camera_matrix.xform(camera_corner_proj); - td.pixel_corner = p_cam_transform.xform(camera_corner_view); - - Vector3 top_corner_proj = Vector3(-1.0f, 1.0f, -1.0f); - Vector3 top_corner_view = inv_camera_matrix.xform(top_corner_proj); - Vector3 top_corner_world = p_cam_transform.xform(top_corner_view); - - Vector3 left_corner_proj = Vector3(1.0f, -1.0f, -1.0f); - Vector3 left_corner_view = inv_camera_matrix.xform(left_corner_proj); - Vector3 left_corner_world = p_cam_transform.xform(left_corner_view); + // Calculate the world coordinates of the viewport. + Vector2 viewport_half = p_cam_projection.get_viewport_half_extents(); + td.pixel_corner = p_cam_transform.xform(Vector3(-viewport_half.x, -viewport_half.y, -p_cam_projection.get_z_near())); + Vector3 top_corner_world = p_cam_transform.xform(Vector3(-viewport_half.x, viewport_half.y, -p_cam_projection.get_z_near())); + Vector3 left_corner_world = p_cam_transform.xform(Vector3(viewport_half.x, -viewport_half.y, -p_cam_projection.get_z_near())); td.pixel_u_interp = left_corner_world - td.pixel_corner; td.pixel_v_interp = top_corner_world - td.pixel_corner; diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 1c6e62650a..8d557aae2a 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -5264,42 +5264,44 @@ void TextServerAdvanced::_shaped_text_overrun_trim_to_width(const RID &p_shaped_ // Find usable fonts, if fonts from the last glyph do not have required chars. RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; - if (!_font_has_char(dot_gl_font_rid, sd->el_char)) { - const Array &fonts = spans[spans.size() - 1].fonts; - for (int i = 0; i < fonts.size(); i++) { - if (_font_has_char(fonts[i], sd->el_char)) { - dot_gl_font_rid = fonts[i]; - found_el_char = true; - break; - } - } - if (!found_el_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { - const char32_t u32str[] = { sd->el_char, 0 }; - RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, u32str); - if (rid.is_valid()) { - dot_gl_font_rid = rid; - found_el_char = true; - } - } - } else { - found_el_char = true; - } - if (!found_el_char) { - bool found_dot_char = false; - dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; - if (!_font_has_char(dot_gl_font_rid, '.')) { + if (add_ellipsis || enforce_ellipsis) { + if (!_font_has_char(dot_gl_font_rid, sd->el_char)) { const Array &fonts = spans[spans.size() - 1].fonts; for (int i = 0; i < fonts.size(); i++) { - if (_font_has_char(fonts[i], '.')) { + if (_font_has_char(fonts[i], sd->el_char)) { dot_gl_font_rid = fonts[i]; - found_dot_char = true; + found_el_char = true; break; } } - if (!found_dot_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { - RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, "."); + if (!found_el_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { + const char32_t u32str[] = { sd->el_char, 0 }; + RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, u32str); if (rid.is_valid()) { dot_gl_font_rid = rid; + found_el_char = true; + } + } + } else { + found_el_char = true; + } + if (!found_el_char) { + bool found_dot_char = false; + dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; + if (!_font_has_char(dot_gl_font_rid, '.')) { + const Array &fonts = spans[spans.size() - 1].fonts; + for (int i = 0; i < fonts.size(); i++) { + if (_font_has_char(fonts[i], '.')) { + dot_gl_font_rid = fonts[i]; + found_dot_char = true; + break; + } + } + if (!found_dot_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { + RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, "."); + if (rid.is_valid()) { + dot_gl_font_rid = rid; + } } } } @@ -5315,8 +5317,8 @@ void TextServerAdvanced::_shaped_text_overrun_trim_to_width(const RID &p_shaped_ } } - int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, (found_el_char ? sd->el_char : '.'), 0) : -1; - Vector2 dot_adv = dot_gl_font_rid.is_valid() ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2(); + int32_t dot_gl_idx = ((add_ellipsis || enforce_ellipsis) && dot_gl_font_rid.is_valid()) ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, (found_el_char ? sd->el_char : '.'), 0) : -1; + Vector2 dot_adv = ((add_ellipsis || enforce_ellipsis) && dot_gl_font_rid.is_valid()) ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2(); int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ', 0) : -1; Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2(); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index d30b2aae19..ae636a3151 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -4077,42 +4077,44 @@ void TextServerFallback::_shaped_text_overrun_trim_to_width(const RID &p_shaped_ // Find usable fonts, if fonts from the last glyph do not have required chars. RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; - if (!_font_has_char(dot_gl_font_rid, sd->el_char)) { - const Array &fonts = spans[spans.size() - 1].fonts; - for (int i = 0; i < fonts.size(); i++) { - if (_font_has_char(fonts[i], sd->el_char)) { - dot_gl_font_rid = fonts[i]; - found_el_char = true; - break; - } - } - if (!found_el_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { - const char32_t u32str[] = { sd->el_char, 0 }; - RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, u32str); - if (rid.is_valid()) { - dot_gl_font_rid = rid; - found_el_char = true; - } - } - } else { - found_el_char = true; - } - if (!found_el_char) { - bool found_dot_char = false; - dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; - if (!_font_has_char(dot_gl_font_rid, '.')) { + if (add_ellipsis || enforce_ellipsis) { + if (!_font_has_char(dot_gl_font_rid, sd->el_char)) { const Array &fonts = spans[spans.size() - 1].fonts; for (int i = 0; i < fonts.size(); i++) { - if (_font_has_char(fonts[i], '.')) { + if (_font_has_char(fonts[i], sd->el_char)) { dot_gl_font_rid = fonts[i]; - found_dot_char = true; + found_el_char = true; break; } } - if (!found_dot_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { - RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, "."); + if (!found_el_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { + const char32_t u32str[] = { sd->el_char, 0 }; + RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, u32str); if (rid.is_valid()) { dot_gl_font_rid = rid; + found_el_char = true; + } + } + } else { + found_el_char = true; + } + if (!found_el_char) { + bool found_dot_char = false; + dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid; + if (!_font_has_char(dot_gl_font_rid, '.')) { + const Array &fonts = spans[spans.size() - 1].fonts; + for (int i = 0; i < fonts.size(); i++) { + if (_font_has_char(fonts[i], '.')) { + dot_gl_font_rid = fonts[i]; + found_dot_char = true; + break; + } + } + if (!found_dot_char && OS::get_singleton()->has_feature("system_fonts") && fonts.size() > 0 && _font_is_allow_system_fallback(fonts[0])) { + RID rid = _find_sys_font_for_text(fonts[0], String(), spans[spans.size() - 1].language, "."); + if (rid.is_valid()) { + dot_gl_font_rid = rid; + } } } } @@ -4128,8 +4130,8 @@ void TextServerFallback::_shaped_text_overrun_trim_to_width(const RID &p_shaped_ } } - int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, (found_el_char ? sd->el_char : '.'), 0) : -1; - Vector2 dot_adv = dot_gl_font_rid.is_valid() ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2(); + int32_t dot_gl_idx = ((add_ellipsis || enforce_ellipsis) && dot_gl_font_rid.is_valid()) ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, (found_el_char ? sd->el_char : '.'), 0) : -1; + Vector2 dot_adv = ((add_ellipsis || enforce_ellipsis) && dot_gl_font_rid.is_valid()) ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2(); int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ', 0) : -1; Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2(); diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index f7c6ea899f..8b2c58acd5 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -115,7 +115,7 @@ void VideoStreamPlaybackTheora::video_write() { format = Image::FORMAT_RGBA8; } - Ref<Image> img = memnew(Image(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation + Ref<Image> img = memnew(Image(size.x, size.y, false, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation texture->update(img); //zero copy send to rendering server diff --git a/modules/vorbis/doc_classes/ResourceImporterOggVorbis.xml b/modules/vorbis/doc_classes/ResourceImporterOggVorbis.xml index 8ae63140f5..cede03c73a 100644 --- a/modules/vorbis/doc_classes/ResourceImporterOggVorbis.xml +++ b/modules/vorbis/doc_classes/ResourceImporterOggVorbis.xml @@ -29,15 +29,15 @@ </methods> <members> <member name="bar_beats" type="int" setter="" getter="" default="4"> - The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects. + The number of bars within a single beat in the audio track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects. A more convenient editor for [member bar_beats] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio. </member> <member name="beat_count" type="int" setter="" getter="" default="0"> - The beat count of the audio track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects. + The beat count of the audio track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects. A more convenient editor for [member beat_count] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio. </member> <member name="bpm" type="float" setter="" getter="" default="0"> - The Beats Per Minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to make use of interactive music functionality (not implemented yet), not sound effects. + The beats per minute of the audio track. This should match the BPM measure that was used to compose the track. This is only relevant for music that wishes to make use of interactive music functionality, not sound effects. A more convenient editor for [member bpm] is provided in the [b]Advanced Import Settings[/b] dialog, as it lets you preview your changes without having to reimport the audio. </member> <member name="loop" type="bool" setter="" getter="" default="false"> diff --git a/modules/vorbis/resource_importer_ogg_vorbis.h b/modules/vorbis/resource_importer_ogg_vorbis.h index 59ae3378a0..f378b80694 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.h +++ b/modules/vorbis/resource_importer_ogg_vorbis.h @@ -65,6 +65,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual bool can_import_threaded() const override { return true; } + ResourceImporterOggVorbis(); }; diff --git a/modules/webp/webp_common.cpp b/modules/webp/webp_common.cpp index 3a2ac5a90e..0284eec574 100644 --- a/modules/webp/webp_common.cpp +++ b/modules/webp/webp_common.cpp @@ -149,7 +149,7 @@ Ref<Image> _webp_unpack(const Vector<uint8_t> &p_buffer) { ERR_FAIL_COND_V_MSG(errdec, Ref<Image>(), "Failed decoding WebP image."); - Ref<Image> img = memnew(Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image)); + Ref<Image> img = memnew(Image(features.width, features.height, false, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image)); return img; } diff --git a/platform/SCsub b/platform/SCsub index 7c9d07f6ef..248b4b88dd 100644 --- a/platform/SCsub +++ b/platform/SCsub @@ -60,7 +60,7 @@ register_platform_apis = env.CommandNoCache( ) env.add_source_files(env.platform_sources, register_platform_apis) for platform in env.platform_apis: - env.add_source_files(env.platform_sources, f"{platform}/api/api.cpp") + env.add_source_files(env.platform_sources, f"{platform}/api/*.cpp") lib = env.add_library("platform", env.platform_sources) env.Prepend(LIBS=[lib]) diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 3c8b44a33f..38f6931c8a 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -203,6 +203,12 @@ void DisplayServerAndroid::emit_file_picker_callback(bool p_ok, const Vector<Str } } +Color DisplayServerAndroid::get_accent_color() const { + GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); + ERR_FAIL_NULL_V(godot_java, Color(0, 0, 0, 0)); + return godot_java->get_accent_color(); +} + TypedArray<Rect2> DisplayServerAndroid::get_display_cutouts() const { GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); ERR_FAIL_NULL_V(godot_io_java, Array()); @@ -243,14 +249,6 @@ DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(in return (ScreenOrientation)orientation; } -int DisplayServerAndroid::screen_get_internal_current_rotation(int p_screen) const { - GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); - ERR_FAIL_NULL_V(godot_io_java, 0); - - const int rotation = godot_io_java->get_internal_current_screen_rotation(); - return rotation; -} - int DisplayServerAndroid::get_screen_count() const { return 1; } diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 30f0f3dbed..1744ad3069 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -125,6 +125,8 @@ public: virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, const FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) override; void emit_file_picker_callback(bool p_ok, const Vector<String> &p_selected_paths); + virtual Color get_accent_color() const override; + virtual TypedArray<Rect2> get_display_cutouts() const override; virtual Rect2i get_display_safe_area() const override; @@ -133,7 +135,6 @@ public: virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override; virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; - virtual int screen_get_internal_current_rotation(int p_screen) const override; virtual int get_screen_count() const override; virtual int get_primary_screen() const override; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 93ac498ab3..d2b64c74a4 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -49,7 +49,9 @@ void register_android_exporter() { EDITOR_DEF_BASIC("export/android/debug_keystore_pass", DEFAULT_ANDROID_KEYSTORE_DEBUG_PASSWORD); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore_pass", PROPERTY_HINT_PASSWORD)); -#ifndef ANDROID_ENABLED +#ifdef ANDROID_ENABLED + EDITOR_DEF_BASIC("export/android/install_exported_apk", true); +#else EDITOR_DEF_BASIC("export/android/java_sdk_path", OS::get_singleton()->get_environment("JAVA_HOME")); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/java_sdk_path", PROPERTY_HINT_GLOBAL_DIR)); EDITOR_DEF_BASIC("export/android/android_sdk_path", OS::get_singleton()->get_environment("ANDROID_HOME")); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 41f460ca8f..aea09583b7 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1693,7 +1693,7 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> & path = static_cast<String>(p_preset->get(launcher_adaptive_icon_monochrome_option)).strip_edges(); if (!path.is_empty()) { print_verbose("Loading adaptive monochrome icon from " + path); - ImageLoader::load_image(path, background); + ImageLoader::load_image(path, monochrome); } } @@ -1778,6 +1778,12 @@ String EditorExportPlatformAndroid::get_export_option_warning(const EditorExport if (!is_package_name_valid(pn, &pn_err)) { return TTR("Invalid package name:") + " " + pn_err; } + } else if (p_name == launcher_adaptive_icon_monochrome_option) { + String monochrome_icon_path = p_preset->get(launcher_adaptive_icon_monochrome_option); + + if (monochrome_icon_path.is_empty()) { + return TTR("No adaptive monochrome icon specified; default Godot monochrome icon will be used."); + } } else if (p_name == "gradle_build/use_gradle_build") { bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build"); String enabled_plugins_names = _get_plugins_names(Ref<EditorExportPreset>(p_preset)); @@ -2887,6 +2893,14 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre #endif print_verbose("Successfully completed signing build."); + +#ifdef ANDROID_ENABLED + bool prompt_apk_install = EDITOR_GET("export/android/install_exported_apk"); + if (prompt_apk_install) { + OS_Android::get_singleton()->shell_open(apk_path); + } +#endif + return OK; } diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index a875745860..c1eb03b31f 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.VIBRATE" /> + <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <application android:allowBackup="false" diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt index 7b6d1f6bd1..6aa2ba7195 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt @@ -390,7 +390,7 @@ abstract class BaseGodotEditor : GodotActivity() { * If the launch policy is [LaunchPolicy.AUTO], resolve it into a specific policy based on the * editor setting or device and screen metrics. * - * If the launch policy is [LaunchPolicy.PIP] but PIP is not supported, fallback to the default + * If the launch policy is [LaunchPolicy.SAME_AND_LAUNCH_IN_PIP_MODE] but PIP is not supported, fallback to the default * launch policy. */ private fun resolveLaunchPolicyIfNeeded(policy: LaunchPolicy): LaunchPolicy { @@ -453,9 +453,9 @@ abstract class BaseGodotEditor : GodotActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) // Check if we got the MANAGE_EXTERNAL_STORAGE permission - if (requestCode == PermissionsUtil.REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - if (!Environment.isExternalStorageManager()) { + when (requestCode) { + PermissionsUtil.REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) { Toast.makeText( this, R.string.denied_storage_permission_error_msg, @@ -463,6 +463,16 @@ abstract class BaseGodotEditor : GodotActivity() { ).show() } } + + PermissionsUtil.REQUEST_INSTALL_PACKAGES_REQ_CODE -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !packageManager.canRequestPackageInstalls()) { + Toast.makeText( + this, + R.string.denied_install_packages_permission_error_msg, + Toast.LENGTH_LONG + ).show() + } + } } } @@ -514,7 +524,7 @@ abstract class BaseGodotEditor : GodotActivity() { override fun supportsFeature(featureTag: String): Boolean { if (featureTag == "xr_editor") { - return isNativeXRDevice(); + return isNativeXRDevice() } if (featureTag == "horizonos") { diff --git a/platform/android/java/editor/src/main/res/values/strings.xml b/platform/android/java/editor/src/main/res/values/strings.xml index 0ad54ac3a1..a25b6c0a2d 100644 --- a/platform/android/java/editor/src/main/res/values/strings.xml +++ b/platform/android/java/editor/src/main/res/values/strings.xml @@ -2,5 +2,6 @@ <resources> <string name="godot_game_activity_name">Godot Play window</string> <string name="denied_storage_permission_error_msg">Missing storage access permission!</string> + <string name="denied_install_packages_permission_error_msg">Missing install packages permission!</string> <string name="pip_button_description">Button used to toggle picture-in-picture mode for the Play window</string> </resources> diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt index 898e3e04be..3ad8e6bc9e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -925,6 +925,12 @@ class Godot(private val context: Context) { } } + @Keep + private fun getAccentColor(): Int { + val value = TypedValue() + context.theme.resolveAttribute(android.R.attr.colorAccent, value, true) + return value.data + } /** * Destroys the Godot Engine and kill the process it's running in. diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 5543745444..79751dd58f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -296,28 +296,6 @@ public class GodotIO { } } - /** - This function is used by DisplayServer::screen_get_internal_current_rotation (C++) - and is used to implement a performance optimization in devices that do not offer - a HW rotator. - @return - Rotation in degrees, in multiples of 90° - */ - public int getInternalCurrentScreenRotation() { - int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); - - switch (rotation) { - case Surface.ROTATION_90: - return 90; - case Surface.ROTATION_180: - return 180; - case Surface.ROTATION_270: - return 270; - default: - return 0; - } - } - public void setEdit(GodotEditText _edit) { edit = _edit; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java index c44a6dd472..885873e46d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java @@ -49,7 +49,6 @@ import androidx.core.content.ContextCompat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -66,6 +65,7 @@ public final class PermissionsUtil { public static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001; public static final int REQUEST_SINGLE_PERMISSION_REQ_CODE = 1002; public static final int REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE = 2002; + public static final int REQUEST_INSTALL_PACKAGES_REQ_CODE = 3002; private PermissionsUtil() { } @@ -105,6 +105,16 @@ public final class PermissionsUtil { activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE); } } + } else if (permission.equals(Manifest.permission.REQUEST_INSTALL_PACKAGES)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !activity.getPackageManager().canRequestPackageInstalls()) { + try { + Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES); + intent.setData(Uri.parse(String.format("package:%s", activity.getPackageName()))); + activity.startActivityForResult(intent, REQUEST_INSTALL_PACKAGES_REQ_CODE); + } catch (Exception e) { + Log.e(TAG, "Unable to request permission " + Manifest.permission.REQUEST_INSTALL_PACKAGES); + } + } } else { PermissionInfo permissionInfo = getPermissionInfo(activity, permission); int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel; @@ -215,7 +225,7 @@ public final class PermissionsUtil { try { manifestPermissions = getManifestPermissions(activity); } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); + Log.e(TAG, "Unable to retrieve manifest permissions", e); return false; } @@ -242,7 +252,7 @@ public final class PermissionsUtil { try { manifestPermissions = getManifestPermissions(context); } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); + Log.e(TAG, "Unable to retrieve manifest permissions", e); return new String[0]; } if (manifestPermissions.isEmpty()) { diff --git a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt index a7d2774db5..a5ecafeb09 100644 --- a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt +++ b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt @@ -21,4 +21,4 @@ target_include_directories(${PROJECT_NAME} ${ANDROID_ROOT_DIR} ${OPENXR_INCLUDE_DIR}) -add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED) +add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED -DDEBUG_ENABLED) diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index e58ef50a73..623db39985 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -66,7 +66,6 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _has_hardware_keyboard = p_env->GetMethodID(cls, "hasHardwareKeyboard", "()Z"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I"); - _get_internal_current_screen_rotation = p_env->GetMethodID(cls, "getInternalCurrentScreenRotation", "()I"); _get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(IZ)Ljava/lang/String;"); } } @@ -268,16 +267,6 @@ int GodotIOJavaWrapper::get_screen_orientation() { } } -int GodotIOJavaWrapper::get_internal_current_screen_rotation() { - if (_get_internal_current_screen_rotation) { - JNIEnv *env = get_jni_env(); - ERR_FAIL_NULL_V(env, 0); - return env->CallIntMethod(godot_io_instance, _get_internal_current_screen_rotation); - } else { - return 0; - } -} - String GodotIOJavaWrapper::get_system_dir(int p_dir, bool p_shared_storage) { if (_get_system_dir) { JNIEnv *env = get_jni_env(); diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 903bdce4be..0a372641cb 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -61,7 +61,6 @@ private: jmethodID _has_hardware_keyboard = 0; jmethodID _set_screen_orientation = 0; jmethodID _get_screen_orientation = 0; - jmethodID _get_internal_current_screen_rotation = 0; jmethodID _get_system_dir = 0; public: @@ -89,7 +88,6 @@ public: void set_vk_height(int p_height); void set_screen_orientation(int p_orient); int get_screen_orientation(); - int get_internal_current_screen_rotation(); String get_system_dir(int p_dir, bool p_shared_storage); }; diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp index 2811182e29..5ecd789d43 100644 --- a/platform/android/java_godot_wrapper.cpp +++ b/platform/android/java_godot_wrapper.cpp @@ -64,6 +64,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_ _alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V"); _is_dark_mode_supported = p_env->GetMethodID(godot_class, "isDarkModeSupported", "()Z"); _is_dark_mode = p_env->GetMethodID(godot_class, "isDarkMode", "()Z"); + _get_accent_color = p_env->GetMethodID(godot_class, "getAccentColor", "()I"); _get_clipboard = p_env->GetMethodID(godot_class, "getClipboard", "()Ljava/lang/String;"); _set_clipboard = p_env->GetMethodID(godot_class, "setClipboard", "(Ljava/lang/String;)V"); _has_clipboard = p_env->GetMethodID(godot_class, "hasClipboard", "()Z"); @@ -214,6 +215,23 @@ bool GodotJavaWrapper::is_dark_mode() { } } +Color GodotJavaWrapper::get_accent_color() { + if (_get_accent_color) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL_V(env, Color(0, 0, 0, 0)); + int accent_color = env->CallIntMethod(godot_instance, _get_accent_color); + + // Convert ARGB to RGBA. + int alpha = (accent_color >> 24) & 0xFF; + int red = (accent_color >> 16) & 0xFF; + int green = (accent_color >> 8) & 0xFF; + int blue = accent_color & 0xFF; + return Color(red / 255.0f, green / 255.0f, blue / 255.0f, alpha / 255.0f); + } else { + return Color(0, 0, 0, 0); + } +} + bool GodotJavaWrapper::has_get_clipboard() { return _get_clipboard != nullptr; } diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index 1a753c5c59..512779169a 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -34,6 +34,7 @@ #include "java_godot_view_wrapper.h" #include "string_android.h" +#include "core/math/color.h" #include "core/templates/list.h" #include <android/log.h> @@ -55,6 +56,7 @@ private: jmethodID _alert = nullptr; jmethodID _is_dark_mode_supported = nullptr; jmethodID _is_dark_mode = nullptr; + jmethodID _get_accent_color = nullptr; jmethodID _get_clipboard = nullptr; jmethodID _set_clipboard = nullptr; jmethodID _has_clipboard = nullptr; @@ -99,6 +101,7 @@ public: void alert(const String &p_message, const String &p_title); bool is_dark_mode_supported(); bool is_dark_mode(); + Color get_accent_color(); bool has_get_clipboard(); String get_clipboard(); bool has_set_clipboard(); diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 6355562feb..b309e8d8eb 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -771,11 +771,11 @@ Vector<String> OS_LinuxBSD::get_system_font_path_for_text(const String &p_font_n FcLangSetAdd(lang_set, reinterpret_cast<const FcChar8 *>(p_locale.utf8().get_data())); FcPatternAddLangSet(pattern, FC_LANG, lang_set); - FcConfigSubstitute(0, pattern, FcMatchPattern); + FcConfigSubstitute(nullptr, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); + FcPattern *match = FcFontMatch(nullptr, pattern, &result); if (match) { char *file_name = nullptr; if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) { @@ -816,11 +816,11 @@ String OS_LinuxBSD::get_system_font_path(const String &p_font_name, int p_weight FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); - FcConfigSubstitute(0, pattern, FcMatchPattern); + FcConfigSubstitute(nullptr, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); + FcPattern *match = FcFontMatch(nullptr, pattern, &result); if (match) { if (!allow_substitutes) { char *family_name = nullptr; diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h index 352b3fe523..c28a6fd082 100644 --- a/platform/web/display_server_web.h +++ b/platform/web/display_server_web.h @@ -209,6 +209,7 @@ public: virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual void screen_set_keep_on(bool p_enable) override {} virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override; virtual void virtual_keyboard_hide() override; @@ -265,6 +266,7 @@ public: virtual bool can_any_window_draw() const override; + virtual void window_set_vsync_mode(VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override {} virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; // events diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 1d17e7b325..30df9df809 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -24,6 +24,7 @@ common_win = [ "gl_manager_windows_angle.cpp", "wgl_detect_version.cpp", "rendering_context_driver_vulkan_windows.cpp", + "drop_target_windows.cpp", ] if env.msvc: diff --git a/platform/windows/crash_handler_windows_signal.cpp b/platform/windows/crash_handler_windows_signal.cpp index e11a60bdc7..c3a0d08ad6 100644 --- a/platform/windows/crash_handler_windows_signal.cpp +++ b/platform/windows/crash_handler_windows_signal.cpp @@ -159,7 +159,7 @@ extern void CrashHandlerException(int signal) { // Load process and image info to determine ASLR addresses offset. MODULEINFO mi; - GetModuleInformation(GetCurrentProcess(), GetModuleHandle(NULL), &mi, sizeof(mi)); + GetModuleInformation(GetCurrentProcess(), GetModuleHandle(nullptr), &mi, sizeof(mi)); int64_t image_mem_base = reinterpret_cast<int64_t>(mi.lpBaseOfDll); int64_t image_file_base = get_image_base(_execpath); data.offset = image_mem_base - image_file_base; diff --git a/platform/windows/detect.py b/platform/windows/detect.py index ddcd29adc9..e1109db24f 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -68,23 +68,23 @@ def can_build(): def get_mingw_bin_prefix(prefix, arch): - if not prefix: - mingw_bin_prefix = "" - elif prefix[-1] != "/": - mingw_bin_prefix = prefix + "/bin/" - else: - mingw_bin_prefix = prefix + "bin/" + bin_prefix = (os.path.normpath(os.path.join(prefix, "bin")) + os.sep) if prefix else "" + ARCH_PREFIXES = { + "x86_64": "x86_64-w64-mingw32-", + "x86_32": "i686-w64-mingw32-", + "arm32": "armv7-w64-mingw32-", + "arm64": "aarch64-w64-mingw32-", + } + arch_prefix = ARCH_PREFIXES[arch] if arch else "" + return bin_prefix + arch_prefix - if arch == "x86_64": - mingw_bin_prefix += "x86_64-w64-mingw32-" - elif arch == "x86_32": - mingw_bin_prefix += "i686-w64-mingw32-" - elif arch == "arm32": - mingw_bin_prefix += "armv7-w64-mingw32-" - elif arch == "arm64": - mingw_bin_prefix += "aarch64-w64-mingw32-" - return mingw_bin_prefix +def get_detected(env: "SConsEnvironment", tool: str) -> str: + checks = [ + get_mingw_bin_prefix(env["mingw_prefix"], env["arch"]) + tool, + get_mingw_bin_prefix(env["mingw_prefix"], "") + tool, + ] + return str(env.Detect(checks)) def detect_build_env_arch(): @@ -245,41 +245,6 @@ def get_flags(): } -def build_res_file(target, source, env: "SConsEnvironment"): - arch_aliases = { - "x86_32": "pe-i386", - "x86_64": "pe-x86-64", - "arm32": "armv7-w64-mingw32", - "arm64": "aarch64-w64-mingw32", - } - cmdbase = "windres --include-dir . --target=" + arch_aliases[env["arch"]] - - mingw_bin_prefix = get_mingw_bin_prefix(env["mingw_prefix"], env["arch"]) - - for x in range(len(source)): - ok = True - # Try prefixed executable (MinGW on Linux). - cmd = mingw_bin_prefix + cmdbase + " -i " + str(source[x]) + " -o " + str(target[x]) - try: - out = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate() - if len(out[1]): - ok = False - except Exception: - ok = False - - # Try generic executable (MSYS2). - if not ok: - cmd = cmdbase + " -i " + str(source[x]) + " -o " + str(target[x]) - try: - out = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate() - if len(out[1]): - return -1 - except Exception: - return -1 - - return 0 - - def setup_msvc_manual(env: "SConsEnvironment"): """Running from VCVARS environment""" @@ -361,6 +326,10 @@ def setup_mingw(env: "SConsEnvironment"): print_error("No valid compilers found, use MINGW_PREFIX environment variable to set MinGW path.") sys.exit(255) + env.Tool("mingw") + env.AppendUnique(CCFLAGS=env.get("ccflags", "").split()) + env.AppendUnique(RCFLAGS=env.get("rcflags", "").split()) + print("Using MinGW, arch %s" % (env["arch"])) @@ -706,6 +675,13 @@ def configure_mingw(env: "SConsEnvironment"): # https://www.scons.org/wiki/LongCmdLinesOnWin32 env.use_windows_spawn_fix() + # HACK: For some reason, Windows-native shells have their MinGW tools + # frequently fail as a result of parsing path separators incorrectly. + # For some other reason, this issue is circumvented entirely if the + # `mingw_prefix` bin is prepended to PATH. + if os.sep == "\\": + env.PrependENVPath("PATH", os.path.join(env["mingw_prefix"], "bin")) + # In case the command line to AR is too long, use a response file. env["ARCOM_ORIG"] = env["ARCOM"] env["ARCOM"] = "${TEMPFILE('$ARCOM_ORIG', '$ARCOMSTR')}" @@ -743,9 +719,6 @@ def configure_mingw(env: "SConsEnvironment"): ## Compiler configuration - if os.name != "nt": - env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation - if env["arch"] == "x86_32": if env["use_static_cpp"]: env.Append(LINKFLAGS=["-static"]) @@ -760,29 +733,31 @@ def configure_mingw(env: "SConsEnvironment"): env.Append(CCFLAGS=["-ffp-contract=off"]) - mingw_bin_prefix = get_mingw_bin_prefix(env["mingw_prefix"], env["arch"]) - if env["use_llvm"]: - env["CC"] = mingw_bin_prefix + "clang" - env["CXX"] = mingw_bin_prefix + "clang++" - if try_cmd("as --version", env["mingw_prefix"], env["arch"]): - env["AS"] = mingw_bin_prefix + "as" - env.Append(ASFLAGS=["-c"]) - if try_cmd("ar --version", env["mingw_prefix"], env["arch"]): - env["AR"] = mingw_bin_prefix + "ar" - if try_cmd("ranlib --version", env["mingw_prefix"], env["arch"]): - env["RANLIB"] = mingw_bin_prefix + "ranlib" + env["CC"] = get_detected(env, "clang") + env["CXX"] = get_detected(env, "clang++") + env["AR"] = get_detected(env, "ar") + env["RANLIB"] = get_detected(env, "ranlib") + env.Append(ASFLAGS=["-c"]) env.extra_suffix = ".llvm" + env.extra_suffix else: - env["CC"] = mingw_bin_prefix + "gcc" - env["CXX"] = mingw_bin_prefix + "g++" - if try_cmd("as --version", env["mingw_prefix"], env["arch"]): - env["AS"] = mingw_bin_prefix + "as" - ar = "ar" if os.name == "nt" else "gcc-ar" - if try_cmd(f"{ar} --version", env["mingw_prefix"], env["arch"]): - env["AR"] = mingw_bin_prefix + ar - if try_cmd("gcc-ranlib --version", env["mingw_prefix"], env["arch"]): - env["RANLIB"] = mingw_bin_prefix + "gcc-ranlib" + env["CC"] = get_detected(env, "gcc") + env["CXX"] = get_detected(env, "g++") + env["AR"] = get_detected(env, "gcc-ar" if os.name != "nt" else "ar") + env["RANLIB"] = get_detected(env, "gcc-ranlib") + + env["RC"] = get_detected(env, "windres") + ARCH_TARGETS = { + "x86_32": "pe-i386", + "x86_64": "pe-x86-64", + "arm32": "armv7-w64-mingw32", + "arm64": "aarch64-w64-mingw32", + } + env.AppendUnique(RCFLAGS=f"--target={ARCH_TARGETS[env['arch']]}") + + env["AS"] = get_detected(env, "as") + env["OBJCOPY"] = get_detected(env, "objcopy") + env["STRIP"] = get_detected(env, "strip") ## LTO @@ -924,9 +899,6 @@ def configure_mingw(env: "SConsEnvironment"): env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)]) - # resrc - env.Append(BUILDERS={"RES": env.Builder(action=build_res_file, suffix=".o", src_suffix=".rc")}) - def configure(env: "SConsEnvironment"): # Validate arch. diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 3bc32fc218..a6eab1bd29 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -30,6 +30,7 @@ #include "display_server_windows.h" +#include "drop_target_windows.h" #include "os_windows.h" #include "wgl_detect_version.h" @@ -735,7 +736,7 @@ Error DisplayServerWindows::_file_dialog_with_options_show(const String &p_title GetWindowRect(fd->hwnd_owner, &crect); fd->wrect = Rect2i(crect.left, crect.top, crect.right - crect.left, crect.bottom - crect.top); } else { - fd->hwnd_owner = 0; + fd->hwnd_owner = nullptr; fd->wrect = Rect2i(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT); } fd->appid = appname; @@ -1617,11 +1618,17 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { } #endif - if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) { - wintab_WTClose(windows[p_window].wtctx); - windows[p_window].wtctx = nullptr; + if ((tablet_get_current_driver() == "wintab") && wintab_available && wd.wtctx) { + wintab_WTClose(wd.wtctx); + wd.wtctx = nullptr; + } + + if (wd.drop_target != nullptr) { + RevokeDragDrop(wd.hWnd); + wd.drop_target->Release(); } - DestroyWindow(windows[p_window].hWnd); + + DestroyWindow(wd.hWnd); windows.erase(p_window); if (last_focused_window == p_window) { @@ -1731,7 +1738,14 @@ void DisplayServerWindows::window_set_drop_files_callback(const Callable &p_call _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); - windows[p_window].drop_files_callback = p_callable; + WindowData &window_data = windows[p_window]; + + window_data.drop_files_callback = p_callable; + + if (window_data.drop_target == nullptr) { + window_data.drop_target = memnew(DropTargetWindows(&window_data)); + ERR_FAIL_COND(RegisterDragDrop(window_data.hWnd, window_data.drop_target) != S_OK); + } } void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_window) { @@ -5320,32 +5334,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } } break; - case WM_DROPFILES: { - HDROP hDropInfo = (HDROP)wParam; - const int buffsize = 4096; - WCHAR buf[buffsize]; - - int fcount = DragQueryFileW(hDropInfo, 0xFFFFFFFF, nullptr, 0); - - Vector<String> files; - - for (int i = 0; i < fcount; i++) { - DragQueryFileW(hDropInfo, i, buf, buffsize); - String file = String::utf16((const char16_t *)buf); - files.push_back(file); - } - - if (files.size() && windows[window_id].drop_files_callback.is_valid()) { - Variant v_files = files; - const Variant *v_args[1] = { &v_files }; - Variant ret; - Callable::CallError ce; - windows[window_id].drop_files_callback.callp((const Variant **)&v_args, 1, ret, ce); - if (ce.error != Callable::CallError::CALL_OK) { - ERR_PRINT(vformat("Failed to execute drop files callback: %s.", Variant::get_callable_error_text(windows[window_id].drop_files_callback, v_args, 1, ce))); - } - } - } break; default: { if (user_proc) { return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam); @@ -5450,7 +5438,7 @@ void DisplayServerWindows::_process_key_events() { k->set_physical_keycode(physical_keycode); k->set_key_label(key_label); k->set_unicode(fix_unicode(unicode)); - if (k->get_unicode() && ke.altgr) { + if (k->get_unicode() && ke.altgr && windows[ke.window_id].ime_active) { k->set_alt_pressed(false); k->set_ctrl_pressed(false); } @@ -5526,7 +5514,7 @@ void DisplayServerWindows::_process_key_events() { } k->set_unicode(fix_unicode(unicode)); } - if (k->get_unicode() && ke.altgr) { + if (k->get_unicode() && ke.altgr && windows[ke.window_id].ime_active) { k->set_alt_pressed(false); k->set_ctrl_pressed(false); } @@ -6174,6 +6162,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win FreeLibrary(comctl32); } + OleInitialize(nullptr); + memset(&wc, 0, sizeof(WNDCLASSEXW)); wc.cbSize = sizeof(WNDCLASSEXW); wc.style = CS_OWNDC | CS_DBLCLKS; @@ -6606,6 +6596,12 @@ DisplayServerWindows::~DisplayServerWindows() { wintab_WTClose(windows[MAIN_WINDOW_ID].wtctx); windows[MAIN_WINDOW_ID].wtctx = nullptr; } + + if (windows[MAIN_WINDOW_ID].drop_target != nullptr) { + RevokeDragDrop(windows[MAIN_WINDOW_ID].hWnd); + windows[MAIN_WINDOW_ID].drop_target->Release(); + } + DestroyWindow(windows[MAIN_WINDOW_ID].hWnd); } @@ -6637,4 +6633,6 @@ DisplayServerWindows::~DisplayServerWindows() { if (tts) { memdelete(tts); } + + OleUninitialize(); } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index fc72e05b1d..0462d3f8fa 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -357,9 +357,13 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS { SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2, } SHC_PROCESS_DPI_AWARENESS; +class DropTargetWindows; + class DisplayServerWindows : public DisplayServer { // No need to register with GDCLASS, it's platform-specific and nothing is added. + friend class DropTargetWindows; + _THREAD_SAFE_CLASS_ // UXTheme API @@ -521,6 +525,9 @@ class DisplayServerWindows : public DisplayServer { Callable input_text_callback; Callable drop_files_callback; + // OLE API + DropTargetWindows *drop_target = nullptr; + WindowID transient_parent = INVALID_WINDOW_ID; HashSet<WindowID> transient_children; diff --git a/platform/windows/drop_target_windows.cpp b/platform/windows/drop_target_windows.cpp new file mode 100644 index 0000000000..d04924a9cf --- /dev/null +++ b/platform/windows/drop_target_windows.cpp @@ -0,0 +1,375 @@ +/**************************************************************************/ +/* drop_target_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "drop_target_windows.h" + +#include "core/io/dir_access.h" +#include "core/math/random_pcg.h" +#include "core/os/time.h" + +#include <fileapi.h> + +// Helpers + +static String create_temp_dir() { + Char16String buf; + int bufsize = GetTempPathW(0, nullptr) + 1; + buf.resize(bufsize); + if (GetTempPathW(bufsize, (LPWSTR)buf.ptrw()) == 0) { + return ""; + } + + String tmp_dir = String::utf16((const char16_t *)buf.ptr()); + RandomPCG gen(Time::get_singleton()->get_ticks_usec()); + + const int attempts = 4; + + for (int i = 0; i < attempts; ++i) { + uint32_t rnd = gen.rand(); + String dirname = "godot_tmp_" + String::num_uint64(rnd); + String res_dir = tmp_dir.path_join(dirname); + Char16String res_dir16 = res_dir.utf16(); + + if (CreateDirectoryW((LPCWSTR)res_dir16.ptr(), nullptr)) { + return res_dir; + } + } + + return ""; +} + +static bool remove_dir_recursive(const String &p_dir) { + Ref<DirAccess> dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (dir_access->change_dir(p_dir) != OK) { + return false; + } + return dir_access->erase_contents_recursive() == OK; +} + +static bool stream2file(IStream *p_stream, FILEDESCRIPTORW *p_desc, const String &p_path) { + if (DirAccess::make_dir_recursive_absolute(p_path.get_base_dir()) != OK) { + return false; + } + + Char16String path16 = p_path.utf16(); + DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + + if (p_desc->dwFlags & FD_ATTRIBUTES) { + dwFlagsAndAttributes = p_desc->dwFileAttributes; + } + + HANDLE file = CreateFileW( + (LPCWSTR)path16.ptr(), + GENERIC_WRITE, + 0, + nullptr, + CREATE_NEW, + dwFlagsAndAttributes, + nullptr); + + if (!file) { + return false; + } + + const int bufsize = 4096; + char buf[bufsize]; + ULONG nread = 0; + DWORD nwritten = 0; + HRESULT read_result = S_OK; + bool result = true; + + while (true) { + read_result = p_stream->Read(buf, bufsize, &nread); + if (read_result != S_OK && read_result != S_FALSE) { + result = false; + goto cleanup; + } + + if (!nread) { + break; + } + + while (nread > 0) { + if (!WriteFile(file, buf, nread, &nwritten, nullptr) || !nwritten) { + result = false; + goto cleanup; + } + nread -= nwritten; + } + } + +cleanup: + CloseHandle(file); + return result; +} + +// DropTargetWindows + +bool DropTargetWindows::is_valid_filedescriptor() { + return cf_filedescriptor != 0 && cf_filecontents != 0; +} + +HRESULT DropTargetWindows::handle_hdrop_format(Vector<String> *p_files, IDataObject *pDataObj) { + FORMATETC fmt = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM stg; + HRESULT res = S_OK; + + if (pDataObj->GetData(&fmt, &stg) != S_OK) { + return E_UNEXPECTED; + } + + HDROP hDropInfo = (HDROP)GlobalLock(stg.hGlobal); + + Char16String buf; + + if (hDropInfo == nullptr) { + ReleaseStgMedium(&stg); + return E_UNEXPECTED; + } + + int fcount = DragQueryFileW(hDropInfo, 0xFFFFFFFF, nullptr, 0); + + for (int i = 0; i < fcount; i++) { + int buffsize = DragQueryFileW(hDropInfo, i, nullptr, 0); + buf.resize(buffsize + 1); + if (DragQueryFileW(hDropInfo, i, (LPWSTR)buf.ptrw(), buffsize + 1) == 0) { + res = E_UNEXPECTED; + goto cleanup; + } + String file = String::utf16((const char16_t *)buf.ptr()); + p_files->push_back(file); + } + +cleanup: + GlobalUnlock(stg.hGlobal); + ReleaseStgMedium(&stg); + + return res; +} + +HRESULT DropTargetWindows::handle_filedescriptor_format(Vector<String> *p_files, IDataObject *pDataObj) { + FORMATETC fmt = { cf_filedescriptor, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM stg; + HRESULT res = S_OK; + + if (pDataObj->GetData(&fmt, &stg) != S_OK) { + return E_UNEXPECTED; + } + + FILEGROUPDESCRIPTORW *filegroup_desc = (FILEGROUPDESCRIPTORW *)GlobalLock(stg.hGlobal); + + if (!filegroup_desc) { + ReleaseStgMedium(&stg); + return E_UNEXPECTED; + } + + tmp_path = create_temp_dir(); + Ref<DirAccess> dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + PackedStringArray copied; + + if (dir_access->change_dir(tmp_path) != OK) { + res = E_UNEXPECTED; + goto cleanup; + } + + for (int i = 0; i < (int)filegroup_desc->cItems; ++i) { + res = save_as_file(tmp_path, filegroup_desc->fgd + i, pDataObj, i); + if (res != S_OK) { + res = E_UNEXPECTED; + goto cleanup; + } + } + + copied = dir_access->get_files(); + for (const String &file : copied) { + p_files->push_back(tmp_path.path_join(file)); + } + + copied = dir_access->get_directories(); + for (const String &dir : copied) { + p_files->push_back(tmp_path.path_join(dir)); + } + +cleanup: + GlobalUnlock(filegroup_desc); + ReleaseStgMedium(&stg); + if (res != S_OK) { + remove_dir_recursive(tmp_path); + tmp_path.clear(); + } + return res; +} + +HRESULT DropTargetWindows::save_as_file(const String &p_out_dir, FILEDESCRIPTORW *p_file_desc, IDataObject *pDataObj, int p_file_idx) { + String relpath = String::utf16((const char16_t *)p_file_desc->cFileName); + String fullpath = p_out_dir.path_join(relpath); + + if (p_file_desc->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (DirAccess::make_dir_recursive_absolute(fullpath) != OK) { + return E_UNEXPECTED; + } + return S_OK; + } + + FORMATETC fmt = { cf_filecontents, nullptr, DVASPECT_CONTENT, p_file_idx, TYMED_ISTREAM }; + STGMEDIUM stg; + HRESULT res = S_OK; + + if (pDataObj->GetData(&fmt, &stg) != S_OK) { + return E_UNEXPECTED; + } + + IStream *stream = stg.pstm; + if (stream == nullptr) { + res = E_UNEXPECTED; + goto cleanup; + } + + if (!stream2file(stream, p_file_desc, fullpath)) { + res = E_UNEXPECTED; + goto cleanup; + } + +cleanup: + ReleaseStgMedium(&stg); + return res; +} + +DropTargetWindows::DropTargetWindows(DisplayServerWindows::WindowData *p_window_data) : + ref_count(1), window_data(p_window_data) { + cf_filedescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW); + cf_filecontents = RegisterClipboardFormat(CFSTR_FILECONTENTS); +} + +HRESULT STDMETHODCALLTYPE DropTargetWindows::QueryInterface(REFIID riid, void **ppvObject) { + if (riid == IID_IUnknown || riid == IID_IDropTarget) { + *ppvObject = static_cast<IDropTarget *>(this); + AddRef(); + return S_OK; + } + *ppvObject = nullptr; + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE DropTargetWindows::AddRef() { + return InterlockedIncrement(&ref_count); +} + +ULONG STDMETHODCALLTYPE DropTargetWindows::Release() { + ULONG count = InterlockedDecrement(&ref_count); + if (count == 0) { + memfree(this); + } + return count; +} + +HRESULT STDMETHODCALLTYPE DropTargetWindows::DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { + (void)grfKeyState; + (void)pt; + + FORMATETC hdrop_fmt = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + FORMATETC filedesc_fmt = { cf_filedescriptor, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + + if (!window_data->drop_files_callback.is_valid()) { + *pdwEffect = DROPEFFECT_NONE; + } else if (pDataObj->QueryGetData(&hdrop_fmt) == S_OK) { + *pdwEffect = DROPEFFECT_COPY; + } else if (is_valid_filedescriptor() && pDataObj->QueryGetData(&filedesc_fmt) == S_OK) { + *pdwEffect = DROPEFFECT_COPY; + } else { + *pdwEffect = DROPEFFECT_NONE; + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DropTargetWindows::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { + (void)grfKeyState; + (void)pt; + + *pdwEffect = DROPEFFECT_COPY; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DropTargetWindows::DragLeave() { + return S_OK; +} + +HRESULT STDMETHODCALLTYPE DropTargetWindows::Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { + (void)grfKeyState; + (void)pt; + + *pdwEffect = DROPEFFECT_NONE; + + if (!window_data->drop_files_callback.is_valid()) { + return S_OK; + } + + FORMATETC hdrop_fmt = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + FORMATETC filedesc_fmt = { cf_filedescriptor, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + Vector<String> files; + + if (pDataObj->QueryGetData(&hdrop_fmt) == S_OK) { + HRESULT res = handle_hdrop_format(&files, pDataObj); + if (res != S_OK) { + return res; + } + } else if (pDataObj->QueryGetData(&filedesc_fmt) == S_OK && is_valid_filedescriptor()) { + HRESULT res = handle_filedescriptor_format(&files, pDataObj); + if (res != S_OK) { + return res; + } + } else { + return E_UNEXPECTED; + } + + if (!files.size()) { + return S_OK; + } + + Variant v_files = files; + const Variant *v_args[1] = { &v_files }; + Variant ret; + Callable::CallError ce; + window_data->drop_files_callback.callp((const Variant **)&v_args, 1, ret, ce); + + if (!tmp_path.is_empty()) { + remove_dir_recursive(tmp_path); + tmp_path.clear(); + } + + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT(vformat("Failed to execute drop files callback: %s.", Variant::get_callable_error_text(window_data->drop_files_callback, v_args, 1, ce))); + return E_UNEXPECTED; + } + + *pdwEffect = DROPEFFECT_COPY; + return S_OK; +} diff --git a/platform/windows/drop_target_windows.h b/platform/windows/drop_target_windows.h new file mode 100644 index 0000000000..bd0e0270c6 --- /dev/null +++ b/platform/windows/drop_target_windows.h @@ -0,0 +1,77 @@ +/**************************************************************************/ +/* drop_target_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 DROP_TARGET_WINDOWS_H +#define DROP_TARGET_WINDOWS_H + +#include "display_server_windows.h" + +#include <shlobj.h> + +// Silence warning due to a COM API weirdness. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif + +// https://learn.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-dodragdrop#remarks +class DropTargetWindows : public IDropTarget { + LONG ref_count; + DisplayServerWindows::WindowData *window_data = nullptr; + CLIPFORMAT cf_filedescriptor = 0; + CLIPFORMAT cf_filecontents = 0; + String tmp_path; + + bool is_valid_filedescriptor(); + HRESULT handle_hdrop_format(Vector<String> *p_files, IDataObject *pDataObj); + HRESULT handle_filedescriptor_format(Vector<String> *p_files, IDataObject *pDataObj); + HRESULT save_as_file(const String &p_out_dir, FILEDESCRIPTORW *p_file_desc, IDataObject *pDataObj, int p_file_idx); + +public: + DropTargetWindows(DisplayServerWindows::WindowData *p_window_data); + virtual ~DropTargetWindows() {} + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; + ULONG STDMETHODCALLTYPE AddRef() override; + ULONG STDMETHODCALLTYPE Release() override; + + // IDropTarget + HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override; + HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override; + HRESULT STDMETHODCALLTYPE DragLeave() override; + HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override; +}; + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +#endif // DROP_TARGET_WINDOWS_H diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index 14536fa130..fc34ad3cb3 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -1,5 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> + <Type Name="Ref<*>"> + <SmartPointer Usage="Minimal">reference</SmartPointer> + <DisplayString Condition="!reference">[empty]</DisplayString> + <DisplayString Condition="!!reference">{*reference}</DisplayString> + <Expand> + <Item Condition="!!reference" Name="[ptr]">reference</Item> + <Item Condition="!!reference" Name="[refcount]">reference->refcount.count.value</Item> + </Expand> + </Type> + <Type Name="Vector<*>"> <Expand> <Item Name="[size]">_cowdata._ptr ? (((const unsigned long long *)(_cowdata._ptr))[-1]) : 0</Item> @@ -91,6 +101,16 @@ <StringView Condition="_data && !_data->cname">_data->name,s32b</StringView> </Type> + <Type Name="HashSet<*,*,*>"> + <Expand> + <Item Name="[size]">num_elements</Item> + <ArrayItems> + <Size>num_elements</Size> + <ValuePointer>($T1 *) keys._cowdata._ptr</ValuePointer> + </ArrayItems> + </Expand> + </Type> + <Type Name="HashMapElement<*,*>"> <DisplayString>{{Key = {($T1 *) &data.key} Value = {($T2 *) &data.value}}}</DisplayString> <Expand> diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index a5f1629cf0..0f55cda5d7 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -122,8 +122,9 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) { memcmp(p_guid, &IID_XOneSWirelessGamepad, sizeof(*p_guid)) == 0 || memcmp(p_guid, &IID_XOneSBluetoothGamepad, sizeof(*p_guid)) == 0 || memcmp(p_guid, &IID_XOneEliteWirelessGamepad, sizeof(*p_guid)) == 0 || - memcmp(p_guid, &IID_XOneElite2WirelessGamepad, sizeof(*p_guid)) == 0) + memcmp(p_guid, &IID_XOneElite2WirelessGamepad, sizeof(*p_guid)) == 0) { return true; + } PRAWINPUTDEVICELIST dev_list = nullptr; unsigned int dev_list_count = 0; diff --git a/platform/windows/native_menu_windows.cpp b/platform/windows/native_menu_windows.cpp index fde55918e4..9fa2849e7b 100644 --- a/platform/windows/native_menu_windows.cpp +++ b/platform/windows/native_menu_windows.cpp @@ -158,7 +158,7 @@ Size2 NativeMenuWindows::get_size(const RID &p_rid) const { int count = GetMenuItemCount(md->menu); for (int i = 0; i < count; i++) { RECT rect; - if (GetMenuItemRect(NULL, md->menu, i, &rect)) { + if (GetMenuItemRect(nullptr, md->menu, i, &rect)) { size.x = MAX(size.x, rect.right - rect.left); size.y += rect.bottom - rect.top; } @@ -992,7 +992,7 @@ void NativeMenuWindows::set_item_submenu(const RID &p_rid, int p_idx, const RID if (p_submenu_rid.is_valid()) { item.hSubMenu = md_sub->menu; } else { - item.hSubMenu = 0; + item.hSubMenu = nullptr; } SetMenuItemInfoW(md->menu, p_idx, true, &item); } @@ -1095,7 +1095,7 @@ void NativeMenuWindows::set_item_icon(const RID &p_rid, int p_idx, const Ref<Tex item_data->bmp = _make_bitmap(item_data->img); } else { item_data->img = Ref<Image>(); - item_data->bmp = 0; + item_data->bmp = nullptr; } item.hbmpItem = item_data->bmp; SetMenuItemInfoW(md->menu, p_idx, true, &item); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index ce4ebb03f2..bff3443214 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -139,13 +139,13 @@ void RedirectIOToConsole() { if (AttachConsole(ATTACH_PARENT_PROCESS)) { // Restore redirection (Note: if not redirected it's NULL handles not INVALID_HANDLE_VALUE). - if (h_stdin != 0) { + if (h_stdin != nullptr) { SetStdHandle(STD_INPUT_HANDLE, h_stdin); } - if (h_stdout != 0) { + if (h_stdout != nullptr) { SetStdHandle(STD_OUTPUT_HANDLE, h_stdout); } - if (h_stderr != 0) { + if (h_stderr != nullptr) { SetStdHandle(STD_ERROR_HANDLE, h_stderr); } @@ -908,9 +908,9 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String } // Create pipes. - HANDLE pipe_in[2] = { 0, 0 }; - HANDLE pipe_out[2] = { 0, 0 }; - HANDLE pipe_err[2] = { 0, 0 }; + HANDLE pipe_in[2] = { nullptr, nullptr }; + HANDLE pipe_out[2] = { nullptr, nullptr }; + HANDLE pipe_err[2] = { nullptr, nullptr }; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -981,7 +981,7 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String Ref<FileAccessWindowsPipe> err_pipe; err_pipe.instantiate(); - err_pipe->open_existing(pipe_err[0], 0, p_blocking); + err_pipe->open_existing(pipe_err[0], nullptr, p_blocking); ret["stdio"] = main_pipe; ret["stderr"] = err_pipe; diff --git a/platform/windows/platform_windows_builders.py b/platform/windows/platform_windows_builders.py index 3fd9e1a581..2020e68748 100644 --- a/platform/windows/platform_windows_builders.py +++ b/platform/windows/platform_windows_builders.py @@ -2,23 +2,11 @@ import os -from detect import get_mingw_bin_prefix, try_cmd - def make_debug_mingw(target, source, env): dst = str(target[0]) # Force separate debug symbols if executable size is larger than 1.9 GB. if env["separate_debug_symbols"] or os.stat(dst).st_size >= 2040109465: - mingw_bin_prefix = get_mingw_bin_prefix(env["mingw_prefix"], env["arch"]) - if try_cmd("objcopy --version", env["mingw_prefix"], env["arch"]): - os.system(mingw_bin_prefix + "objcopy --only-keep-debug {0} {0}.debugsymbols".format(dst)) - else: - os.system("objcopy --only-keep-debug {0} {0}.debugsymbols".format(dst)) - if try_cmd("strip --version", env["mingw_prefix"], env["arch"]): - os.system(mingw_bin_prefix + "strip --strip-debug --strip-unneeded {0}".format(dst)) - else: - os.system("strip --strip-debug --strip-unneeded {0}".format(dst)) - if try_cmd("objcopy --version", env["mingw_prefix"], env["arch"]): - os.system(mingw_bin_prefix + "objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(dst)) - else: - os.system("objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(dst)) + os.system("{0} --only-keep-debug {1} {1}.debugsymbols".format(env["OBJCOPY"], dst)) + os.system("{0} --strip-debug --strip-unneeded {1}".format(env["STRIP"], dst)) + os.system("{0} --add-gnu-debuglink={1}.debugsymbols {1}".format(env["OBJCOPY"], dst)) diff --git a/platform/windows/windows_utils.cpp b/platform/windows/windows_utils.cpp index 30743c6900..3b9bfb50f7 100644 --- a/platform/windows/windows_utils.cpp +++ b/platform/windows/windows_utils.cpp @@ -67,11 +67,11 @@ Error WindowsUtils::copy_and_rename_pdb(const String &p_dll_path) { { // The custom LoadLibraryExW is used instead of open_dynamic_library // to avoid loading the original PDB into the debugger. - HMODULE library_ptr = LoadLibraryExW((LPCWSTR)(p_dll_path.utf16().get_data()), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); + HMODULE library_ptr = LoadLibraryExW((LPCWSTR)(p_dll_path.utf16().get_data()), nullptr, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); ERR_FAIL_NULL_V_MSG(library_ptr, ERR_FILE_CANT_OPEN, vformat("Failed to load library '%s'.", p_dll_path)); - IMAGE_DEBUG_DIRECTORY *dbg_dir = (IMAGE_DEBUG_DIRECTORY *)ImageDirectoryEntryToDataEx(library_ptr, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dbg_info_size, NULL); + IMAGE_DEBUG_DIRECTORY *dbg_dir = (IMAGE_DEBUG_DIRECTORY *)ImageDirectoryEntryToDataEx(library_ptr, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dbg_info_size, nullptr); bool has_debug = dbg_dir && dbg_dir->Type == IMAGE_DEBUG_TYPE_CODEVIEW; if (has_debug) { diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index f737e23126..30bd59c1a2 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -823,6 +823,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) { Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer); uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer); uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer); + real_t physics_priority = tile_set->get_physics_layer_collision_priority(tile_set_physics_layer); RID body = r_cell_data.bodies[tile_set_physics_layer]; if (tile_data->get_collision_polygons_count(tile_set_physics_layer) == 0) { @@ -849,6 +850,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) { ps->body_attach_object_instance_id(body, tile_map_node ? tile_map_node->get_instance_id() : get_instance_id()); ps->body_set_collision_layer(body, physics_layer); ps->body_set_collision_mask(body, physics_mask); + ps->body_set_collision_priority(body, physics_priority); ps->body_set_pickable(body, false); ps->body_set_state(body, PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, tile_data->get_constant_linear_velocity(tile_set_physics_layer)); ps->body_set_state(body, PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, tile_data->get_constant_angular_velocity(tile_set_physics_layer)); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index c1c992588b..abece303d1 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -183,17 +183,17 @@ bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const { void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { for (uint32_t i = 0; i < bones.size(); i++) { - const String prep = vformat("%s/%d/", PNAME("bones"), i); - p_list->push_back(PropertyInfo(Variant::STRING, prep + PNAME("name"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::INT, prep + PNAME("parent"), PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prep + PNAME("rest"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::BOOL, prep + PNAME("enabled"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::VECTOR3, prep + PNAME("position"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::QUATERNION, prep + PNAME("rotation"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::VECTOR3, prep + PNAME("scale"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + const String prep = vformat("%s/%d/", "bones", i); + p_list->push_back(PropertyInfo(Variant::STRING, prep + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::VECTOR3, prep + "position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::QUATERNION, prep + "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::VECTOR3, prep + "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); for (const KeyValue<StringName, Variant> &K : bones[i].metadata) { - PropertyInfo pi = PropertyInfo(bones[i].metadata[K.key].get_type(), prep + PNAME("bone_meta/") + K.key, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR); + PropertyInfo pi = PropertyInfo(bones[i].metadata[K.key].get_type(), prep + "bone_meta/" + K.key, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR); p_list->push_back(pi); } } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index ecfe095f1d..90902f71e2 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -162,7 +162,7 @@ private: Vector<int> parentless_bones; AHashMap<String, int> name_to_bone_index; - mutable StringName concatenated_bone_names = StringName(); + mutable StringName concatenated_bone_names; void _update_bone_names() const; void _make_dirty(); diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 5d6020194e..94145a6915 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -131,7 +131,7 @@ class SkeletonIK3D : public SkeletonModifier3D { real_t min_distance = 0.01; int max_iterations = 10; - Variant target_node_override_ref = Variant(); + Variant target_node_override_ref; FabrikInverseKinematic::Task *task = nullptr; #ifndef DISABLE_DEPRECATED diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index b87285ed74..377bc0eefe 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -30,6 +30,7 @@ #include "scene_debugger.h" +#include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" #include "core/io/marshalls.h" #include "core/object/script_language.h" @@ -93,6 +94,13 @@ void SceneDebugger::deinitialize() { } #ifdef DEBUG_ENABLED +void SceneDebugger::_handle_input(const Ref<InputEvent> &p_event, const Ref<Shortcut> &p_shortcut) { + Ref<InputEventKey> k = p_event; + if (k.is_valid() && k->is_pressed() && !k->is_echo() && p_shortcut->matches_event(k)) { + EngineDebugger::get_singleton()->send_message("request_quit", Array()); + } +} + Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) { SceneTree *scene_tree = SceneTree::get_singleton(); if (!scene_tree) { @@ -109,7 +117,10 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra } r_captured = true; - if (p_msg == "request_scene_tree") { // Scene tree + if (p_msg == "setup_scene") { + SceneTree::get_singleton()->get_root()->connect(SceneStringName(window_input), callable_mp_static(SceneDebugger::_handle_input).bind(DebuggerMarshalls::deserialize_key_shortcut(p_args))); + + } else if (p_msg == "request_scene_tree") { // Scene tree live_editor->_send_tree(); } else if (p_msg == "save_node") { // Save node. @@ -147,7 +158,6 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA); Transform2D transform = p_args[0]; scene_tree->get_root()->set_canvas_transform_override(transform); - runtime_node_select->_queue_selection_update(); #ifndef _3D_DISABLED @@ -164,16 +174,19 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra scene_tree->get_root()->set_camera_3d_override_orthogonal(size_or_fov, depth_near, depth_far); } scene_tree->get_root()->set_camera_3d_override_transform(transform); - runtime_node_select->_queue_selection_update(); #endif // _3D_DISABLED } else if (p_msg == "set_object_property") { ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); _set_object_property(p_args[0], p_args[1], p_args[2]); - runtime_node_select->_queue_selection_update(); + } else if (p_msg == "reload_cached_files") { + ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA); + PackedStringArray files = p_args[0]; + reload_cached_files(files); + } else if (p_msg.begins_with("live_")) { /// Live Edit if (p_msg == "live_set_root") { ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); @@ -269,7 +282,8 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra } else if (p_msg.begins_with("runtime_node_select_")) { /// Runtime Node Selection if (p_msg == "runtime_node_select_setup") { - runtime_node_select->_setup(); + ERR_FAIL_COND_V(p_args.is_empty() || p_args[0].get_type() != Variant::DICTIONARY, ERR_INVALID_DATA); + runtime_node_select->_setup(p_args[0]); } else if (p_msg == "runtime_node_select_set_type") { ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA); @@ -289,8 +303,10 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra } else if (p_msg == "runtime_node_select_reset_camera_2d") { runtime_node_select->_reset_camera_2d(); +#ifndef _3D_DISABLED } else if (p_msg == "runtime_node_select_reset_camera_3d") { runtime_node_select->_reset_camera_3d(); +#endif // _3D_DISABLED } else { return ERR_SKIP; @@ -413,6 +429,15 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) { } } +void SceneDebugger::reload_cached_files(const PackedStringArray &p_files) { + for (const String &file : p_files) { + Ref<Resource> res = ResourceCache::get_ref(file); + if (res.is_valid()) { + res->reload_from_file(); + } + } +} + /// SceneDebuggerObject SceneDebuggerObject::SceneDebuggerObject(ObjectID p_id) { id = ObjectID(); @@ -1210,7 +1235,7 @@ RuntimeNodeSelect::~RuntimeNodeSelect() { #endif // _3D_DISABLED } -void RuntimeNodeSelect::_setup() { +void RuntimeNodeSelect::_setup(const Dictionary &p_settings) { Window *root = SceneTree::get_singleton()->get_root(); ERR_FAIL_COND(root->is_connected(SceneStringName(window_input), callable_mp(this, &RuntimeNodeSelect::_root_window_input))); @@ -1227,6 +1252,14 @@ void RuntimeNodeSelect::_setup() { panner.instantiate(); panner->set_callbacks(callable_mp(this, &RuntimeNodeSelect::_pan_callback), callable_mp(this, &RuntimeNodeSelect::_zoom_callback)); + ViewPanner::ControlScheme panning_scheme = (ViewPanner::ControlScheme)p_settings.get("editors/panning/2d_editor_panning_scheme", 0).operator int(); + bool simple_panning = p_settings.get("editors/panning/simple_panning", false); + int pan_speed = p_settings.get("editors/panning/2d_editor_pan_speed", 20); + Array keys = p_settings.get("canvas_item_editor/pan_view", Array()).operator Array(); + panner->setup(panning_scheme, DebuggerMarshalls::deserialize_key_shortcut(keys), simple_panning); + panner->set_scroll_speed(pan_speed); + warped_panning = p_settings.get("editors/panning/warped_mouse_panning", false); + /// 2D Selection Box Generation sbox_2d_canvas = RS::get_singleton()->canvas_create(); @@ -1336,7 +1369,7 @@ void RuntimeNodeSelect::_root_window_input(const Ref<InputEvent> &p_event) { if (camera_override) { if (node_select_type == NODE_TYPE_2D) { - if (panner->gui_input(p_event, Rect2(Vector2(), root->get_size()))) { + if (panner->gui_input(p_event, warped_panning ? Rect2(Vector2(), root->get_size()) : Rect2())) { return; } } else if (node_select_type == NODE_TYPE_3D) { diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index f9dd6161aa..90c8000eb4 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -57,6 +57,8 @@ public: #ifdef DEBUG_ENABLED private: + static void _handle_input(const Ref<InputEvent> &p_event, const Ref<Shortcut> &p_shortcut); + static void _save_node(ObjectID id, const String &p_path); static void _set_node_owner_recursive(Node *p_node, Node *p_owner); static void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value); @@ -67,6 +69,7 @@ public: static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured); static void add_to_cache(const String &p_filename, Node *p_node); static void remove_from_cache(const String &p_filename, Node *p_node); + static void reload_cached_files(const PackedStringArray &p_files); #endif }; @@ -200,6 +203,7 @@ private: PopupMenu *selection_list = nullptr; bool selection_visible = true; bool selection_update_queued = false; + bool warped_panning = false; bool camera_override = false; @@ -270,7 +274,7 @@ private: NodeType node_select_type = NODE_TYPE_2D; SelectMode node_select_mode = SELECT_MODE_SINGLE; - void _setup(); + void _setup(const Dictionary &p_settings); void _node_set_type(NodeType p_type); void _select_set_mode(SelectMode p_mode); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 4bd85cbde9..3e593a8372 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -561,6 +561,7 @@ void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) { } autowrap_flags = autowrap_flags | TextServer::BREAK_TRIM_EDGE_SPACES; p_paragraph->set_break_flags(autowrap_flags); + p_paragraph->set_line_spacing(theme_cache.line_spacing); if (text_direction == Control::TEXT_DIRECTION_INHERITED) { p_paragraph->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); @@ -833,6 +834,7 @@ void Button::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Button, icon_max_width); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Button, align_to_largest_stylebox); + BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Button, line_spacing); } Button::Button(const String &p_text) { diff --git a/scene/gui/button.h b/scene/gui/button.h index b86d6a6c1f..686d4806db 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -100,6 +100,7 @@ private: int h_separation = 0; int icon_max_width = 0; + int line_spacing = 0; } theme_cache; void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = ""); diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index ab443e95e1..2cd34ec99f 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -251,13 +251,13 @@ private: Ref<Texture2D> completion_color_bg; Color breakpoint_color = Color(1, 1, 1); - Ref<Texture2D> breakpoint_icon = Ref<Texture2D>(); + Ref<Texture2D> breakpoint_icon; Color bookmark_color = Color(1, 1, 1); - Ref<Texture2D> bookmark_icon = Ref<Texture2D>(); + Ref<Texture2D> bookmark_icon; Color executing_line_color = Color(1, 1, 1); - Ref<Texture2D> executing_line_icon = Ref<Texture2D>(); + Ref<Texture2D> executing_line_icon; Color line_number_color = Color(1, 1, 1); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 18864b1289..9eda1a256f 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -1586,6 +1586,7 @@ FileDialog::FileDialog() { vbox->add_child(hbc); tree = memnew(Tree); + tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); tree->set_hide_root(true); vbox->add_margin_child(ETR("Directories & Files:"), tree, true); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index cb495f9d47..b1c47d858d 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -317,7 +317,7 @@ bool GraphEdit::is_node_connected(const StringName &p_from, int p_from_port, con void GraphEdit::disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) { ERR_FAIL_NULL_MSG(connections_layer, "connections_layer is missing."); - for (const List<Ref<Connection>>::Element *E = connections.front(); E; E = E->next()) { + for (List<Ref<Connection>>::Element *E = connections.front(); E; E = E->next()) { if (E->get()->from_node == p_from && E->get()->from_port == p_from_port && E->get()->to_node == p_to && E->get()->to_port == p_to_port) { connection_map[p_from].erase(E->get()); connection_map[p_to].erase(E->get()); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 42b4e56b48..7a0e5b8867 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -335,6 +335,121 @@ inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Col } } +void Label::_ensure_shaped() const { + if (dirty || font_dirty || lines_dirty) { + const_cast<Label *>(this)->_shape(); + } +} + +RID Label::get_line_rid(int p_line) const { + return lines_rid[p_line]; +} + +Rect2 Label::get_line_rect(int p_line) const { + // Returns a rect providing the line's horizontal offset and total size. To determine the vertical + // offset, use r_offset and r_line_spacing from get_layout_data. + bool rtl = TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL; + bool rtl_layout = is_layout_rtl(); + Ref<StyleBox> style = theme_cache.normal_style; + Size2 size = get_size(); + Size2 line_size = TS->shaped_text_get_size(lines_rid[p_line]); + Vector2 offset; + + switch (horizontal_alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + if (rtl && autowrap_mode != TextServer::AUTOWRAP_OFF) { + offset.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); + } else { + offset.x = style->get_offset().x; + } + break; + case HORIZONTAL_ALIGNMENT_LEFT: { + if (rtl_layout) { + offset.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); + } else { + offset.x = style->get_offset().x; + } + } break; + case HORIZONTAL_ALIGNMENT_CENTER: { + offset.x = int(size.width - line_size.width) / 2; + } break; + case HORIZONTAL_ALIGNMENT_RIGHT: { + if (rtl_layout) { + offset.x = style->get_offset().x; + } else { + offset.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); + } + } break; + } + + return Rect2(offset, line_size); +} + +void Label::get_layout_data(Vector2 &r_offset, int &r_line_limit, int &r_line_spacing) const { + // Computes several common parameters involved in laying out and rendering text set to this label. + // Only vertical margin is considered in r_offset: use get_line_rect to get the horizontal offset + // for a given line of text. + Size2 size = get_size(); + Ref<StyleBox> style = theme_cache.normal_style; + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; + + float total_h = 0.0; + int lines_visible = 0; + + // Get number of lines to fit to the height. + for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { + total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; + if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { + break; + } + lines_visible++; + } + + if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { + lines_visible = max_lines_visible; + } + + r_line_limit = MIN(lines_rid.size(), lines_visible + lines_skipped); + + // Get real total height. + total_h = 0; + for (int64_t i = lines_skipped; i < r_line_limit; i++) { + total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; + } + total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); + + int vbegin = 0, vsep = 0; + if (lines_visible > 0) { + switch (vertical_alignment) { + case VERTICAL_ALIGNMENT_TOP: { + // Nothing. + } break; + case VERTICAL_ALIGNMENT_CENTER: { + vbegin = (size.y - (total_h - line_spacing)) / 2; + vsep = 0; + + } break; + case VERTICAL_ALIGNMENT_BOTTOM: { + vbegin = size.y - (total_h - line_spacing); + vsep = 0; + + } break; + case VERTICAL_ALIGNMENT_FILL: { + vbegin = 0; + if (lines_visible > 1) { + vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1); + } else { + vsep = 0; + } + + } break; + } + } + + r_offset = { 0, style->get_offset().y + vbegin }; + r_line_spacing = line_spacing + vsep; +} + PackedStringArray Label::get_configuration_warnings() const { PackedStringArray warnings = Control::get_configuration_warnings(); @@ -361,10 +476,7 @@ PackedStringArray Label::get_configuration_warnings() const { } if (font.is_valid()) { - if (dirty || font_dirty || lines_dirty) { - const_cast<Label *>(this)->_shape(); - } - + _ensure_shaped(); const Glyph *glyph = TS->shaped_text_get_glyphs(text_rid); int64_t glyph_count = TS->shaped_text_get_glyph_count(text_rid); for (int64_t i = 0; i < glyph_count; i++) { @@ -416,22 +528,17 @@ void Label::_notification(int p_what) { } } - if (dirty || font_dirty || lines_dirty) { - _shape(); - } + _ensure_shaped(); RID ci = get_canvas_item(); bool has_settings = settings.is_valid(); Size2 string_size; - Size2 size = get_size(); Ref<StyleBox> style = theme_cache.normal_style; - Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; Color font_color = has_settings ? settings->get_font_color() : theme_cache.font_color; Color font_shadow_color = has_settings ? settings->get_shadow_color() : theme_cache.font_shadow_color; Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : theme_cache.font_shadow_offset; - int line_spacing = has_settings ? settings->get_line_spacing() : theme_cache.line_spacing; Color font_outline_color = has_settings ? settings->get_outline_color() : theme_cache.font_outline_color; int outline_size = has_settings ? settings->get_outline_size() : theme_cache.font_outline_size; int shadow_outline_size = has_settings ? settings->get_shadow_size() : theme_cache.font_shadow_outline_size; @@ -440,98 +547,28 @@ void Label::_notification(int p_what) { style->draw(ci, Rect2(Point2(0, 0), get_size())); - float total_h = 0.0; - int lines_visible = 0; - - // Get number of lines to fit to the height. - for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { - total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; - if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { - break; - } - lines_visible++; - } - - if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { - lines_visible = max_lines_visible; - } - - int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped); bool trim_chars = (visible_chars >= 0) && (visible_chars_behavior == TextServer::VC_CHARS_AFTER_SHAPING); bool trim_glyphs_ltr = (visible_chars >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_LTR) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && !rtl_layout)); bool trim_glyphs_rtl = (visible_chars >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_RTL) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && rtl_layout)); - // Get real total height. + Vector2 ofs; + int line_limit; + int line_spacing; + get_layout_data(ofs, line_limit, line_spacing); + + int processed_glyphs = 0; int total_glyphs = 0; - total_h = 0; - for (int64_t i = lines_skipped; i < last_line; i++) { - total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; + + for (int64_t i = lines_skipped; i < line_limit; i++) { total_glyphs += TS->shaped_text_get_glyph_count(lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); } - int visible_glyphs = total_glyphs * visible_ratio; - int processed_glyphs = 0; - total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); - - int vbegin = 0, vsep = 0; - if (lines_visible > 0) { - switch (vertical_alignment) { - case VERTICAL_ALIGNMENT_TOP: { - // Nothing. - } break; - case VERTICAL_ALIGNMENT_CENTER: { - vbegin = (size.y - (total_h - line_spacing)) / 2; - vsep = 0; - - } break; - case VERTICAL_ALIGNMENT_BOTTOM: { - vbegin = size.y - (total_h - line_spacing); - vsep = 0; - - } break; - case VERTICAL_ALIGNMENT_FILL: { - vbegin = 0; - if (lines_visible > 1) { - vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1); - } else { - vsep = 0; - } - } break; - } - } + int visible_glyphs = total_glyphs * visible_ratio; - Vector2 ofs; - ofs.y = style->get_offset().y + vbegin; - for (int i = lines_skipped; i < last_line; i++) { - Size2 line_size = TS->shaped_text_get_size(lines_rid[i]); - ofs.x = 0; + for (int i = lines_skipped; i < line_limit; i++) { + Vector2 line_offset = get_line_rect(i).position; + ofs.x = line_offset.x; ofs.y += TS->shaped_text_get_ascent(lines_rid[i]); - switch (horizontal_alignment) { - case HORIZONTAL_ALIGNMENT_FILL: - if (rtl && autowrap_mode != TextServer::AUTOWRAP_OFF) { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); - } else { - ofs.x = style->get_offset().x; - } - break; - case HORIZONTAL_ALIGNMENT_LEFT: { - if (rtl_layout) { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); - } else { - ofs.x = style->get_offset().x; - } - } break; - case HORIZONTAL_ALIGNMENT_CENTER: { - ofs.x = int(size.width - line_size.width) / 2; - } break; - case HORIZONTAL_ALIGNMENT_RIGHT: { - if (rtl_layout) { - ofs.x = style->get_offset().x; - } else { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); - } - } break; - } const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]); int gl_size = TS->shaped_text_get_glyph_count(lines_rid[i]); @@ -621,7 +658,7 @@ void Label::_notification(int p_what) { } } } - ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing; + ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } } break; @@ -637,102 +674,16 @@ void Label::_notification(int p_what) { } Rect2 Label::get_character_bounds(int p_pos) const { - if (dirty || font_dirty || lines_dirty) { - const_cast<Label *>(this)->_shape(); - } - - bool has_settings = settings.is_valid(); - Size2 size = get_size(); - Ref<StyleBox> style = theme_cache.normal_style; - int line_spacing = has_settings ? settings->get_line_spacing() : theme_cache.line_spacing; - bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL); - bool rtl_layout = is_layout_rtl(); - - float total_h = 0.0; - int lines_visible = 0; - - // Get number of lines to fit to the height. - for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { - total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; - if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { - break; - } - lines_visible++; - } - - if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { - lines_visible = max_lines_visible; - } - - int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped); - - // Get real total height. - total_h = 0; - for (int64_t i = lines_skipped; i < last_line; i++) { - total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; - } - - total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); - - int vbegin = 0, vsep = 0; - if (lines_visible > 0) { - switch (vertical_alignment) { - case VERTICAL_ALIGNMENT_TOP: { - // Nothing. - } break; - case VERTICAL_ALIGNMENT_CENTER: { - vbegin = (size.y - (total_h - line_spacing)) / 2; - vsep = 0; - - } break; - case VERTICAL_ALIGNMENT_BOTTOM: { - vbegin = size.y - (total_h - line_spacing); - vsep = 0; - - } break; - case VERTICAL_ALIGNMENT_FILL: { - vbegin = 0; - if (lines_visible > 1) { - vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1); - } else { - vsep = 0; - } - - } break; - } - } + _ensure_shaped(); Vector2 ofs; - ofs.y = style->get_offset().y + vbegin; - for (int i = lines_skipped; i < last_line; i++) { - Size2 line_size = TS->shaped_text_get_size(lines_rid[i]); - ofs.x = 0; - switch (horizontal_alignment) { - case HORIZONTAL_ALIGNMENT_FILL: - if (rtl && autowrap_mode != TextServer::AUTOWRAP_OFF) { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); - } else { - ofs.x = style->get_offset().x; - } - break; - case HORIZONTAL_ALIGNMENT_LEFT: { - if (rtl_layout) { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); - } else { - ofs.x = style->get_offset().x; - } - } break; - case HORIZONTAL_ALIGNMENT_CENTER: { - ofs.x = int(size.width - line_size.width) / 2; - } break; - case HORIZONTAL_ALIGNMENT_RIGHT: { - if (rtl_layout) { - ofs.x = style->get_offset().x; - } else { - ofs.x = int(size.width - style->get_margin(SIDE_RIGHT) - line_size.width); - } - } break; - } + int line_limit; + int line_spacing; + get_layout_data(ofs, line_limit, line_spacing); + + for (int i = lines_skipped; i < line_limit; i++) { + Rect2 line_rect = get_line_rect(i); + ofs.x = line_rect.position.x; int v_size = TS->shaped_text_get_glyph_count(lines_rid[i]); const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]); @@ -746,22 +697,19 @@ Rect2 Label::get_character_bounds(int p_pos) const { } Rect2 rect; rect.position = ofs + Vector2(gl_off, 0); - rect.size = Vector2(advance, TS->shaped_text_get_size(lines_rid[i]).y); + rect.size = Vector2(advance, line_rect.size.y); return rect; } } gl_off += glyphs[j].advance * glyphs[j].repeat; } - ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing; + ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } return Rect2(); } Size2 Label::get_minimum_size() const { - // don't want to mutable everything - if (dirty || font_dirty || lines_dirty) { - const_cast<Label *>(this)->_shape(); - } + _ensure_shaped(); Size2 min_size = minsize; @@ -798,10 +746,7 @@ int Label::get_line_count() const { if (!is_inside_tree()) { return 1; } - if (dirty || font_dirty || lines_dirty) { - const_cast<Label *>(this)->_shape(); - } - + _ensure_shaped(); return lines_rid.size(); } @@ -1104,10 +1049,7 @@ int Label::get_max_lines_visible() const { } int Label::get_total_character_count() const { - if (dirty || font_dirty || lines_dirty) { - const_cast<Label *>(this)->_shape(); - } - + _ensure_shaped(); return xl_text.length(); } diff --git a/scene/gui/label.h b/scene/gui/label.h index e0ebca944a..2576d21c33 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -91,11 +91,16 @@ private: int font_shadow_outline_size; } theme_cache; + void _ensure_shaped() const; void _update_visible(); void _shape(); void _invalidate(); protected: + RID get_line_rid(int p_line) const; + Rect2 get_line_rect(int p_line) const; + void get_layout_data(Vector2 &r_offset, int &r_line_limit, int &r_line_spacing) const; + void _notification(int p_what); static void _bind_methods(); #ifndef DISABLE_DEPRECATED diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 9967805134..3f979f7c20 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -128,6 +128,7 @@ bool LineEdit::has_ime_text() const { void LineEdit::cancel_ime() { if (!has_ime_text()) { + _close_ime_window(); return; } ime_text = String(); @@ -140,6 +141,7 @@ void LineEdit::cancel_ime() { void LineEdit::apply_ime() { if (!has_ime_text()) { + _close_ime_window(); return; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 6b5ff23436..b1918ff23f 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3169,6 +3169,7 @@ bool TextEdit::has_ime_text() const { void TextEdit::cancel_ime() { if (!has_ime_text()) { + _close_ime_window(); return; } ime_text = String(); @@ -3181,6 +3182,7 @@ void TextEdit::cancel_ime() { void TextEdit::apply_ime() { if (!has_ime_text()) { + _close_ime_window(); return; } @@ -5069,7 +5071,7 @@ bool TextEdit::multicaret_edit_ignore_caret(int p_caret) const { } bool TextEdit::is_caret_visible(int p_caret) const { - ERR_FAIL_INDEX_V(p_caret, carets.size(), 0); + ERR_FAIL_INDEX_V(p_caret, carets.size(), false); return carets[p_caret].visible; } @@ -5736,7 +5738,7 @@ TextServer::AutowrapMode TextEdit::get_autowrap_mode() const { } bool TextEdit::is_line_wrapped(int p_line) const { - ERR_FAIL_INDEX_V(p_line, text.size(), 0); + ERR_FAIL_INDEX_V(p_line, text.size(), false); if (get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) { return false; } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index e0d552848d..6b137581f2 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -139,7 +139,7 @@ private: Variant metadata; bool clickable = false; - Ref<Texture2D> icon = Ref<Texture2D>(); + Ref<Texture2D> icon; String text = ""; Color color = Color(1, 1, 1); }; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index aab6f672f0..f6e05f5796 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1574,7 +1574,7 @@ Size2 TreeItem::get_minimum_size(int p_column) { const TreeItem::Cell &cell = cells[p_column]; - if (cell.cached_minimum_size_dirty) { + if (cell.cached_minimum_size_dirty || cell.text_buf->is_dirty() || cell.dirty) { Size2 size = Size2( parent_tree->theme_cache.inner_item_margin_left + parent_tree->theme_cache.inner_item_margin_right, parent_tree->theme_cache.inner_item_margin_top + parent_tree->theme_cache.inner_item_margin_bottom); @@ -1593,7 +1593,9 @@ Size2 TreeItem::get_minimum_size(int p_column) { // Icon. if (cell.mode == CELL_MODE_CHECK) { - size.width += parent_tree->theme_cache.checked->get_width() + parent_tree->theme_cache.h_separation; + Size2i check_size = parent_tree->theme_cache.checked->get_size(); + size.width += check_size.width + parent_tree->theme_cache.h_separation; + size.height = MAX(size.height, check_size.height); } if (cell.icon.is_valid()) { Size2i icon_size = parent_tree->_get_cell_icon_size(cell); @@ -1605,7 +1607,8 @@ Size2 TreeItem::get_minimum_size(int p_column) { for (int i = 0; i < cell.buttons.size(); i++) { Ref<Texture2D> texture = cell.buttons[i].texture; if (texture.is_valid()) { - Size2 button_size = texture->get_size() + parent_tree->theme_cache.button_pressed->get_minimum_size(); + Size2 button_size = texture->get_size(); + button_size.width += parent_tree->theme_cache.button_pressed->get_minimum_size().width; size.width += button_size.width + parent_tree->theme_cache.button_margin; size.height = MAX(size.height, button_size.height); } @@ -1889,44 +1892,7 @@ int Tree::compute_item_height(TreeItem *p_item) const { int height = 0; for (int i = 0; i < columns.size(); i++) { - if (p_item->cells[i].dirty) { - const_cast<Tree *>(this)->update_item_cell(p_item, i); - } - height = MAX(height, p_item->cells[i].text_buf->get_size().y); - for (int j = 0; j < p_item->cells[i].buttons.size(); j++) { - Size2i s; // = cache.button_pressed->get_minimum_size(); - s += p_item->cells[i].buttons[j].texture->get_size(); - if (s.height > height) { - height = s.height; - } - } - - switch (p_item->cells[i].mode) { - case TreeItem::CELL_MODE_CHECK: { - int check_icon_h = theme_cache.checked->get_height(); - if (height < check_icon_h) { - height = check_icon_h; - } - [[fallthrough]]; - } - case TreeItem::CELL_MODE_STRING: - case TreeItem::CELL_MODE_CUSTOM: - case TreeItem::CELL_MODE_ICON: { - Ref<Texture2D> icon = p_item->cells[i].icon; - if (!icon.is_null()) { - Size2i s = _get_cell_icon_size(p_item->cells[i]); - if (s.height > height) { - height = s.height; - } - } - if (p_item->cells[i].mode == TreeItem::CELL_MODE_CUSTOM && p_item->cells[i].custom_button) { - height += theme_cache.custom_button->get_minimum_size().height; - } - - } break; - default: { - } - } + height = MAX(height, p_item->get_minimum_size(i).y); } int item_min_height = MAX(theme_cache.font->get_height(theme_cache.font_size), p_item->get_custom_minimum_height()); if (height < item_min_height) { @@ -4702,6 +4668,7 @@ void Tree::item_edited(int p_column, TreeItem *p_item, MouseButton p_custom_mous edited_col = p_column; if (p_item != nullptr && p_column >= 0 && p_column < p_item->cells.size()) { edited_item->cells.write[p_column].dirty = true; + edited_item->cells.write[p_column].cached_minimum_size_dirty = true; } emit_signal(SNAME("item_edited")); if (p_custom_mouse_index != MouseButton::NONE) { @@ -5362,14 +5329,16 @@ void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) { int y_offset = get_item_offset(p_item); if (y_offset != -1) { - const int tbh = _get_title_button_height(); - y_offset -= tbh; + const int title_button_height = _get_title_button_height(); + y_offset -= title_button_height; const int cell_h = compute_item_height(p_item) + theme_cache.v_separation; - int screen_h = area_size.height - tbh; + int screen_h = area_size.height - title_button_height; if (p_center_on_item) { - v_scroll->set_value(y_offset - (screen_h - cell_h) / 2.0f); + // This makes sure that centering the offset doesn't overflow. + const double v_scroll_value = y_offset - MAX((screen_h - cell_h) / 2.0, 0.0); + v_scroll->set_value(v_scroll_value); } else { if (cell_h > screen_h) { // Screen size is too small, maybe it was not resized yet. v_scroll->set_value(y_offset); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 045c3ae02d..fc2fe4320b 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -31,10 +31,8 @@ #include "window.h" #include "core/config/project_settings.h" -#include "core/debugger/engine_debugger.h" #include "core/input/shortcut.h" #include "core/string/translation_server.h" -#include "core/variant/variant_parser.h" #include "scene/gui/control.h" #include "scene/theme/theme_db.h" #include "scene/theme/theme_owner.h" @@ -1631,35 +1629,6 @@ bool Window::_can_consume_input_events() const { void Window::_window_input(const Ref<InputEvent> &p_ev) { ERR_MAIN_THREAD_GUARD; - if (EngineDebugger::is_active()) { - // Quit from game window using the stop shortcut (F8 by default). - // The custom shortcut is provided via environment variable when running from the editor. - if (debugger_stop_shortcut.is_null()) { - String shortcut_str = OS::get_singleton()->get_environment("__GODOT_EDITOR_STOP_SHORTCUT__"); - if (!shortcut_str.is_empty()) { - Variant shortcut_var; - - VariantParser::StreamString ss; - ss.s = shortcut_str; - - String errs; - int line; - VariantParser::parse(&ss, shortcut_var, errs, line); - debugger_stop_shortcut = shortcut_var; - } - - if (debugger_stop_shortcut.is_null()) { - // Define a default shortcut if it wasn't provided or is invalid. - debugger_stop_shortcut.instantiate(); - debugger_stop_shortcut->set_events({ (Variant)InputEventKey::create_reference(Key::F8) }); - } - } - - Ref<InputEventKey> k = p_ev; - if (k.is_valid() && k->is_pressed() && !k->is_echo() && debugger_stop_shortcut->matches_event(k)) { - EngineDebugger::get_singleton()->send_message("request_quit", Array()); - } - } if (exclusive_child != nullptr) { if (!is_embedding_subwindows()) { // Not embedding, no need for event. diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 6b1ce2b4ca..315ccaeb8c 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -512,6 +512,9 @@ void register_scene_types() { GDREGISTER_CLASS(AnimationNodeStateMachine); GDREGISTER_CLASS(AnimationNodeStateMachinePlayback); + GDREGISTER_INTERNAL_CLASS(AnimationNodeStartState); + GDREGISTER_INTERNAL_CLASS(AnimationNodeEndState); + GDREGISTER_CLASS(AnimationNodeSync); GDREGISTER_CLASS(AnimationNodeStateMachineTransition); GDREGISTER_CLASS(AnimationNodeOutput); diff --git a/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h b/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h index 0732153997..d1e50cb702 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h +++ b/scene/resources/2d/skeleton/skeleton_modification_stack_2d.h @@ -64,7 +64,7 @@ public: execution_mode_physics_process }; - Vector<Ref<SkeletonModification2D>> modifications = Vector<Ref<SkeletonModification2D>>(); + Vector<Ref<SkeletonModification2D>> modifications; void setup(); void execute(float p_delta, int p_execution_mode); diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp index ca80486363..5ecfc32622 100644 --- a/scene/resources/2d/tile_set.cpp +++ b/scene/resources/2d/tile_set.cpp @@ -699,6 +699,17 @@ uint32_t TileSet::get_physics_layer_collision_mask(int p_layer_index) const { return physics_layers[p_layer_index].collision_mask; } +void TileSet::set_physics_layer_collision_priority(int p_layer_index, real_t p_priority) { + ERR_FAIL_INDEX(p_layer_index, physics_layers.size()); + physics_layers.write[p_layer_index].collision_priority = p_priority; + emit_changed(); +} + +real_t TileSet::get_physics_layer_collision_priority(int p_layer_index) const { + ERR_FAIL_INDEX_V(p_layer_index, physics_layers.size(), 0); + return physics_layers[p_layer_index].collision_priority; +} + void TileSet::set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material) { ERR_FAIL_INDEX(p_layer_index, physics_layers.size()); physics_layers.write[p_layer_index].physics_material = p_physics_material; @@ -3900,6 +3911,13 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } set_physics_layer_collision_mask(index, p_value); return true; + } else if (components[1] == "collision_priority") { + ERR_FAIL_COND_V(p_value.get_type() != Variant::FLOAT, false); + while (index >= physics_layers.size()) { + add_physics_layer(); + } + set_physics_layer_collision_priority(index, p_value); + return true; } else if (components[1] == "physics_material") { Ref<PhysicsMaterial> physics_material = p_value; while (index >= physics_layers.size()) { @@ -4051,6 +4069,9 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { } else if (components[1] == "collision_mask") { r_ret = get_physics_layer_collision_mask(index); return true; + } else if (components[1] == "collision_priority") { + r_ret = get_physics_layer_collision_priority(index); + return true; } else if (components[1] == "physics_material") { r_ret = get_physics_layer_physics_material(index); return true; @@ -4176,6 +4197,13 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { } p_list->push_back(property_info); + // physics_layer_%d/collision_priority + property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/collision_priority", i)); + if (physics_layers[i].collision_priority == 1.0) { + property_info.usage ^= PROPERTY_USAGE_STORAGE; + } + p_list->push_back(property_info); + // physics_layer_%d/physics_material property_info = PropertyInfo(Variant::OBJECT, vformat("physics_layer_%d/physics_material", i), PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"); if (!physics_layers[i].physics_material.is_valid()) { @@ -4220,10 +4248,10 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { // Tile Proxies. // Note: proxies need to be set after sources are set. - p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Tile Proxies", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); - p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/source_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/coords_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::ARRAY, PNAME("tile_proxies/alternative_level"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::NIL, "Tile Proxies", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/source_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/coords_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::ARRAY, "tile_proxies/alternative_level", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); // Patterns. for (unsigned int pattern_index = 0; pattern_index < patterns.size(); pattern_index++) { @@ -4287,6 +4315,8 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("get_physics_layer_collision_layer", "layer_index"), &TileSet::get_physics_layer_collision_layer); ClassDB::bind_method(D_METHOD("set_physics_layer_collision_mask", "layer_index", "mask"), &TileSet::set_physics_layer_collision_mask); ClassDB::bind_method(D_METHOD("get_physics_layer_collision_mask", "layer_index"), &TileSet::get_physics_layer_collision_mask); + ClassDB::bind_method(D_METHOD("set_physics_layer_collision_priority", "layer_index", "priority"), &TileSet::set_physics_layer_collision_priority); + ClassDB::bind_method(D_METHOD("get_physics_layer_collision_priority", "layer_index"), &TileSet::get_physics_layer_collision_priority); ClassDB::bind_method(D_METHOD("set_physics_layer_physics_material", "layer_index", "physics_material"), &TileSet::set_physics_layer_physics_material); ClassDB::bind_method(D_METHOD("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material); @@ -4931,10 +4961,13 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const { } for (const KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { + const String formatted_key = itos(E_alternative.key); + // Add a dummy property to show the alternative exists. - tile_property_list.push_back(PropertyInfo(Variant::INT, vformat("%d", E_alternative.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + tile_property_list.push_back(PropertyInfo(Variant::INT, formatted_key, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); // Get the alternative tile's properties and append them to the list of properties. + const String alternative_property_info_prefix = formatted_key + '/'; List<PropertyInfo> alternative_property_list; E_alternative.value->get_property_list(&alternative_property_list); for (PropertyInfo &alternative_property_info : alternative_property_list) { @@ -4943,14 +4976,15 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const { if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) { alternative_property_info.usage ^= PROPERTY_USAGE_STORAGE; } - alternative_property_info.name = vformat("%s/%s", vformat("%d", E_alternative.key), alternative_property_info.name); + alternative_property_info.name = alternative_property_info_prefix + alternative_property_info.name; tile_property_list.push_back(alternative_property_info); } } // Add all alternative. + const String property_info_prefix = vformat("%d:%d/", E_tile.key.x, E_tile.key.y); for (PropertyInfo &tile_property_info : tile_property_list) { - tile_property_info.name = vformat("%s/%s", vformat("%d:%d", E_tile.key.x, E_tile.key.y), tile_property_info.name); + tile_property_info.name = property_info_prefix + tile_property_info.name; p_list->push_back(tile_property_info); } } diff --git a/scene/resources/2d/tile_set.h b/scene/resources/2d/tile_set.h index 7979e2ca39..6d3ccd1d2d 100644 --- a/scene/resources/2d/tile_set.h +++ b/scene/resources/2d/tile_set.h @@ -327,6 +327,7 @@ private: struct PhysicsLayer { uint32_t collision_layer = 1; uint32_t collision_mask = 1; + real_t collision_priority = 1.0; Ref<PhysicsMaterial> physics_material; }; Vector<PhysicsLayer> physics_layers; @@ -448,6 +449,8 @@ public: uint32_t get_physics_layer_collision_layer(int p_layer_index) const; void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask); uint32_t get_physics_layer_collision_mask(int p_layer_index) const; + void set_physics_layer_collision_priority(int p_layer_index, real_t p_priority); + real_t get_physics_layer_collision_priority(int p_layer_index) const; void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material); Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const; @@ -836,7 +839,7 @@ private: bool flip_v = false; bool transpose = false; Vector2i texture_origin; - Ref<Material> material = Ref<Material>(); + Ref<Material> material; Color modulate = Color(1.0, 1.0, 1.0, 1.0); int z_index = 0; int y_sort_origin = 0; diff --git a/scene/resources/3d/importer_mesh.cpp b/scene/resources/3d/importer_mesh.cpp index e255cb077f..f040f04cd8 100644 --- a/scene/resources/3d/importer_mesh.cpp +++ b/scene/resources/3d/importer_mesh.cpp @@ -168,10 +168,56 @@ void ImporterMesh::set_surface_material(int p_surface, const Ref<Material> &p_ma mesh.unref(); } -void ImporterMesh::optimize_indices_for_cache() { +template <typename T> +static Vector<T> _remap_array(Vector<T> p_array, const Vector<uint32_t> &p_remap, uint32_t p_vertex_count) { + ERR_FAIL_COND_V(p_array.size() % p_remap.size() != 0, p_array); + int num_elements = p_array.size() / p_remap.size(); + T *data = p_array.ptrw(); + SurfaceTool::remap_vertex_func(data, data, p_remap.size(), sizeof(T) * num_elements, p_remap.ptr()); + p_array.resize(p_vertex_count * num_elements); + return p_array; +} + +static void _remap_arrays(Array &r_arrays, const Vector<uint32_t> &p_remap, uint32_t p_vertex_count) { + for (int i = 0; i < r_arrays.size(); i++) { + if (i == RS::ARRAY_INDEX) { + continue; + } + + switch (r_arrays[i].get_type()) { + case Variant::NIL: + break; + case Variant::PACKED_VECTOR3_ARRAY: + r_arrays[i] = _remap_array<Vector3>(r_arrays[i], p_remap, p_vertex_count); + break; + case Variant::PACKED_VECTOR2_ARRAY: + r_arrays[i] = _remap_array<Vector2>(r_arrays[i], p_remap, p_vertex_count); + break; + case Variant::PACKED_FLOAT32_ARRAY: + r_arrays[i] = _remap_array<float>(r_arrays[i], p_remap, p_vertex_count); + break; + case Variant::PACKED_INT32_ARRAY: + r_arrays[i] = _remap_array<int32_t>(r_arrays[i], p_remap, p_vertex_count); + break; + case Variant::PACKED_BYTE_ARRAY: + r_arrays[i] = _remap_array<uint8_t>(r_arrays[i], p_remap, p_vertex_count); + break; + case Variant::PACKED_COLOR_ARRAY: + r_arrays[i] = _remap_array<Color>(r_arrays[i], p_remap, p_vertex_count); + break; + default: + ERR_FAIL_MSG("Unhandled array type."); + } + } +} + +void ImporterMesh::optimize_indices() { if (!SurfaceTool::optimize_vertex_cache_func) { return; } + if (!SurfaceTool::optimize_vertex_fetch_remap_func || !SurfaceTool::remap_vertex_func || !SurfaceTool::remap_index_func) { + return; + } for (int i = 0; i < surfaces.size(); i++) { if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) { @@ -188,10 +234,48 @@ void ImporterMesh::optimize_indices_for_cache() { continue; } + // Optimize indices for vertex cache to establish final triangle order. int *indices_ptr = indices.ptrw(); SurfaceTool::optimize_vertex_cache_func((unsigned int *)indices_ptr, (const unsigned int *)indices_ptr, index_count, vertex_count); + surfaces.write[i].arrays[RS::ARRAY_INDEX] = indices; + + for (int j = 0; j < surfaces[i].lods.size(); ++j) { + Surface::LOD &lod = surfaces.write[i].lods.write[j]; + int *lod_indices_ptr = lod.indices.ptrw(); + SurfaceTool::optimize_vertex_cache_func((unsigned int *)lod_indices_ptr, (const unsigned int *)lod_indices_ptr, lod.indices.size(), vertex_count); + } + // Concatenate indices for all LODs in the order of coarse->fine; this establishes the effective order of vertices, + // and is important to optimize for vertex fetch (all GPUs) and shading (Mali GPUs) + PackedInt32Array merged_indices; + for (int j = surfaces[i].lods.size() - 1; j >= 0; --j) { + merged_indices.append_array(surfaces[i].lods[j].indices); + } + merged_indices.append_array(indices); + + // Generate remap array that establishes optimal vertex order according to the order of indices above. + Vector<uint32_t> remap; + remap.resize(vertex_count); + unsigned int new_vertex_count = SurfaceTool::optimize_vertex_fetch_remap_func(remap.ptrw(), (const unsigned int *)merged_indices.ptr(), merged_indices.size(), vertex_count); + + // We need to remap all vertex and index arrays in lockstep according to the remap. + SurfaceTool::remap_index_func((unsigned int *)indices_ptr, (const unsigned int *)indices_ptr, index_count, remap.ptr()); surfaces.write[i].arrays[RS::ARRAY_INDEX] = indices; + + for (int j = 0; j < surfaces[i].lods.size(); ++j) { + Surface::LOD &lod = surfaces.write[i].lods.write[j]; + int *lod_indices_ptr = lod.indices.ptrw(); + SurfaceTool::remap_index_func((unsigned int *)lod_indices_ptr, (const unsigned int *)lod_indices_ptr, lod.indices.size(), remap.ptr()); + } + + _remap_arrays(surfaces.write[i].arrays, remap, new_vertex_count); + for (int j = 0; j < surfaces[i].blend_shape_data.size(); j++) { + _remap_arrays(surfaces.write[i].blend_shape_data.write[j].arrays, remap, new_vertex_count); + } + } + + if (shadow_mesh.is_valid()) { + shadow_mesh->optimize_indices(); } } @@ -215,9 +299,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf if (!SurfaceTool::simplify_with_attrib_func) { return; } - if (!SurfaceTool::optimize_vertex_cache_func) { - return; - } LocalVector<Transform3D> bone_transform_vector; for (int i = 0; i < p_bone_transform_array.size(); i++) { @@ -431,12 +512,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf } surfaces.write[i].lods.sort_custom<Surface::LODComparator>(); - - for (int j = 0; j < surfaces.write[i].lods.size(); j++) { - Surface::LOD &lod = surfaces.write[i].lods.write[j]; - unsigned int *lod_indices_ptr = (unsigned int *)lod.indices.ptrw(); - SurfaceTool::optimize_vertex_cache_func(lod_indices_ptr, lod_indices_ptr, lod.indices.size(), vertex_count); - } } } @@ -574,10 +649,6 @@ void ImporterMesh::create_shadow_mesh() { index_wptr[j] = vertex_remap[index]; } - if (SurfaceTool::optimize_vertex_cache_func && surfaces[i].primitive == Mesh::PRIMITIVE_TRIANGLES) { - SurfaceTool::optimize_vertex_cache_func((unsigned int *)index_wptr, (const unsigned int *)index_wptr, index_count, new_vertices.size()); - } - new_surface[RS::ARRAY_INDEX] = new_indices; // Make sure the same LODs as the full version are used. @@ -596,10 +667,6 @@ void ImporterMesh::create_shadow_mesh() { index_wptr[k] = vertex_remap[index]; } - if (SurfaceTool::optimize_vertex_cache_func && surfaces[i].primitive == Mesh::PRIMITIVE_TRIANGLES) { - SurfaceTool::optimize_vertex_cache_func((unsigned int *)index_wptr, (const unsigned int *)index_wptr, index_count, new_vertices.size()); - } - lods[surfaces[i].lods[j].distance] = new_indices; } } diff --git a/scene/resources/3d/importer_mesh.h b/scene/resources/3d/importer_mesh.h index 7776e78f11..2bdf759da6 100644 --- a/scene/resources/3d/importer_mesh.h +++ b/scene/resources/3d/importer_mesh.h @@ -113,7 +113,7 @@ public: void set_surface_material(int p_surface, const Ref<Material> &p_material); - void optimize_indices_for_cache(); + void optimize_indices(); void generate_lods(float p_normal_merge_angle, Array p_skin_pose_transform_array); diff --git a/scene/resources/audio_stream_wav.cpp b/scene/resources/audio_stream_wav.cpp index f9787dde2e..539001bf25 100644 --- a/scene/resources/audio_stream_wav.cpp +++ b/scene/resources/audio_stream_wav.cpp @@ -624,7 +624,7 @@ Error AudioStreamWAV::save_to_wav(const String &p_path) { } String file_path = p_path; - if (!(file_path.substr(file_path.length() - 4, 4) == ".wav")) { + if (file_path.substr(file_path.length() - 4, 4).to_lower() != ".wav") { file_path += ".wav"; } diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index f8c70c3002..b5e23e9832 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -130,10 +130,7 @@ int Environment::get_canvas_max_layer() const { void Environment::set_camera_feed_id(int p_id) { bg_camera_feed_id = p_id; -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - RS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id); -#endif + RS::get_singleton()->environment_set_camera_feed_id(environment, bg_camera_feed_id); } int Environment::get_camera_feed_id() const { diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 5e4136f449..a4677d917d 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -647,13 +647,13 @@ void FontFile::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz) wa[ofs_dst + 1] = r[ofs_src + 3]; } } - Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r)); + Ref<Image> img_r = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_r)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r); - Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g); - Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b)); + Ref<Image> img_b = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_b)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b); - Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a)); + Ref<Image> img_a = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_a)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a); } @@ -738,22 +738,22 @@ void FontFile::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz) } } } - Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r)); + Ref<Image> img_r = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_r)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r); - Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g); - Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b)); + Ref<Image> img_b = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_b)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b); - Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a)); + Ref<Image> img_a = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_a)); set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a); - Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro)); + Ref<Image> img_ro = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_ro)); set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro); - Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go)); + Ref<Image> img_go = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_go)); set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go); - Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo)); + Ref<Image> img_bo = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_bo)); set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo); - Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao)); + Ref<Image> img_ao = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_ao)); set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao); } @@ -806,10 +806,10 @@ void FontFile::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) { } } } - Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g)); + Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_RGBA8, imgdata_g)); set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g); - Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o)); + Ref<Image> img_o = memnew(Image(w, h, false, Image::FORMAT_RGBA8, imgdata_o)); set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o); } @@ -838,7 +838,7 @@ void FontFile::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, in wg[ofs_dst + 1] = r[ofs_src + p_ch]; } } - Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g)); set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g); } @@ -878,10 +878,10 @@ void FontFile::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, in } } } - Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g)); + Ref<Image> img_g = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_g)); set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g); - Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o)); + Ref<Image> img_o = memnew(Image(w, h, false, Image::FORMAT_LA8, imgdata_o)); set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o); } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index d6fe4385c4..bb3aad0f28 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -786,7 +786,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has Dictionary missing_resource_properties = p_node->get_meta(META_MISSING_RESOURCES, Dictionary()); for (const PropertyInfo &E : plist) { - if (!(E.usage & PROPERTY_USAGE_STORAGE)) { + if (!(E.usage & PROPERTY_USAGE_STORAGE) && !missing_resource_properties.has(E.name)) { continue; } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 4a318a10f0..535903a1b6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -600,7 +600,7 @@ Error ResourceLoaderText::load() { if (do_assign) { bool set_valid = true; - if (value.get_type() == Variant::OBJECT && missing_resource != nullptr) { + if (value.get_type() == Variant::OBJECT && missing_resource == nullptr && ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) { // If the property being set is a missing resource (and the parent is not), // then setting it will most likely not work. // Instead, save it as metadata. @@ -723,24 +723,25 @@ Error ResourceLoaderText::load() { if (error) { if (error != ERR_FILE_EOF) { _printerr(); - } else { - error = OK; - if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { - if (!ResourceCache::has(res_path)) { - resource->set_path(res_path); - } - resource->set_as_translation_remapped(translation_remapped); - } else { - resource->set_path_cache(res_path); + return error; + } + // EOF, Done parsing. + error = OK; + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + if (!ResourceCache::has(res_path)) { + resource->set_path(res_path); } + resource->set_as_translation_remapped(translation_remapped); + } else { + resource->set_path_cache(res_path); } - return error; + break; } if (!assign.is_empty()) { bool set_valid = true; - if (value.get_type() == Variant::OBJECT && missing_resource != nullptr) { + if (value.get_type() == Variant::OBJECT && missing_resource == nullptr && ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) { // If the property being set is a missing resource (and the parent is not), // then setting it will most likely not work. // Instead, save it as metadata. @@ -1900,7 +1901,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso #endif } - Dictionary missing_resource_properties = p_resource->get_meta(META_MISSING_RESOURCES, Dictionary()); + Dictionary missing_resource_properties = res->get_meta(META_MISSING_RESOURCES, Dictionary()); List<PropertyInfo> property_list; res->get_property_list(&property_list); @@ -1912,7 +1913,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso continue; } - if (PE->get().usage & PROPERTY_USAGE_STORAGE) { + if (PE->get().usage & PROPERTY_USAGE_STORAGE || missing_resource_properties.has(PE->get().name)) { String name = PE->get().name; Variant value; if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 6921885ee0..c230cf1b70 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -33,10 +33,10 @@ #define EQ_VERTEX_DIST 0.00001 SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr; +SurfaceTool::OptimizeVertexFetchRemapFunc SurfaceTool::optimize_vertex_fetch_remap_func = nullptr; SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr; SurfaceTool::SimplifyWithAttribFunc SurfaceTool::simplify_with_attrib_func = nullptr; SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr; -SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr; SurfaceTool::GenerateRemapFunc SurfaceTool::generate_remap_func = nullptr; SurfaceTool::RemapVertexFunc SurfaceTool::remap_vertex_func = nullptr; SurfaceTool::RemapIndexFunc SurfaceTool::remap_index_func = nullptr; diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 3b18e082a1..68dc9e7198 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -90,14 +90,14 @@ public: typedef void (*OptimizeVertexCacheFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, size_t vertex_count); static OptimizeVertexCacheFunc optimize_vertex_cache_func; + typedef size_t (*OptimizeVertexFetchRemapFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, size_t vertex_count); + static OptimizeVertexFetchRemapFunc optimize_vertex_fetch_remap_func; typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float *r_error); static SimplifyFunc simplify_func; typedef size_t (*SimplifyWithAttribFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_data, size_t vertex_count, size_t vertex_stride, const float *attributes, size_t attribute_stride, const float *attribute_weights, size_t attribute_count, const unsigned char *vertex_lock, size_t target_index_count, float target_error, unsigned int options, float *result_error); static SimplifyWithAttribFunc simplify_with_attrib_func; typedef float (*SimplifyScaleFunc)(const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride); static SimplifyScaleFunc simplify_scale_func; - typedef size_t (*SimplifySloppyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *out_result_error); - static SimplifySloppyFunc simplify_sloppy_func; typedef size_t (*GenerateRemapFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const void *vertices, size_t vertex_count, size_t vertex_size); static GenerateRemapFunc generate_remap_func; typedef void (*RemapVertexFunc)(void *destination, const void *vertices, size_t vertex_count, size_t vertex_size, const unsigned int *remap); @@ -222,7 +222,9 @@ public: void clear(); - LocalVector<Vertex> &get_vertex_array() { return vertex_array; } + LocalVector<Vertex> &get_vertex_array() { + return vertex_array; + } void create_from_triangle_arrays(const Array &p_arrays); void create_from_arrays(const Array &p_arrays, Mesh::PrimitiveType p_primitive_type = Mesh::PRIMITIVE_TRIANGLES); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 29a8541cb0..65c6e40241 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -112,6 +112,11 @@ void TextParagraph::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lines_visible"), "set_max_lines_visible", "get_max_lines_visible"); + ClassDB::bind_method(D_METHOD("set_line_spacing", "line_spacing"), &TextParagraph::set_line_spacing); + ClassDB::bind_method(D_METHOD("get_line_spacing"), &TextParagraph::get_line_spacing); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing"), "set_line_spacing", "get_line_spacing"); + ClassDB::bind_method(D_METHOD("get_line_objects", "line"), &TextParagraph::get_line_objects); ClassDB::bind_method(D_METHOD("get_line_object_rect", "line", "key"), &TextParagraph::get_line_object_rect); ClassDB::bind_method(D_METHOD("get_line_size", "line"), &TextParagraph::get_line_size); @@ -180,6 +185,7 @@ void TextParagraph::_shape_lines() { for (int i = 0; i < line_breaks.size(); i = i + 2) { RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x; + h += line_spacing; if (!tab_stops.is_empty()) { TS->shaped_text_tab_align(line, tab_stops); } @@ -574,12 +580,18 @@ Size2 TextParagraph::get_size() const { } size.x = MAX(size.x, lsize.x); size.y += lsize.y; + if (i != visible_lines - 1) { + size.y += line_spacing; + } } else { if (h_offset > 0 && i <= dropcap_lines) { lsize.y += h_offset; } size.x += lsize.x; size.y = MAX(size.y, lsize.y); + if (i != visible_lines - 1) { + size.x += line_spacing; + } } } if (h_offset > 0) { @@ -612,6 +624,19 @@ int TextParagraph::get_max_lines_visible() const { return max_lines_visible; } +void TextParagraph::set_line_spacing(float p_spacing) { + _THREAD_SAFE_METHOD_ + + if (line_spacing != p_spacing) { + line_spacing = p_spacing; + lines_dirty = true; + } +} + +float TextParagraph::get_line_spacing() const { + return line_spacing; +} + Array TextParagraph::get_line_objects(int p_line) const { _THREAD_SAFE_METHOD_ @@ -697,10 +722,10 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const { if (i != p_line) { if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = 0.f; - ofs.y += TS->shaped_text_get_descent(lines_rid[i]); + ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } else { ofs.y = 0.f; - ofs.x += TS->shaped_text_get_descent(lines_rid[i]); + ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } } } @@ -872,10 +897,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo TS->shaped_text_draw(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color); if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_descent(lines_rid[i]); + ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_descent(lines_rid[i]); + ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } } } @@ -974,10 +999,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli TS->shaped_text_draw_outline(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color); if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_descent(lines_rid[i]); + ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_descent(lines_rid[i]); + ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + line_spacing; } } } @@ -1001,17 +1026,21 @@ int TextParagraph::hit_test(const Point2 &p_coords) const { if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(line_rid).y)) { return TS->shaped_text_hit_test_position(line_rid, p_coords.x); } - ofs.y += TS->shaped_text_get_size(line_rid).y; + ofs.y += TS->shaped_text_get_size(line_rid).y + line_spacing; } else { if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(line_rid).x)) { return TS->shaped_text_hit_test_position(line_rid, p_coords.y); } - ofs.y += TS->shaped_text_get_size(line_rid).x; + ofs.y += TS->shaped_text_get_size(line_rid).x + line_spacing; } } return TS->shaped_text_get_range(rid).y; } +bool TextParagraph::is_dirty() { + return lines_dirty; +} + void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const { _THREAD_SAFE_METHOD_ diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index 8b7f21fa9a..966ce556d5 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -51,6 +51,7 @@ private: bool lines_dirty = true; + float line_spacing = 0.0; float width = -1.0; int max_lines_visible = -1; @@ -122,6 +123,9 @@ public: void set_max_lines_visible(int p_lines); int get_max_lines_visible() const; + void set_line_spacing(float p_spacing); + float get_line_spacing() const; + Size2 get_non_wrapped_size() const; Size2 get_size() const; @@ -152,6 +156,8 @@ public: int hit_test(const Point2 &p_coords) const; + bool is_dirty(); + Mutex &get_mutex() const { return _thread_safe_; } TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 933e990920..847867fa4d 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1368,7 +1368,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por ERR_FAIL_INDEX(p_type, TYPE_MAX); Graph *g = &graph[p_type]; - for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { + for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { g->connections.erase(E); g->nodes[p_from_node].next_connected_nodes.erase(p_to_node); @@ -1921,13 +1921,13 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } for (const KeyValue<String, Varying> &E : varyings) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", PNAME("varyings"), E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", "varyings", E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); } #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { for (const KeyValue<String, Variant> &E : preview_params) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", PNAME("preview_params"), E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING, vformat("%s/%s", "preview_params", E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); } } #endif // TOOLS_ENABLED diff --git a/scu_builders.py b/scu_builders.py index 6bf87b9163..e0bfffc320 100644 --- a/scu_builders.py +++ b/scu_builders.py @@ -259,10 +259,6 @@ def process_folder(folders, sought_exceptions=[], includes_per_scu=0, extension= def generate_scu_files(max_includes_per_scu): - print("=============================") - print("Single Compilation Unit Build") - print("=============================") - global _max_includes_per_scu _max_includes_per_scu = max_includes_per_scu diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 42aa43269b..d5c37c2acc 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -281,7 +281,7 @@ double AudioStream::get_bpm() const { } bool AudioStream::has_loop() const { - bool ret = 0; + bool ret = false; GDVIRTUAL_CALL(_has_loop, ret); return ret; } diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 14c4c3b7e1..63b2f28e74 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -371,10 +371,14 @@ void AudioServer::_mix_step() { bus->soloed = false; } } + // This is legacy code from 3.x that allows video players and other audio sources that do not implement AudioStreamPlayback to output audio. for (CallbackItem *ci : mix_callback_list) { ci->callback(ci->userdata); } + // Main mixing loop for audio streams. + // The basic idea here is to copy the samples returned by the AudioStreamPlayback's mix function into the audio buffers, + // while always maintaining a lookahead buffer of size LOOKAHEAD_BUFFER_SIZE to allow fade-outs for sudden stoppages. for (AudioStreamPlaybackListNode *playback : playback_list) { // Paused streams are no-ops. Don't even mix audio from the stream playback. if (playback->state.load() == AudioStreamPlaybackListNode::PAUSED) { @@ -385,22 +389,26 @@ void AudioServer::_mix_step() { continue; } + // If `fading_out` is true, we're in the process of fading out the stream playback. + // TODO: Currently this sets the volume of the stream to 0 which creates a linear interpolation between its previous volume and silence. + // A more punchy option for fading out could be to just use the lookahead buffer. bool fading_out = playback->state.load() == AudioStreamPlaybackListNode::FADE_OUT_TO_DELETION || playback->state.load() == AudioStreamPlaybackListNode::FADE_OUT_TO_PAUSE; AudioFrame *buf = mix_buffer.ptrw(); - // Copy the lookeahead buffer into the mix buffer. + // Copy the old contents of the lookahead buffer into the beginning of the mix buffer. for (int i = 0; i < LOOKAHEAD_BUFFER_SIZE; i++) { buf[i] = playback->lookahead[i]; } - // Mix the audio stream + // Mix the audio stream. unsigned int mixed_frames = playback->stream_playback->mix(&buf[LOOKAHEAD_BUFFER_SIZE], playback->pitch_scale.get(), buffer_size); if (tag_used_audio_streams && playback->stream_playback->is_playing()) { playback->stream_playback->tag_used_streams(); } + // Check to see if the stream has run out of samples. if (mixed_frames != buffer_size) { // We know we have at least the size of our lookahead buffer for fade-out purposes. @@ -416,42 +424,52 @@ void AudioServer::_mix_step() { new_state = AudioStreamPlaybackListNode::AWAITING_DELETION; playback->state.store(new_state); } else { - // Move the last little bit of what we just mixed into our lookahead buffer. + // Move the last little bit of what we just mixed into our lookahead buffer for the next call to _mix_step. for (int i = 0; i < LOOKAHEAD_BUFFER_SIZE; i++) { playback->lookahead[i] = buf[buffer_size + i]; } } - AudioStreamPlaybackBusDetails *ptr = playback->bus_details.load(); - ERR_FAIL_NULL(ptr); - // By putting null into the bus details pointers, we're taking ownership of their memory for the duration of this mix. - AudioStreamPlaybackBusDetails bus_details = *ptr; + // Get the bus details for this playback. This contains information about which buses the playback is assigned to and the volume of the playback on each bus. + AudioStreamPlaybackBusDetails *bus_details_ptr = playback->bus_details.load(); + ERR_FAIL_NULL(bus_details_ptr); + // Make a copy of the bus details so we can modify it without worrying about other threads. + AudioStreamPlaybackBusDetails bus_details = *bus_details_ptr; // Mix to any active buses. for (int idx = 0; idx < MAX_BUSES_PER_PLAYBACK; idx++) { if (!bus_details.bus_active[idx]) { continue; } + // This is the AudioServer-internal index of the bus we're mixing to in this step of the loop. Not to be confused with `idx` which is an index into `AudioStreamPlaybackBusDetails` member var arrays. int bus_idx = thread_find_bus_index(bus_details.bus[idx]); + // It's important to know whether or not this bus was active in the previous mix step of this stream. If it was, we need to perform volume interpolation to avoid pops. int prev_bus_idx = -1; for (int search_idx = 0; search_idx < MAX_BUSES_PER_PLAYBACK; search_idx++) { if (!playback->prev_bus_details->bus_active[search_idx]) { continue; } + // If the StringNames of the buses match, we've found the previous bus index. This indicates that this playback mixed to `prev_bus_details->bus[prev_bus_index]` in the previous mix step, which gives us a way to look up the playback's previous volume. if (playback->prev_bus_details->bus[search_idx].hash() == bus_details.bus[idx].hash()) { prev_bus_idx = search_idx; + break; } } + // It's now time to mix to the bus. We do this by going through each channel of the bus and mixing to it. + // The channels correspond to output channels of the audio device, e.g. stereo or 5.1. To reduce needless nesting, this is done with a helper method named `_mix_step_for_channel`. for (int channel_idx = 0; channel_idx < channel_count; channel_idx++) { AudioFrame *channel_buf = thread_get_channel_mix_buffer(bus_idx, channel_idx); + // TODO: This `fading_out` check could be replaced with with an exponential fadeout of the samples from the lookahead buffer for more punchy results. if (fading_out) { bus_details.volume[idx][channel_idx] = AudioFrame(0, 0); } AudioFrame channel_vol = bus_details.volume[idx][channel_idx]; - AudioFrame prev_channel_vol = AudioFrame(0, 0); + // If this bus was not active in the previous mix step, we want to start playback at the full volume to avoid crushing transients. + AudioFrame prev_channel_vol = channel_vol; + // If this bus was active in the previous mix step, we need to interpolate between the previous volume and the current volume to avoid pops. Set `prev_channel_volume` accordingly. if (prev_bus_idx != -1) { prev_channel_vol = playback->prev_bus_details->volume[prev_bus_idx][channel_idx]; } @@ -480,7 +498,7 @@ void AudioServer::_mix_step() { for (int channel_idx = 0; channel_idx < channel_count; channel_idx++) { AudioFrame *channel_buf = thread_get_channel_mix_buffer(bus_idx, channel_idx); AudioFrame prev_channel_vol = playback->prev_bus_details->volume[idx][channel_idx]; - // Fade out to silence + // Fade out to silence. This could be replaced with an exponential fadeout of the samples from the lookahead buffer for more punchy results. _mix_step_for_channel(channel_buf, buf, prev_channel_vol, AudioFrame(0, 0), playback->attenuation_filter_cutoff_hz.get(), playback->highshelf_gain.get(), &playback->filter_process[channel_idx * 2], &playback->filter_process[channel_idx * 2 + 1]); } } @@ -501,15 +519,12 @@ void AudioServer::_mix_step() { switch (playback->state.load()) { case AudioStreamPlaybackListNode::AWAITING_DELETION: case AudioStreamPlaybackListNode::FADE_OUT_TO_DELETION: + // Remove the playback from the list. _delete_stream_playback_list_node(playback); break; case AudioStreamPlaybackListNode::FADE_OUT_TO_PAUSE: { // Pause the stream. - AudioStreamPlaybackListNode::PlaybackState old_state, new_state; - do { - old_state = playback->state.load(); - new_state = AudioStreamPlaybackListNode::PAUSED; - } while (!playback->state.compare_exchange_strong(/* expected= */ old_state, new_state)); + playback->state.store(AudioStreamPlaybackListNode::PAUSED); } break; case AudioStreamPlaybackListNode::PLAYING: case AudioStreamPlaybackListNode::PAUSED: @@ -518,13 +533,13 @@ void AudioServer::_mix_step() { } } + // Now that all of the buses have their audio sources mixed into them, we can process the effects and bus sends. for (int i = buses.size() - 1; i >= 0; i--) { - //go bus by bus Bus *bus = buses[i]; for (int k = 0; k < bus->channels.size(); k++) { if (bus->channels[k].active && !bus->channels[k].used) { - //buffer was not used, but it's still active, so it must be cleaned + // Buffer was not used, but it's still active, so it must be cleaned. AudioFrame *buf = bus->channels.write[k].buffer.ptrw(); for (uint32_t j = 0; j < buffer_size; j++) { @@ -533,7 +548,7 @@ void AudioServer::_mix_step() { } } - //process effects + // Process effects. if (!bus->bypass) { for (int j = 0; j < bus->effects.size(); j++) { if (!bus->effects[j].enabled) { @@ -551,7 +566,7 @@ void AudioServer::_mix_step() { bus->channels.write[k].effect_instances.write[j]->process(bus->channels[k].buffer.ptr(), temp_buffer.write[k].ptrw(), buffer_size); } - //swap buffers, so internal buffer always has the right data + // Swap buffers, so internal buffer always has the right data. for (int k = 0; k < bus->channels.size(); k++) { if (!(buses[i]->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) { continue; @@ -565,17 +580,17 @@ void AudioServer::_mix_step() { } } - //process send + // Process send. Bus *send = nullptr; if (i > 0) { - //everything has a send save for master bus + // Everything has a send except for the master bus. if (!bus_map.has(bus->send)) { send = buses[0]; } else { send = bus_map[bus->send]; - if (send->index_cache >= bus->index_cache) { //invalid, send to master + if (send->index_cache >= bus->index_cache) { // Invalid, send to master. send = buses[0]; } } @@ -603,7 +618,7 @@ void AudioServer::_mix_step() { } } - //apply volume and compute peak + // Apply volume and compute peak. for (uint32_t j = 0; j < buffer_size; j++) { buf[j] *= volume; @@ -620,7 +635,7 @@ void AudioServer::_mix_step() { bus->channels.write[k].peak_volume = AudioFrame(Math::linear_to_db(peak.left + AUDIO_PEAK_OFFSET), Math::linear_to_db(peak.right + AUDIO_PEAK_OFFSET)); if (!bus->channels[k].used) { - //see if any audio is contained, because channel was not used + // See if any audio is contained, because channel was not used. if (MAX(peak.right, peak.left) > Math::db_to_linear(channel_disable_threshold_db)) { bus->channels.write[k].last_mix_with_audio = mix_frames; @@ -631,7 +646,7 @@ void AudioServer::_mix_step() { } if (send) { - //if not master bus, send + // If not master bus, send. AudioFrame *target_buf = thread_get_channel_mix_buffer(send->index_cache, k); for (uint32_t j = 0; j < buffer_size; j++) { @@ -646,6 +661,7 @@ void AudioServer::_mix_step() { } void AudioServer::_mix_step_for_channel(AudioFrame *p_out_buf, AudioFrame *p_source_buf, AudioFrame p_vol_start, AudioFrame p_vol_final, float p_attenuation_filter_cutoff_hz, float p_highshelf_gain, AudioFilterSW::Processor *p_processor_l, AudioFilterSW::Processor *p_processor_r) { + // TODO: In the future it could be nice to replace all of these hardcoded effects with something a bit cleaner and more flexible, but for now this is what we do to support 3D audio players. if (p_highshelf_gain != 0) { AudioFilterSW filter; filter.set_mode(AudioFilterSW::HIGHSHELF); @@ -665,7 +681,7 @@ void AudioServer::_mix_step_for_channel(AudioFrame *p_out_buf, AudioFrame *p_sou p_processor_r->update_coeffs(buffer_size); for (unsigned int frame_idx = 0; frame_idx < buffer_size; frame_idx++) { - // Make this buffer size invariant if buffer_size ever becomes a project setting. + // TODO: Make lerp speed buffer-size-invariant if buffer_size ever becomes a project setting to avoid very small buffer sizes causing pops due to too-fast lerps. float lerp_param = (float)frame_idx / buffer_size; AudioFrame vol = p_vol_final * lerp_param + (1 - lerp_param) * p_vol_start; AudioFrame mixed = vol * p_source_buf[frame_idx]; @@ -676,7 +692,7 @@ void AudioServer::_mix_step_for_channel(AudioFrame *p_out_buf, AudioFrame *p_sou } else { for (unsigned int frame_idx = 0; frame_idx < buffer_size; frame_idx++) { - // Make this buffer size invariant if buffer_size ever becomes a project setting. + // TODO: Make lerp speed buffer-size-invariant if buffer_size ever becomes a project setting to avoid very small buffer sizes causing pops due to too-fast lerps. float lerp_param = (float)frame_idx / buffer_size; p_out_buf[frame_idx] += (p_vol_final * lerp_param + (1 - lerp_param) * p_vol_start) * p_source_buf[frame_idx]; } @@ -701,6 +717,7 @@ void AudioServer::_delete_stream_playback(Ref<AudioStreamPlayback> p_playback) { } void AudioServer::_delete_stream_playback_list_node(AudioStreamPlaybackListNode *p_playback_node) { + // Remove the playback from the list, registering a destructor to be run on the main thread. playback_list.erase(p_playback_node, [](AudioStreamPlaybackListNode *p) { delete p->prev_bus_details; delete p->bus_details.load(); @@ -1471,7 +1488,9 @@ void AudioServer::init_channels_and_buffers() { void AudioServer::init() { channel_disable_threshold_db = GLOBAL_DEF_RST("audio/buses/channel_disable_threshold_db", -60.0); channel_disable_frames = float(GLOBAL_DEF_RST(PropertyInfo(Variant::FLOAT, "audio/buses/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"), 2.0)) * get_mix_rate(); - buffer_size = 512; //hardcoded for now + // TODO: Buffer size is hardcoded for now. This would be really nice to have as a project setting because currently it limits audio latency to an absolute minimum of 11ms with default mix rate, but there's some additional work required to make that happen. See TODOs in `_mix_step_for_channel`. + // When this becomes a project setting, it should be specified in milliseconds rather than raw sample count, because 512 samples at 192khz is shorter than it is at 48khz, for example. + buffer_size = 512; init_channels_and_buffers(); diff --git a/servers/audio_server.h b/servers/audio_server.h index 8978ad438e..9a80882dd7 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -271,6 +271,14 @@ private: }; struct AudioStreamPlaybackListNode { + // The state machine for audio stream playbacks is as follows: + // 1. The playback is created and added to the playback list in the playing state. + // 2. The playback is (maybe) paused, and the state is set to FADE_OUT_TO_PAUSE. + // 2.1. The playback is mixed after being paused, and the audio server thread atomically sets the state to PAUSED after performing a brief fade-out. + // 3. The playback is (maybe) deleted, and the state is set to FADE_OUT_TO_DELETION. + // 3.1. The playback is mixed after being deleted, and the audio server thread atomically sets the state to AWAITING_DELETION after performing a brief fade-out. + // NOTE: The playback is not deallocated at this time because allocation and deallocation are not realtime-safe. + // 4. The playback is removed and deallocated on the main thread using the SafeList maybe_cleanup method. enum PlaybackState { PAUSED = 0, // Paused. Keep this stream playback around though so it can be restarted. PLAYING = 1, // Playing. Fading may still be necessary if volume changes! diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp index 4021d9564b..e93ab3a544 100644 --- a/servers/camera/camera_feed.cpp +++ b/servers/camera/camera_feed.cpp @@ -50,6 +50,8 @@ void CameraFeed::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rgb_image", "rgb_image"), &CameraFeed::set_rgb_image); ClassDB::bind_method(D_METHOD("set_ycbcr_image", "ycbcr_image"), &CameraFeed::set_ycbcr_image); + ClassDB::bind_method(D_METHOD("set_external", "width", "height"), &CameraFeed::set_external); + ClassDB::bind_method(D_METHOD("get_texture_tex_id", "feed_image_type"), &CameraFeed::get_texture_tex_id); ClassDB::bind_method(D_METHOD("get_datatype"), &CameraFeed::get_datatype); @@ -68,6 +70,7 @@ void CameraFeed::_bind_methods() { BIND_ENUM_CONSTANT(FEED_RGB); BIND_ENUM_CONSTANT(FEED_YCBCR); BIND_ENUM_CONSTANT(FEED_YCBCR_SEP); + BIND_ENUM_CONSTANT(FEED_EXTERNAL); BIND_ENUM_CONSTANT(FEED_UNSPECIFIED); BIND_ENUM_CONSTANT(FEED_FRONT); @@ -137,6 +140,10 @@ RID CameraFeed::get_texture(CameraServer::FeedImage p_which) { return texture[p_which]; } +uint64_t CameraFeed::get_texture_tex_id(CameraServer::FeedImage p_which) { + return RenderingServer::get_singleton()->texture_get_native_handle(texture[p_which]); +} + CameraFeed::CameraFeed() { // initialize our feed id = CameraServer::get_singleton()->get_free_id(); @@ -252,6 +259,19 @@ void CameraFeed::set_ycbcr_images(const Ref<Image> &p_y_img, const Ref<Image> &p } } +void CameraFeed::set_external(int p_width, int p_height) { + if ((base_width != p_width) || (base_height != p_height)) { + // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... + base_width = p_width; + base_height = p_height; + + auto new_texture = RenderingServer::get_singleton()->texture_external_create(p_width, p_height, 0); + RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_YCBCR_IMAGE], new_texture); + } + + datatype = CameraFeed::FEED_EXTERNAL; +} + bool CameraFeed::activate_feed() { // nothing to do here return true; diff --git a/servers/camera/camera_feed.h b/servers/camera/camera_feed.h index 492a909239..365ed7c635 100644 --- a/servers/camera/camera_feed.h +++ b/servers/camera/camera_feed.h @@ -49,7 +49,8 @@ public: FEED_NOIMAGE, // we don't have an image yet FEED_RGB, // our texture will contain a normal RGB texture that can be used directly FEED_YCBCR, // our texture will contain a YCbCr texture that needs to be converted to RGB before output - FEED_YCBCR_SEP // our camera is split into two textures, first plane contains Y data, second plane contains CbCr data + FEED_YCBCR_SEP, // our camera is split into two textures, first plane contains Y data, second plane contains CbCr data + FEED_EXTERNAL, // specific for android atm, camera feed is managed externally, assumed RGB for now }; enum FeedPosition { @@ -104,6 +105,7 @@ public: void set_transform(const Transform2D &p_transform); RID get_texture(CameraServer::FeedImage p_which); + uint64_t get_texture_tex_id(CameraServer::FeedImage p_which); CameraFeed(); CameraFeed(String p_name, FeedPosition p_position = CameraFeed::FEED_UNSPECIFIED); @@ -113,6 +115,7 @@ public: void set_rgb_image(const Ref<Image> &p_rgb_img); void set_ycbcr_image(const Ref<Image> &p_ycbcr_img); void set_ycbcr_images(const Ref<Image> &p_y_img, const Ref<Image> &p_cbcr_img); + void set_external(int p_width, int p_height); virtual bool set_format(int p_index, const Dictionary &p_parameters); virtual Array get_formats() const; diff --git a/servers/display_server.h b/servers/display_server.h index f983145193..916c006f01 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -361,13 +361,6 @@ public: virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW); virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; - // Note: The "internal" current orientation is not necessarily the current orientation and will often be 0 for most platforms. - // - // Some Android GPUs come with a HW-based rotator which means the screen gets rotated for free to - // whatever orientation the device is currently facing. But many Android GPUs emulate it via SW instead, - // which costs performance and power. This value is an optimization that tells Godot's compositor how to - // rotate the render texture before presenting to screen so that Android's compositor doesn't have to. - virtual int screen_get_internal_current_rotation(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return 0; } virtual void screen_set_keep_on(bool p_enable); //disable screensaver virtual bool screen_is_kept_on() const; diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 701b4da8f8..d01976acf2 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -612,8 +612,9 @@ void RendererCanvasCull::canvas_item_set_visibility_layer(RID p_item, uint32_t p uint32_t RendererCanvasCull::canvas_item_get_visibility_layer(RID p_item) { Item *canvas_item = canvas_item_owner.get_or_null(p_item); - if (!canvas_item) + if (!canvas_item) { return 0; + } return canvas_item->visibility_layer; } diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index c7a7532d76..808c82f712 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -1002,15 +1002,19 @@ void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuf MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); + Rect2i screen_rect; + float atlas_width = p_dst_size.width / p_rect.size.width; + float atlas_height = p_dst_size.height / p_rect.size.height; + screen_rect.position.x = (int32_t)(Math::round(p_rect.position.x * atlas_width)); + screen_rect.position.y = (int32_t)(Math::round(p_rect.position.y * atlas_height)); + screen_rect.size.width = (int32_t)(Math::round(p_dst_size.width)); + screen_rect.size.height = (int32_t)(Math::round(p_dst_size.height)); + CopyToDPPushConstant push_constant; - push_constant.screen_rect[0] = p_rect.position.x; - push_constant.screen_rect[1] = p_rect.position.y; - push_constant.screen_rect[2] = p_rect.size.width; - push_constant.screen_rect[3] = p_rect.size.height; push_constant.z_far = p_z_far; push_constant.z_near = p_z_near; - push_constant.texel_size[0] = 1.0f / p_dst_size.x; - push_constant.texel_size[1] = 1.0f / p_dst_size.y; + push_constant.texel_size[0] = 1.0f / p_dst_size.width; + push_constant.texel_size[1] = 1.0f / p_dst_size.height; push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign // setup our uniforms @@ -1021,7 +1025,7 @@ void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuf RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0); ERR_FAIL_COND(shader.is_null()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, Vector<Color>(), 1.0f, 0, screen_rect); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index 014f78e2b9..b6fc95d0f1 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -217,7 +217,6 @@ private: float z_far; float z_near; float texel_size[2]; - float screen_rect[4]; }; struct CopyToDP { diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 12ff28d7b0..235aa9f828 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -350,7 +350,7 @@ bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const { bool GI::voxel_gi_is_interior(RID p_voxel_gi) const { VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); - ERR_FAIL_NULL_V(voxel_gi, 0); + ERR_FAIL_NULL_V(voxel_gi, false); return voxel_gi->interior; } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 76d8972ad9..eb73a9d7e6 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -395,6 +395,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p RID xforms_uniform_set = surf->owner->transforms_uniform_set; SceneShaderForwardClustered::ShaderSpecialization pipeline_specialization = p_params->base_specialization; + pipeline_specialization.multimesh = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH); + pipeline_specialization.multimesh_format_2d = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D); + pipeline_specialization.multimesh_has_color = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR); + pipeline_specialization.multimesh_has_custom_data = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA); if constexpr (p_pass_mode == PASS_MODE_COLOR) { pipeline_specialization.use_light_soft_shadows = element_info.uses_softshadow; @@ -1961,7 +1965,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, Vector2(0.0f, 0.0f), this); } else { - sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, screen_size, p_render_data->scene_data->taa_jitter, this); + Projection projection = p_render_data->scene_data->cam_projection; + if (p_render_data->scene_data->cam_frustum) { + // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. + projection[2].y = -projection[2].y; + } + + sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, &projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, p_render_data->scene_data->taa_jitter, this); } sky_energy_multiplier *= bg_energy_multiplier; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 532b5b6484..00a70e3690 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -374,6 +374,10 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT; specialization_constants.push_back(sc); + sc.constant_id = 1; + sc.int_value = p_pipeline_key.shader_specialization.packed_1; + specialization_constants.push_back(sc); + RID shader_rid = get_shader_variant(p_pipeline_key.version, p_pipeline_key.color_pass_flags, p_pipeline_key.ubershader); ERR_FAIL_COND(shader_rid.is_null()); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 8d79539b3d..e1ed85779e 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -117,7 +117,17 @@ public: uint32_t packed_0; }; - uint32_t packed_1; + union { + struct { + uint32_t multimesh : 1; + uint32_t multimesh_format_2d : 1; + uint32_t multimesh_has_color : 1; + uint32_t multimesh_has_custom_data : 1; + }; + + uint32_t packed_1; + }; + uint32_t packed_2; }; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 978ce097d3..5ad92bd211 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -911,14 +911,19 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color Color clear_color = p_default_bg_color; bool load_color = false; bool copy_canvas = false; + bool use_ambient_cubemap = false; + bool use_reflection_cubemap = false; if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black } else if (is_environment(p_render_data->environment)) { + RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_render_data->environment); RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment); float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment); bg_energy_multiplier *= environment_get_bg_intensity(p_render_data->environment); RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(p_render_data->environment); + use_ambient_cubemap = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY; + use_reflection_cubemap = (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY; if (p_render_data->camera_attributes.is_valid()) { bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); @@ -963,7 +968,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color } // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); @@ -976,7 +981,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, Vector2(0.0f, 0.0f), this); } else { - sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, screen_size, p_render_data->scene_data->taa_jitter, this); + Projection projection = p_render_data->scene_data->cam_projection; + if (p_render_data->scene_data->cam_frustum) { + // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. + projection[2].y = -projection[2].y; + } + + sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, &projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, p_render_data->scene_data->taa_jitter, this); } sky_energy_multiplier *= bg_energy_multiplier; @@ -1008,13 +1019,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color SceneShaderForwardMobile::ShaderSpecialization base_specialization = scene_shader.default_specialization; { - //figure out spec constants - - if (p_render_data->directional_light_count > 0) { - base_specialization.use_directional_soft_shadows = p_render_data->directional_light_soft_shadows; - } else { - base_specialization.disable_directional_lights = true; - } + base_specialization.use_directional_soft_shadows = p_render_data->directional_light_count > 0 ? p_render_data->directional_light_soft_shadows : false; + base_specialization.directional_lights = p_render_data->directional_light_count; if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment)) { base_specialization.disable_fog = true; @@ -1023,6 +1029,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (p_render_data->environment.is_valid() && environment_get_fog_mode(p_render_data->environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH) { base_specialization.use_depth_fog = true; } + + base_specialization.scene_use_ambient_cubemap = use_ambient_cubemap; + base_specialization.scene_use_reflection_cubemap = use_reflection_cubemap; + base_specialization.scene_roughness_limiter_enabled = p_render_data->render_buffers.is_valid() && screen_space_roughness_limiter_is_active(); } { @@ -2144,7 +2154,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr } SceneShaderForwardMobile::ShaderSpecialization pipeline_specialization = p_params->base_specialization; - pipeline_specialization.is_multimesh = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH); + pipeline_specialization.multimesh = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH); + pipeline_specialization.multimesh_format_2d = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D); + pipeline_specialization.multimesh_has_color = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR); + pipeline_specialization.multimesh_has_custom_data = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA); SceneState::PushConstant push_constant; push_constant.base_index = i + p_params->element_offset; @@ -2165,10 +2178,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr } else { pipeline_specialization.use_light_projector = inst->use_projector; pipeline_specialization.use_light_soft_shadows = inst->use_soft_shadow; - pipeline_specialization.disable_omni_lights = inst->omni_light_count == 0; - pipeline_specialization.disable_spot_lights = inst->spot_light_count == 0; - pipeline_specialization.disable_reflection_probes = inst->reflection_probe_count == 0; - pipeline_specialization.disable_decals = inst->decals_count == 0; + pipeline_specialization.omni_lights = inst->omni_light_count; + pipeline_specialization.spot_lights = inst->spot_light_count; + pipeline_specialization.reflection_probes = inst->reflection_probe_count; + pipeline_specialization.decals = inst->decals_count; #ifdef DEBUG_ENABLED if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) { diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 6323d7dd6a..4525b50b6e 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -237,6 +237,7 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli "VERSION:", p_pipeline_key.version, "SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0, "SPEC PACKED #1:", p_pipeline_key.shader_specialization.packed_1, + "SPEC PACKED #2:", p_pipeline_key.shader_specialization.packed_2, "RENDER PASS:", p_pipeline_key.render_pass, "WIREFRAME:", p_pipeline_key.wireframe); #endif diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index a27da6c72d..f0afeebe79 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -65,25 +65,35 @@ public: uint32_t use_directional_soft_shadows : 1; uint32_t decal_use_mipmaps : 1; uint32_t projector_use_mipmaps : 1; - uint32_t disable_omni_lights : 1; - uint32_t disable_spot_lights : 1; - uint32_t disable_reflection_probes : 1; - uint32_t disable_directional_lights : 1; - uint32_t disable_decals : 1; uint32_t disable_fog : 1; uint32_t use_depth_fog : 1; - uint32_t is_multimesh : 1; uint32_t use_lightmap_bicubic_filter : 1; + uint32_t multimesh : 1; + uint32_t multimesh_format_2d : 1; + uint32_t multimesh_has_color : 1; + uint32_t multimesh_has_custom_data : 1; + uint32_t scene_use_ambient_cubemap : 1; + uint32_t scene_use_reflection_cubemap : 1; + uint32_t scene_roughness_limiter_enabled : 1; + uint32_t padding : 5; uint32_t soft_shadow_samples : 6; uint32_t penumbra_shadow_samples : 6; - uint32_t directional_soft_shadow_samples : 6; }; uint32_t packed_0; }; union { - uint32_t directional_penumbra_shadow_samples : 6; + struct { + uint32_t directional_soft_shadow_samples : 6; + uint32_t directional_penumbra_shadow_samples : 6; + uint32_t omni_lights : 4; + uint32_t spot_lights : 4; + uint32_t reflection_probes : 4; + uint32_t directional_lights : 4; + uint32_t decals : 4; + }; + uint32_t packed_1; }; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index c4a732fef1..0dcdb90948 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -993,36 +993,43 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, Vector<Color> cc; cc.push_back(Color(p_far, p_far, p_far, 1.0)); - for (int i = 0; i < 4; i++) { - //make sure it remains orthogonal, makes easy to read angle later + Projection projection; + { + real_t fov = 90; + real_t nearp = p_near; + real_t farp = p_far; + real_t aspect = 1.0; - //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); + real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5)); + real_t ymin = -ymax; + real_t xmin = ymin * aspect; + real_t xmax = ymax * aspect; - Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); + projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); + } - Projection projection; - { - real_t fov = 90; - real_t nearp = p_near; - real_t farp = p_far; - real_t aspect = 1.0; + // Precomputed: + // Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); + // projection = projection * Projection(Transform3D().looking_at(cam_targets[i], Vector3(0, 0, -1)).affine_inverse()); + const Projection projections[4] = { + projection * Projection(Vector4(0, 0, -1, 0), Vector4(1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)), - real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5)); - real_t ymin = -ymax; - real_t xmin = ymin * aspect; - real_t xmax = ymax * aspect; + projection * Projection(Vector4(-1, 0, 0, 0), Vector4(0, 0, -1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)), - projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); - } + projection * Projection(Vector4(0, 0, 1, 0), Vector4(-1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)), + + projection * Projection(Vector4(1, 0, 0, 0), Vector4(0, 0, 1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)) + + }; - Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); - projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); + for (int i = 0; i < 4; i++) { + Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { - push_constant.projection[y * 4 + x] = projection.columns[y][x]; + push_constant.projection[y * 4 + x] = projections[i].columns[y][x]; } } static const Vector2 directions[4] = { Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0), Vector2(0, -1) }; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index d04285fbb4..ba47508700 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -67,7 +67,7 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_target_descriptors[rd_texture], 0); // We need to invert the phone rotation. - int screen_rotation_degrees = -DisplayServer::get_singleton()->screen_get_internal_current_rotation(); + const int screen_rotation_degrees = -RD::get_singleton()->screen_get_pre_rotation_degrees(p_screen); float screen_rotation = Math::deg_to_rad((float)screen_rotation_degrees); blit.push_constant.rotation_cos = Math::cos(screen_rotation); @@ -238,7 +238,7 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uset, 0); - int screen_rotation_degrees = DisplayServer::get_singleton()->screen_get_internal_current_rotation(); + const int screen_rotation_degrees = -RD::get_singleton()->screen_get_pre_rotation_degrees(DisplayServer::MAIN_WINDOW_ID); float screen_rotation = Math::deg_to_rad((float)screen_rotation_degrees); blit.push_constant.rotation_cos = Math::cos(screen_rotation); blit.push_constant.rotation_sin = Math::sin(screen_rotation); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index dc2605b670..4417f6832c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1130,6 +1130,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render scene_data.cam_transform = p_camera_data->main_transform; scene_data.cam_projection = p_camera_data->main_projection; scene_data.cam_orthogonal = p_camera_data->is_orthogonal; + scene_data.cam_frustum = p_camera_data->is_frustum; scene_data.camera_visible_layers = p_camera_data->visible_layers; scene_data.taa_jitter = p_camera_data->taa_jitter; scene_data.taa_frame_count = p_camera_data->taa_frame_count; diff --git a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl index 3fb93dda35..b45e310b61 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl @@ -8,7 +8,6 @@ layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; - vec4 screen_rect; } params; @@ -17,8 +16,7 @@ layout(location = 0) out vec2 uv_interp; void main() { vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; - vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy; - gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0); + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); } #[fragment] @@ -35,7 +33,6 @@ layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; - vec4 screen_rect; } params; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 72236dcd9f..81d3d87a22 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -211,6 +211,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec } #endif +uint multimesh_stride() { + uint stride = sc_multimesh_format_2d() ? 2 : 3; + stride += sc_multimesh_has_color() ? 1 : 0; + stride += sc_multimesh_has_custom_data() ? 1 : 0; + return stride; +} + void vertex_shader(vec3 vertex_input, #ifdef NORMAL_USED in vec3 normal_input, @@ -219,7 +226,7 @@ void vertex_shader(vec3 vertex_input, in vec3 tangent_input, in vec3 binormal_input, #endif - in uint instance_index, in bool is_multimesh, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { + in uint instance_index, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; @@ -248,7 +255,7 @@ void vertex_shader(vec3 vertex_input, mat4 matrix; mat4 read_model_matrix = model_matrix; - if (is_multimesh) { + if (sc_multimesh()) { //multimesh, instances are for it #ifdef USE_PARTICLE_TRAILS @@ -296,25 +303,10 @@ void vertex_shader(vec3 vertex_input, #endif #else - uint stride = 0; - { - //TODO implement a small lookup table for the stride - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { - stride += 2; - } else { - stride += 3; - } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { - stride += 1; - } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { - stride += 1; - } - } - + uint stride = multimesh_stride(); uint offset = stride * (gl_InstanceIndex + multimesh_offset); - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { + if (sc_multimesh_format_2d()) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); offset += 2; } else { @@ -322,14 +314,14 @@ void vertex_shader(vec3 vertex_input, offset += 3; } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { + if (sc_multimesh_has_color()) { #ifdef COLOR_USED color_interp *= transforms.data[offset]; #endif offset += 1; } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { + if (sc_multimesh_has_custom_data()) { instance_custom = transforms.data[offset]; } @@ -427,7 +419,7 @@ void vertex_shader(vec3 vertex_input, // Then we combine the translations from the model matrix and the view matrix using emulated doubles. // We add the result to the vertex and ignore the final lost precision. vec3 model_origin = model_matrix[3].xyz; - if (is_multimesh) { + if (sc_multimesh()) { vertex = mat3(matrix) * vertex; model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision); } @@ -708,9 +700,7 @@ void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position void main() { uint instance_index = draw_call.instance_index; - - bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH); - if (!is_multimesh) { + if (!sc_multimesh()) { instance_index += gl_InstanceIndex; } @@ -753,7 +743,7 @@ void main() { prev_tangent, prev_binormal, #endif - instance_index, is_multimesh, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); + instance_index, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); #else // Unused output. vec4 screen_position; @@ -792,7 +782,7 @@ void main() { tangent, binormal, #endif - instance_index, is_multimesh, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position); + instance_index, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position); } #[fragment] diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index 7bfcb2fb12..8f153f7ed5 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -59,6 +59,10 @@ uint sc_packed_0() { return draw_call.sc_packed_0; } +uint sc_packed_1() { + return draw_call.sc_packed_1; +} + uint uc_cull_mode() { return (draw_call.uc_packed_0 >> 0) & 3U; } @@ -67,11 +71,16 @@ uint uc_cull_mode() { // Pull the constants from the pipeline's specialization constants. layout(constant_id = 0) const uint pso_sc_packed_0 = 0; +layout(constant_id = 1) const uint pso_sc_packed_1 = 0; uint sc_packed_0() { return pso_sc_packed_0; } +uint sc_packed_1() { + return pso_sc_packed_1; +} + #endif bool sc_use_forward_gi() { @@ -122,6 +131,22 @@ uint sc_directional_penumbra_shadow_samples() { return (sc_packed_0() >> 26) & 63U; } +bool sc_multimesh() { + return ((sc_packed_1() >> 0) & 1U) != 0; +} + +bool sc_multimesh_format_2d() { + return ((sc_packed_1() >> 1) & 1U) != 0; +} + +bool sc_multimesh_has_color() { + return ((sc_packed_1() >> 2) & 1U) != 0; +} + +bool sc_multimesh_has_custom_data() { + return ((sc_packed_1() >> 3) & 1U) != 0; +} + float sc_luminance_multiplier() { // Not used in clustered renderer but we share some code with the mobile renderer that requires this. return 1.0; @@ -144,10 +169,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; #define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9) #define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10) #define INSTANCE_FLAGS_PARTICLES (1 << 11) -#define INSTANCE_FLAGS_MULTIMESH (1 << 12) -#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) -#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) -#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15) #define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16 #define INSTANCE_FLAGS_FADE_SHIFT 24 //3 bits of stride diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 2f0e4e0bea..404f658fa6 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -178,6 +178,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec } #endif +uint multimesh_stride() { + uint stride = sc_multimesh_format_2d() ? 2 : 3; + stride += sc_multimesh_has_color() ? 1 : 0; + stride += sc_multimesh_has_custom_data() ? 1 : 0; + return stride; +} + void main() { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) @@ -208,7 +215,7 @@ void main() { mat4 matrix; mat4 read_model_matrix = model_matrix; - if (sc_is_multimesh()) { + if (sc_multimesh()) { //multimesh, instances are for it #ifdef USE_PARTICLE_TRAILS @@ -256,25 +263,10 @@ void main() { #endif #else - uint stride = 0; - { - //TODO implement a small lookup table for the stride - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { - stride += 2; - } else { - stride += 3; - } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { - stride += 1; - } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { - stride += 1; - } - } - + uint stride = multimesh_stride(); uint offset = stride * gl_InstanceIndex; - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { + if (sc_multimesh_format_2d()) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); offset += 2; } else { @@ -282,14 +274,14 @@ void main() { offset += 3; } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { + if (sc_multimesh_has_color()) { #ifdef COLOR_USED color_interp *= transforms.data[offset]; #endif offset += 1; } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { + if (sc_multimesh_has_custom_data()) { instance_custom = transforms.data[offset]; } @@ -404,7 +396,7 @@ void main() { // Then we combine the translations from the model matrix and the view matrix using emulated doubles. // We add the result to the vertex and ignore the final lost precision. vec3 model_origin = model_matrix[3].xyz; - if (sc_is_multimesh()) { + if (sc_multimesh()) { vertex = mat3(matrix) * vertex; model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision); } @@ -461,50 +453,24 @@ void main() { diffuse_light_interp = vec4(0.0); specular_light_interp = vec4(0.0); - if (!sc_disable_omni_lights()) { - uint light_indices = instances.data[draw_call.instance_index].omni_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].omni_lights.y; - } else { - light_indices = light_indices >> 8; - } - - if (light_index == 0xFF) { - break; - } - - light_process_omni_vertex(light_index, vertex, view, normal, roughness, - diffuse_light_interp.rgb, specular_light_interp.rgb); - } + uvec2 omni_light_indices = instances.data[draw_call.instance_index].omni_lights; + for (uint i = 0; i < sc_omni_lights(); i++) { + uint light_index = (i > 3) ? ((omni_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_light_indices.x >> (i * 8)) & 0xFF); + light_process_omni_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb); } - if (!sc_disable_spot_lights()) { - uint light_indices = instances.data[draw_call.instance_index].spot_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].spot_lights.y; - } else { - light_indices = light_indices >> 8; - } - - if (light_index == 0xFF) { - break; - } - - light_process_spot_vertex(light_index, vertex, view, normal, roughness, - diffuse_light_interp.rgb, specular_light_interp.rgb); - } + uvec2 spot_light_indices = instances.data[draw_call.instance_index].spot_lights; + for (uint i = 0; i < sc_spot_lights(); i++) { + uint light_index = (i > 3) ? ((spot_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_light_indices.x >> (i * 8)) & 0xFF); + light_process_spot_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb); } - if (!sc_disable_directional_lights()) { + if (sc_directional_lights() > 0) { // We process the first directional light separately as it may have shadows. vec3 directional_diffuse = vec3(0.0); vec3 directional_specular = vec3(0.0); - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { continue; // Not masked, skip. } @@ -823,7 +789,7 @@ vec4 fog_process(vec3 vertex) { float sun_total = 0.0; vec3 view = normalize(vertex); - for (uint i = 0; i < scene_data_block.data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy; float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0); fog_color += light_color * light_amount * scene_data_block.data.fog_sun_scatter; @@ -1110,97 +1076,83 @@ void main() { vec3 vertex_ddx = dFdx(vertex); vec3 vertex_ddy = dFdy(vertex); - if (!sc_disable_decals()) { //Decals - // must implement - - uint decal_indices = instances.data[draw_call.instance_index].decals.x; - for (uint i = 0; i < 8; i++) { - uint decal_index = decal_indices & 0xFF; - if (i == 3) { - decal_indices = instances.data[draw_call.instance_index].decals.y; - } else { - decal_indices = decal_indices >> 8; - } + uvec2 decal_indices = instances.data[draw_call.instance_index].decals; + for (uint i = 0; i < sc_decals(); i++) { + uint decal_index = (i > 3) ? ((decal_indices.y >> ((i - 4) * 8)) & 0xFF) : ((decal_indices.x >> (i * 8)) & 0xFF); + if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) { + continue; //not masked + } - if (decal_index == 0xFF) { - break; - } + vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; + if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { + continue; //out of decal + } - if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) { - continue; //not masked - } + float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); - vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; - if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { - continue; //out of decal - } + if (decals.data[decal_index].normal_fade > 0.0) { + fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); + } - float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); + //we need ddx/ddy for mipmaps, so simulate them + vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; + vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; - if (decals.data[decal_index].normal_fade > 0.0) { - fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); + if (decals.data[decal_index].albedo_rect != vec4(0.0)) { + //has albedo + vec4 decal_albedo; + if (sc_decal_use_mipmaps()) { + decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); + } else { + decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0); } + decal_albedo *= decals.data[decal_index].modulate; + decal_albedo.a *= fade; + albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); - //we need ddx/ddy for mipmaps, so simulate them - vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; - vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; - - if (decals.data[decal_index].albedo_rect != vec4(0.0)) { - //has albedo - vec4 decal_albedo; + if (decals.data[decal_index].normal_rect != vec4(0.0)) { + vec3 decal_normal; if (sc_decal_use_mipmaps()) { - decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); + decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; } else { - decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0); - } - decal_albedo *= decals.data[decal_index].modulate; - decal_albedo.a *= fade; - albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); - - if (decals.data[decal_index].normal_rect != vec4(0.0)) { - vec3 decal_normal; - if (sc_decal_use_mipmaps()) { - decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; - } else { - decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz; - } - decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software - decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); - //convert to view space, use xzy because y is up - decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; - - normal = normalize(mix(normal, decal_normal, decal_albedo.a)); + decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz; } + decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software + decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); + //convert to view space, use xzy because y is up + decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; - if (decals.data[decal_index].orm_rect != vec4(0.0)) { - vec3 decal_orm; - if (sc_decal_use_mipmaps()) { - decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; - } else { - decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz; - } - ao = mix(ao, decal_orm.r, decal_albedo.a); - roughness = mix(roughness, decal_orm.g, decal_albedo.a); - metallic = mix(metallic, decal_orm.b, decal_albedo.a); - } + normal = normalize(mix(normal, decal_normal, decal_albedo.a)); } - if (decals.data[decal_index].emission_rect != vec4(0.0)) { - //emission is additive, so its independent from albedo + if (decals.data[decal_index].orm_rect != vec4(0.0)) { + vec3 decal_orm; if (sc_decal_use_mipmaps()) { - emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; } else { - emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade; + decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz; } + ao = mix(ao, decal_orm.r, decal_albedo.a); + roughness = mix(roughness, decal_orm.g, decal_albedo.a); + metallic = mix(metallic, decal_orm.b, decal_albedo.a); + } + } + + if (decals.data[decal_index].emission_rect != vec4(0.0)) { + //emission is additive, so its independent from albedo + if (sc_decal_use_mipmaps()) { + emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + } else { + emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade; } } - } //Decals + } #endif //!MODE_RENDER_DEPTH /////////////////////// LIGHTING ////////////////////////////// #ifdef NORMAL_USED - if (scene_data.roughness_limiter_enabled) { + if (sc_scene_roughness_limiter_enabled()) { //https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf float roughness2 = roughness * roughness; vec3 dndu = dFdx(normal), dndv = dFdy(normal); @@ -1225,7 +1177,7 @@ void main() { #ifndef AMBIENT_LIGHT_DISABLED - if (scene_data.use_reflection_cubemap) { + if (sc_scene_use_reflection_cubemap()) { #ifdef LIGHT_ANISOTROPY_USED // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; @@ -1266,7 +1218,7 @@ void main() { if (scene_data.use_ambient_light) { ambient_light = scene_data.ambient_light_color_energy.rgb; - if (scene_data.use_ambient_cubemap) { + if (sc_scene_use_ambient_cubemap()) { vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; #ifdef USE_RADIANCE_CUBEMAP_ARRAY vec3 cubemap_ambient = texture(samplerCubeArray(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(ambient_dir, MAX_ROUGHNESS_LOD)).rgb; @@ -1285,7 +1237,7 @@ void main() { #endif // CUSTOM_IRRADIANCE_USED #ifdef LIGHT_CLEARCOAT_USED - if (scene_data.use_reflection_cubemap) { + if (sc_scene_use_reflection_cubemap()) { vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map float NoV = max(dot(n, view), 0.0001); vec3 ref_vec = reflect(-view, n); @@ -1393,12 +1345,10 @@ void main() { // skipping ssao, do we remove ssao totally? - if (!sc_disable_reflection_probes()) { //Reflection probes + if (sc_reflection_probes() > 0) { vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); - uint reflection_indices = instances.data[draw_call.instance_index].reflection_probes.x; - #ifdef LIGHT_ANISOTROPY_USED // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; @@ -1411,18 +1361,9 @@ void main() { vec3 ref_vec = normalize(reflect(-view, bent_normal)); ref_vec = mix(ref_vec, bent_normal, roughness * roughness); - for (uint i = 0; i < 8; i++) { - uint reflection_index = reflection_indices & 0xFF; - if (i == 3) { - reflection_indices = instances.data[draw_call.instance_index].reflection_probes.y; - } else { - reflection_indices = reflection_indices >> 8; - } - - if (reflection_index == 0xFF) { - break; - } - + uvec2 reflection_indices = instances.data[draw_call.instance_index].reflection_probes; + for (uint i = 0; i < sc_reflection_probes(); i++) { + uint reflection_index = (i > 3) ? ((reflection_indices.y >> ((i - 4) * 8)) & 0xFF) : ((reflection_indices.x >> (i * 8)) & 0xFF); reflection_process(reflection_index, vertex, ref_vec, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } @@ -1487,7 +1428,7 @@ void main() { specular_light += specular_light_interp.rgb * f0; #endif - if (!sc_disable_directional_lights()) { //directional light + if (sc_directional_lights() > 0) { #ifndef SHADOWS_DISABLED // Do shadow and lighting in two passes to reduce register pressure uint shadow0 = 0; @@ -1497,7 +1438,7 @@ void main() { // Only process the first light's shadow for vertex lighting. for (uint i = 0; i < 1; i++) { #else - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { #endif if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { @@ -1612,7 +1553,7 @@ void main() { #endif // SHADOWS_DISABLED #ifndef USE_VERTEX_LIGHTING - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { continue; //not masked } @@ -1678,95 +1619,72 @@ void main() { } //directional light #ifndef USE_VERTEX_LIGHTING - if (!sc_disable_omni_lights()) { //omni lights - uint light_indices = instances.data[draw_call.instance_index].omni_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].omni_lights.y; - } else { - light_indices = light_indices >> 8; - } - - if (light_index == 0xFF) { - break; - } + uvec2 omni_indices = instances.data[draw_call.instance_index].omni_lights; + for (uint i = 0; i < sc_omni_lights(); i++) { + uint light_index = (i > 3) ? ((omni_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_indices.x >> (i * 8)) & 0xFF); - float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count); + float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count); - shadow = blur_shadow(shadow); + shadow = blur_shadow(shadow); - // Fragment lighting - light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, + // Fragment lighting + light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif /* #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_boost, #endif */ #ifdef LIGHT_RIM_USED - rim, - rim_tint, + rim, + rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_roughness, normalize(normal_interp), + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, - binormal, anisotropy, + tangent, + binormal, anisotropy, #endif - diffuse_light, specular_light); - } - } //omni lights - - if (!sc_disable_spot_lights()) { //spot lights - - uint light_indices = instances.data[draw_call.instance_index].spot_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].spot_lights.y; - } else { - light_indices = light_indices >> 8; - } + diffuse_light, specular_light); + } - if (light_index == 0xFF) { - break; - } + uvec2 spot_indices = instances.data[draw_call.instance_index].spot_lights; + for (uint i = 0; i < sc_spot_lights(); i++) { + uint light_index = (i > 3) ? ((spot_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_indices.x >> (i * 8)) & 0xFF); - float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count); + float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count); - shadow = blur_shadow(shadow); + shadow = blur_shadow(shadow); - light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, + light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif /* #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_boost, #endif */ #ifdef LIGHT_RIM_USED - rim, - rim_tint, + rim, + rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_roughness, normalize(normal_interp), + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, - binormal, anisotropy, + tangent, + binormal, anisotropy, #endif - diffuse_light, specular_light); - } - } //spot lights + diffuse_light, specular_light); + } #endif // !VERTEX_LIGHTING #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index df528973da..2cc86482f6 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -95,56 +95,80 @@ bool sc_projector_use_mipmaps() { return ((sc_packed_0() >> 4) & 1U) != 0; } -bool sc_disable_omni_lights() { +bool sc_disable_fog() { return ((sc_packed_0() >> 5) & 1U) != 0; } -bool sc_disable_spot_lights() { +bool sc_use_depth_fog() { return ((sc_packed_0() >> 6) & 1U) != 0; } -bool sc_disable_reflection_probes() { +bool sc_use_lightmap_bicubic_filter() { return ((sc_packed_0() >> 7) & 1U) != 0; } -bool sc_disable_directional_lights() { +bool sc_multimesh() { return ((sc_packed_0() >> 8) & 1U) != 0; } -bool sc_disable_decals() { +bool sc_multimesh_format_2d() { return ((sc_packed_0() >> 9) & 1U) != 0; } -bool sc_disable_fog() { +bool sc_multimesh_has_color() { return ((sc_packed_0() >> 10) & 1U) != 0; } -bool sc_use_depth_fog() { +bool sc_multimesh_has_custom_data() { return ((sc_packed_0() >> 11) & 1U) != 0; } -bool sc_is_multimesh() { +bool sc_scene_use_ambient_cubemap() { return ((sc_packed_0() >> 12) & 1U) != 0; } -bool sc_use_lightmap_bicubic_filter() { +bool sc_scene_use_reflection_cubemap() { return ((sc_packed_0() >> 13) & 1U) != 0; } +bool sc_scene_roughness_limiter_enabled() { + return ((sc_packed_0() >> 14) & 1U) != 0; +} + uint sc_soft_shadow_samples() { - return (sc_packed_0() >> 14) & 63U; + return (sc_packed_0() >> 20) & 63U; } uint sc_penumbra_shadow_samples() { - return (sc_packed_0() >> 20) & 63U; + return (sc_packed_0() >> 26) & 63U; } uint sc_directional_soft_shadow_samples() { - return (sc_packed_0() >> 26) & 63U; + return (sc_packed_1() >> 0) & 63U; } uint sc_directional_penumbra_shadow_samples() { - return (sc_packed_1() >> 0) & 63U; + return (sc_packed_1() >> 6) & 63U; +} + +uint sc_omni_lights() { + return (sc_packed_1() >> 12) & 15U; +} + +uint sc_spot_lights() { + return (sc_packed_1() >> 16) & 15U; +} + +uint sc_reflection_probes() { + return (sc_packed_1() >> 20) & 15U; +} + +uint sc_directional_lights() { + return (sc_packed_1() >> 24) & 15U; +} + +uint sc_decals() { + return (sc_packed_1() >> 28) & 15U; } float sc_luminance_multiplier() { @@ -166,10 +190,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; #define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9) #define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10) #define INSTANCE_FLAGS_PARTICLES (1 << 11) -#define INSTANCE_FLAGS_MULTIMESH (1 << 12) -#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) -#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) -#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15) #define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16 //3 bits of stride #define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 314cbf9aa9..6efb8c176f 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -306,9 +306,14 @@ void ParticlesStorage::_particles_free_data(Particles *particles) { particles->emission_storage_buffer = RID(); } - if (particles->unused_storage_buffer.is_valid()) { - RD::get_singleton()->free(particles->unused_storage_buffer); - particles->unused_storage_buffer = RID(); + if (particles->unused_emission_storage_buffer.is_valid()) { + RD::get_singleton()->free(particles->unused_emission_storage_buffer); + particles->unused_emission_storage_buffer = RID(); + } + + if (particles->unused_trail_storage_buffer.is_valid()) { + RD::get_singleton()->free(particles->unused_trail_storage_buffer); + particles->unused_trail_storage_buffer = RID(); } if (RD::get_singleton()->uniform_set_is_valid(particles->particles_material_uniform_set)) { @@ -534,9 +539,15 @@ void ParticlesStorage::_particles_allocate_emission_buffer(Particles *particles) } } -void ParticlesStorage::_particles_ensure_unused_buffer(Particles *particles) { - if (particles->unused_storage_buffer.is_null()) { - particles->unused_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4); +void ParticlesStorage::_particles_ensure_unused_emission_buffer(Particles *particles) { + if (particles->unused_emission_storage_buffer.is_null()) { + particles->unused_emission_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4); + } +} + +void ParticlesStorage::_particles_ensure_unused_trail_buffer(Particles *particles) { + if (particles->unused_trail_storage_buffer.is_null()) { + particles->unused_trail_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4); } } @@ -763,8 +774,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta if (p_particles->emission_storage_buffer.is_valid()) { u.append_id(p_particles->emission_storage_buffer); } else { - _particles_ensure_unused_buffer(p_particles); - u.append_id(p_particles->unused_storage_buffer); + _particles_ensure_unused_emission_buffer(p_particles); + u.append_id(p_particles->unused_emission_storage_buffer); } uniforms.push_back(u); } @@ -779,8 +790,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta } u.append_id(sub_emitter->emission_storage_buffer); } else { - _particles_ensure_unused_buffer(p_particles); - u.append_id(p_particles->unused_storage_buffer); + _particles_ensure_unused_emission_buffer(p_particles); + u.append_id(p_particles->unused_emission_storage_buffer); } uniforms.push_back(u); } @@ -1481,8 +1492,8 @@ void ParticlesStorage::update_particles() { if (particles->trail_bind_pose_buffer.is_valid()) { u.append_id(particles->trail_bind_pose_buffer); } else { - _particles_ensure_unused_buffer(particles); - u.append_id(particles->unused_storage_buffer); + _particles_ensure_unused_trail_buffer(particles); + u.append_id(particles->unused_trail_storage_buffer); } uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 33f44f3045..ec897c4ea9 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -247,7 +247,8 @@ private: ParticleEmissionBuffer *emission_buffer = nullptr; RID emission_storage_buffer; - RID unused_storage_buffer; + RID unused_emission_storage_buffer; + RID unused_trail_storage_buffer; HashSet<RID> collisions; @@ -265,7 +266,8 @@ private: void _particles_process(Particles *p_particles, double p_delta); void _particles_allocate_emission_buffer(Particles *particles); - void _particles_ensure_unused_buffer(Particles *particles); + void _particles_ensure_unused_emission_buffer(Particles *particles); + void _particles_ensure_unused_trail_buffer(Particles *particles); void _particles_free_data(Particles *particles); void _particles_update_buffers(Particles *particles); @@ -509,7 +511,7 @@ public: _FORCE_INLINE_ bool particles_has_collision(RID p_particles) { Particles *particles = particles_owner.get_or_null(p_particles); - ERR_FAIL_NULL_V(particles, 0); + ERR_FAIL_NULL_V(particles, false); return particles->has_collision_cache; } diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h index 4a70482d72..59671c3a13 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h @@ -51,6 +51,7 @@ public: float taa_frame_count = 0.0f; uint32_t camera_visible_layers; bool cam_orthogonal = false; + bool cam_frustum = false; bool flip_y = false; // For billboards to cast correct shadows. diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index b9acd0d758..3d281cf98a 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -102,9 +102,9 @@ private: /* Canvas Texture API */ struct CanvasTextureCache { - RID diffuse = RID(); - RID normal = RID(); - RID specular = RID(); + RID diffuse; + RID normal; + RID specular; }; class CanvasTexture { diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 45f980ab41..11ca7de44f 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2738,6 +2738,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu Projection projection; bool vaspect = camera->vaspect; bool is_orthogonal = false; + bool is_frustum = false; switch (camera->type) { case Camera::ORTHOGONAL: { @@ -2766,10 +2767,11 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu camera->znear, camera->zfar, camera->vaspect); + is_frustum = true; } break; } - camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, taa_frame_count, camera->visible_layers); + camera_data.set_camera(transform, projection, is_orthogonal, is_frustum, vaspect, jitter, taa_frame_count, camera->visible_layers); } else { // Setup our camera for our XR interface. // We can support multiple views here each with their own camera @@ -2791,9 +2793,9 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu } if (view_count == 1) { - camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers); + camera_data.set_camera(transforms[0], projections[0], false, false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers); } else if (view_count == 2) { - camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect); + camera_data.set_multiview_camera(view_count, transforms, projections, false, false, camera->vaspect); } else { // this won't be called (see fail check above) but keeping this comment to indicate we may support more then 2 views in the future... } @@ -3641,7 +3643,7 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend RENDER_TIMESTAMP("Render Empty 3D Scene"); RendererSceneRender::CameraData camera_data; - camera_data.set_camera(Transform3D(), Projection(), true, false); + camera_data.set_camera(Transform3D(), Projection(), true, false, false); scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), compositor, p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif @@ -3719,7 +3721,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int RENDER_TIMESTAMP("Render ReflectionProbe, Step " + itos(p_step)); RendererSceneRender::CameraData camera_data; - camera_data.set_camera(xform, cm, false, false); + camera_data.set_camera(xform, cm, false, false, false); Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas); _render_scene(&camera_data, render_buffers, environment, RID(), RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows); diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index d3f03c4789..82523fd4ef 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -1256,6 +1256,7 @@ public: PASS3(environment_set_bg_energy, RID, float, float) PASS2(environment_set_canvas_max_layer, RID, int) PASS6(environment_set_ambient_light, RID, const Color &, RS::EnvironmentAmbientSource, float, float, RS::EnvironmentReflectionSource) + PASS2(environment_set_camera_feed_id, RID, int) PASS1RC(RS::EnvironmentBG, environment_get_background, RID) PASS1RC(RID, environment_get_sky, RID) diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index 797ba7eaf7..07259f73d2 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -33,9 +33,10 @@ ///////////////////////////////////////////////////////////////////////////// // CameraData -void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, const uint32_t p_visible_layers) { +void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, const uint32_t p_visible_layers) { view_count = 1; is_orthogonal = p_is_orthogonal; + is_frustum = p_is_frustum; vaspect = p_vaspect; main_transform = p_transform; @@ -48,12 +49,13 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, taa_frame_count = p_taa_frame_count; } -void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) { +void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect) { ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view"); visible_layers = 0xFFFFFFFF; view_count = p_view_count; is_orthogonal = p_is_orthogonal; + is_frustum = p_is_frustum; vaspect = p_vaspect; Vector<Plane> planes[2]; @@ -349,6 +351,14 @@ RS::EnvironmentReflectionSource RendererSceneRender::environment_get_reflection_ return environment_storage.environment_get_reflection_source(p_env); } +void RendererSceneRender::environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) { + environment_storage.environment_set_camera_feed_id(p_env, p_camera_feed_id); +} + +int RendererSceneRender::environment_get_camera_feed_id(RID p_env) const { + return environment_storage.environment_get_camera_feed_id(p_env); +} + // Tonemap void RendererSceneRender::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) { diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 4d81a9b6a3..99418e0411 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -118,10 +118,7 @@ public: void environment_set_bg_energy(RID p_env, float p_multiplier, float p_exposure_value); void environment_set_canvas_max_layer(RID p_env, int p_max_layer); void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG); -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); -#endif RS::EnvironmentBG environment_get_background(RID p_env) const; RID environment_get_sky(RID p_env) const; @@ -136,6 +133,7 @@ public: float environment_get_ambient_light_energy(RID p_env) const; float environment_get_ambient_sky_contribution(RID p_env) const; RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; + int environment_get_camera_feed_id(RID p_env) const; // Tonemap void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white); @@ -302,6 +300,7 @@ public: // flags uint32_t view_count; bool is_orthogonal; + bool is_frustum; uint32_t visible_layers; bool vaspect; @@ -314,8 +313,8 @@ public: Vector2 taa_jitter; float taa_frame_count = 0.0f; - void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), float p_taa_frame_count = 0.0f, uint32_t p_visible_layers = 0xFFFFFFFF); - void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); + void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), float p_taa_frame_count = 0.0f, uint32_t p_visible_layers = 0xFFFFFFFF); + void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect); }; virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index dc5a178aaa..cc67873b24 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -3757,6 +3757,15 @@ int RenderingDevice::screen_get_height(DisplayServer::WindowID p_screen) const { return context->surface_get_height(surface); } +int RenderingDevice::screen_get_pre_rotation_degrees(DisplayServer::WindowID p_screen) const { + _THREAD_SAFE_METHOD_ + + HashMap<DisplayServer::WindowID, RDD::SwapChainID>::ConstIterator it = screen_swap_chains.find(p_screen); + ERR_FAIL_COND_V_MSG(it == screen_swap_chains.end(), ERR_CANT_CREATE, "A swap chain was not created for the screen."); + + return driver->swap_chain_get_pre_rotation_degrees(it->value); +} + RenderingDevice::FramebufferFormatID RenderingDevice::screen_get_framebuffer_format(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index c7b93f2fc7..9939df976f 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -1083,6 +1083,7 @@ public: Error screen_prepare_for_drawing(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID); int screen_get_width(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const; int screen_get_height(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const; + int screen_get_pre_rotation_degrees(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const; FramebufferFormatID screen_get_framebuffer_format(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const; Error screen_free(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID); diff --git a/servers/rendering/rendering_device_driver.cpp b/servers/rendering/rendering_device_driver.cpp index 9ff7b83215..c1a3f34af8 100644 --- a/servers/rendering/rendering_device_driver.cpp +++ b/servers/rendering/rendering_device_driver.cpp @@ -376,6 +376,8 @@ uint64_t RenderingDeviceDriver::api_trait_get(ApiTrait p_trait) { return true; case API_TRAIT_USE_GENERAL_IN_COPY_QUEUES: return false; + case API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS: + return false; default: ERR_FAIL_V(0); } diff --git a/servers/rendering/rendering_device_driver.h b/servers/rendering/rendering_device_driver.h index 953401e9bd..d2d14676db 100644 --- a/servers/rendering/rendering_device_driver.h +++ b/servers/rendering/rendering_device_driver.h @@ -120,9 +120,9 @@ struct VersatileResourceTemplate { class RenderingDeviceDriver : public RenderingDeviceCommons { public: struct ID { - size_t id = 0; + uint64_t id = 0; _ALWAYS_INLINE_ ID() = default; - _ALWAYS_INLINE_ ID(size_t p_id) : + _ALWAYS_INLINE_ ID(uint64_t p_id) : id(p_id) {} }; @@ -138,11 +138,9 @@ public: _ALWAYS_INLINE_ bool operator!=(const m_name##ID &p_other) const { return id != p_other.id; } \ _ALWAYS_INLINE_ m_name##ID(const m_name##ID &p_other) : ID(p_other.id) {} \ _ALWAYS_INLINE_ explicit m_name##ID(uint64_t p_int) : ID(p_int) {} \ - _ALWAYS_INLINE_ explicit m_name##ID(void *p_ptr) : ID((size_t)p_ptr) {} \ + _ALWAYS_INLINE_ explicit m_name##ID(void *p_ptr) : ID((uint64_t)p_ptr) {} \ _ALWAYS_INLINE_ m_name##ID() = default; \ - }; \ - /* Ensure type-punnable to pointer. Makes some things easier.*/ \ - static_assert(sizeof(m_name##ID) == sizeof(void *)); + }; // Id types declared before anything else to prevent cyclic dependencies between the different concerns. DEFINE_ID(Buffer); @@ -454,6 +452,9 @@ public: // Retrieve the render pass that can be used to draw on the swap chain's framebuffers. virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) = 0; + // Retrieve the rotation in degrees to apply as a pre-transform. Usually 0 on PC. May be 0, 90, 180 & 270 on Android. + virtual int swap_chain_get_pre_rotation_degrees(SwapChainID p_swap_chain) { return 0; } + // Retrieve the format used by the swap chain's framebuffers. virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) = 0; @@ -756,6 +757,7 @@ public: API_TRAIT_SECONDARY_VIEWPORT_SCISSOR, API_TRAIT_CLEARS_WITH_COPY_ENGINE, API_TRAIT_USE_GENERAL_IN_COPY_QUEUES, + API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS, }; enum ShaderChangeInvalidation { diff --git a/servers/rendering/rendering_device_graph.cpp b/servers/rendering/rendering_device_graph.cpp index 750753d796..ec2f336f3c 100644 --- a/servers/rendering/rendering_device_graph.cpp +++ b/servers/rendering/rendering_device_graph.cpp @@ -140,6 +140,25 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage #endif } +bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const { + if (p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE && p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE) { + // We don't check possible intersections for usages that aren't consecutive color or depth writes. + return true; + } + + const uint32_t previous_command_data_offset = command_data_offsets[p_previous_command_index]; + const uint32_t current_command_data_offset = command_data_offsets[p_command_index]; + const RecordedDrawListCommand &previous_draw_list_command = *reinterpret_cast<const RecordedDrawListCommand *>(&command_data[previous_command_data_offset]); + const RecordedDrawListCommand ¤t_draw_list_command = *reinterpret_cast<const RecordedDrawListCommand *>(&command_data[current_command_data_offset]); + if (previous_draw_list_command.type != RecordedCommand::TYPE_DRAW_LIST || current_draw_list_command.type != RecordedCommand::TYPE_DRAW_LIST) { + // We don't check possible intersections if both commands aren't draw lists. + return true; + } + + // We check if the region used by both draw lists have an intersection. + return previous_draw_list_command.region.intersects(current_draw_list_command.region); +} + int32_t RenderingDeviceGraph::_add_to_command_list(int32_t p_command_index, int32_t p_list_index) { DEV_ASSERT(p_command_index < int32_t(command_count)); DEV_ASSERT(p_list_index < int32_t(command_list_nodes.size())); @@ -425,11 +444,9 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr #if USE_BUFFER_BARRIERS _add_buffer_barrier_to_command(resource_tracker->buffer_driver_id, resource_tracker->usage_access, new_usage_access, r_command->buffer_barrier_index, r_command->buffer_barrier_count); #endif - // FIXME: Memory barriers are currently pushed regardless of whether buffer barriers are being used or not. Refer to the comment on the - // definition of USE_BUFFER_BARRIERS for the reason behind this. This can be fixed to be one case or the other once it's been confirmed - // the buffer and memory barrier behavior discrepancy has been solved. - r_command->memory_barrier.src_access = resource_tracker->usage_access; - r_command->memory_barrier.dst_access = new_usage_access; + // Memory barriers are pushed regardless of buffer barriers being used or not. + r_command->memory_barrier.src_access = r_command->memory_barrier.src_access | resource_tracker->usage_access; + r_command->memory_barrier.dst_access = r_command->memory_barrier.dst_access | new_usage_access; } else { DEV_ASSERT(false && "Resource tracker does not contain a valid buffer or texture ID."); } @@ -449,10 +466,12 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr if (different_usage) { // Even if the usage of the resource isn't a write usage explicitly, a different usage implies a transition and it should therefore be considered a write. - write_usage = true; + // In the case of buffers however, this is not exactly necessary if the driver does not consider different buffer usages as different states. + write_usage = write_usage || bool(resource_tracker->texture_driver_id) || driver_buffers_require_transitions; resource_tracker->usage = new_resource_usage; } + bool command_intersection_failed = false; if (search_tracker->write_command_or_list_index >= 0) { if (search_tracker->write_command_list_enabled) { // Make this command adjacent to any commands that wrote to this resource and intersect with the slice if it applies. @@ -464,7 +483,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr if (!resource_has_parent || search_tracker_rect.intersects(write_list_node.subresources)) { if (write_list_node.command_index == p_command_index) { ERR_FAIL_COND_MSG(!resource_has_parent, "Command can't have itself as a dependency."); - } else { + } else if (_check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index)) { // Command is dependent on this command. Add this command to the adjacency list of the write command. _add_adjacent_command(write_list_node.command_index, p_command_index, r_command); @@ -480,6 +499,8 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr write_list_index = write_list_node.next_list_index; continue; } + } else { + command_intersection_failed = true; } } @@ -490,14 +511,16 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr // The index is just the latest command index that wrote to the resource. if (search_tracker->write_command_or_list_index == p_command_index) { ERR_FAIL_MSG("Command can't have itself as a dependency."); - } else { + } else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index)) { _add_adjacent_command(search_tracker->write_command_or_list_index, p_command_index, r_command); + } else { + command_intersection_failed = true; } } } if (write_usage) { - if (resource_has_parent) { + if (resource_has_parent || command_intersection_failed) { if (!search_tracker->write_command_list_enabled && search_tracker->write_command_or_list_index >= 0) { // Write command list was not being used but there was a write command recorded. Add a new node with the entire parent resource's subresources and the recorded command index to the list. const RDD::TextureSubresourceRange &tracker_subresources = search_tracker->texture_subresources; @@ -1318,6 +1341,7 @@ void RenderingDeviceGraph::initialize(RDD *p_driver, RenderingContextDriver::Dev driver_honors_barriers = driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS); driver_clears_with_copy_engine = driver->api_trait_get(RDD::API_TRAIT_CLEARS_WITH_COPY_ENGINE); + driver_buffers_require_transitions = driver->api_trait_get(RDD::API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS); } void RenderingDeviceGraph::finalize() { diff --git a/servers/rendering/rendering_device_graph.h b/servers/rendering/rendering_device_graph.h index e52ab0c2f5..9ddd70bc80 100644 --- a/servers/rendering/rendering_device_graph.h +++ b/servers/rendering/rendering_device_graph.h @@ -637,6 +637,7 @@ private: BarrierGroup barrier_group; bool driver_honors_barriers : 1; bool driver_clears_with_copy_engine : 1; + bool driver_buffers_require_transitions : 1; WorkaroundsState workarounds_state; TightLocalVector<Frame> frames; uint32_t frame = 0; @@ -648,6 +649,7 @@ private: static bool _is_write_usage(ResourceUsage p_usage); static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage); static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage); + bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const; int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index); void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command); int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index); diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h index 4c277ac215..34f11924ce 100644 --- a/servers/rendering/rendering_method.h +++ b/servers/rendering/rendering_method.h @@ -168,6 +168,7 @@ public: virtual void environment_set_bg_energy(RID p_env, float p_multiplier, float p_exposure_value) = 0; virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) = 0; + virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; virtual RS::EnvironmentBG environment_get_background(RID p_Env) const = 0; virtual RID environment_get_sky(RID p_env) const = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 766ec8fa96..5c3ee513c7 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -786,10 +786,8 @@ public: FUNC2(environment_set_canvas_max_layer, RID, int) FUNC6(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource) -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 FUNC2(environment_set_camera_feed_id, RID, int) -#endif + FUNC6(environment_set_ssr, RID, bool, int, float, float, float) FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index ddd4c41059..4dade4d79f 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -1213,7 +1213,7 @@ public: struct ShaderCompileInfo { HashMap<StringName, FunctionInfo> functions; Vector<ModeInfo> render_modes; - VaryingFunctionNames varying_function_names = VaryingFunctionNames(); + VaryingFunctionNames varying_function_names; HashSet<String> shader_types; GlobalShaderUniformGetTypeFunc global_shader_uniform_type_func = nullptr; bool is_include = false; diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp index 0e41a178b5..88ea74cdfc 100644 --- a/servers/rendering/shader_preprocessor.cpp +++ b/servers/rendering/shader_preprocessor.cpp @@ -816,6 +816,11 @@ void ShaderPreprocessor::process_undef(Tokenizer *p_tokenizer) { } if (state->defines.has(label)) { + if (state->defines[label]->is_builtin) { + set_error(vformat(RTR("Cannot use '%s' on built-in define."), "undef"), line); + return; + } + memdelete(state->defines[label]); state->defines.erase(label); } @@ -1324,6 +1329,35 @@ Error ShaderPreprocessor::preprocess(const String &p_code, const String &p_filen pp_state.current_filename = p_filename; pp_state.save_regions = r_regions != nullptr; } + + // Built-in defines. + { + static HashMap<StringName, String> defines; + + if (defines.is_empty()) { + const String rendering_method = OS::get_singleton()->get_current_rendering_method(); + + if (rendering_method == "forward_plus") { + defines["CURRENT_RENDERER"] = _MKSTR(2); + } else if (rendering_method == "mobile") { + defines["CURRENT_RENDERER"] = _MKSTR(1); + } else { // gl_compatibility + defines["CURRENT_RENDERER"] = _MKSTR(0); + } + + defines["RENDERER_COMPATIBILITY"] = _MKSTR(0); + defines["RENDERER_MOBILE"] = _MKSTR(1); + defines["RENDERER_FORWARD_PLUS"] = _MKSTR(2); + } + + for (const KeyValue<StringName, String> &E : defines) { + Define *define = memnew(Define); + define->is_builtin = true; + define->body = E.value; + pp_state.defines[E.key] = define; + } + } + Error err = preprocess(&pp_state, p_code, r_result); if (err != OK) { if (r_error_text) { diff --git a/servers/rendering/shader_preprocessor.h b/servers/rendering/shader_preprocessor.h index 0a90aec958..b3d9594bcb 100644 --- a/servers/rendering/shader_preprocessor.h +++ b/servers/rendering/shader_preprocessor.h @@ -132,6 +132,7 @@ private: struct Define { Vector<String> arguments; String body; + bool is_builtin = false; }; struct Branch { diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp index 1bbb5da6bb..e7556f9000 100644 --- a/servers/rendering/storage/environment_storage.cpp +++ b/servers/rendering/storage/environment_storage.cpp @@ -189,6 +189,18 @@ RS::EnvironmentReflectionSource RendererEnvironmentStorage::environment_get_refl return env->reflection_source; } +void RendererEnvironmentStorage::environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_NULL(env); + env->camera_feed_id = p_camera_feed_id; +} + +int RendererEnvironmentStorage::environment_get_camera_feed_id(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_NULL_V(env, -1); + return env->camera_feed_id; +} + // Tonemap void RendererEnvironmentStorage::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) { diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h index 9f78808ff7..6fdc047ba2 100644 --- a/servers/rendering/storage/environment_storage.h +++ b/servers/rendering/storage/environment_storage.h @@ -57,6 +57,7 @@ private: float ambient_light_energy = 1.0; float ambient_sky_contribution = 1.0; RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; + int camera_feed_id = 0; // Tonemap RS::EnvironmentToneMapper tone_mapper; @@ -181,10 +182,8 @@ public: void environment_set_bg_energy(RID p_env, float p_multiplier, float p_exposure_value); void environment_set_canvas_max_layer(RID p_env, int p_max_layer); void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG); -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); -#endif + int environment_get_camera_feed_id(RID p_env) const; RS::EnvironmentBG environment_get_background(RID p_env) const; RID environment_get_sky(RID p_env) const; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 1008d5706e..272908aa49 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -309,7 +309,7 @@ RID RenderingServer::get_white_texture() { w[i] = 255; } } - Ref<Image> white = memnew(Image(4, 4, 0, Image::FORMAT_RGB8, wt)); + Ref<Image> white = memnew(Image(4, 4, false, Image::FORMAT_RGB8, wt)); white_texture = texture_2d_create(white); return white_texture; } @@ -2980,6 +2980,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_create"), &RenderingServer::environment_create); ClassDB::bind_method(D_METHOD("environment_set_background", "env", "bg"), &RenderingServer::environment_set_background); + ClassDB::bind_method(D_METHOD("environment_set_camera_id", "env", "id"), &RenderingServer::environment_set_camera_feed_id); ClassDB::bind_method(D_METHOD("environment_set_sky", "env", "sky"), &RenderingServer::environment_set_sky); ClassDB::bind_method(D_METHOD("environment_set_sky_custom_fov", "env", "scale"), &RenderingServer::environment_set_sky_custom_fov); ClassDB::bind_method(D_METHOD("environment_set_sky_orientation", "env", "orientation"), &RenderingServer::environment_set_sky_orientation); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 6c1e1274d4..90365a19eb 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1180,6 +1180,7 @@ public: virtual void environment_set_bg_energy(RID p_env, float p_multiplier, float p_exposure_value) = 0; virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; virtual void environment_set_ambient_light(RID p_env, const Color &p_color, EnvironmentAmbientSource p_ambient = ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, EnvironmentReflectionSource p_reflection_source = ENV_REFLECTION_SOURCE_BG) = 0; + virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; enum EnvironmentGlowBlendMode { ENV_GLOW_BLEND_MODE_ADDITIVE, diff --git a/tests/core/string/test_fuzzy_search.h b/tests/core/string/test_fuzzy_search.h new file mode 100644 index 0000000000..d647ebdd1a --- /dev/null +++ b/tests/core/string/test_fuzzy_search.h @@ -0,0 +1,83 @@ +/**************************************************************************/ +/* test_fuzzy_search.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 TEST_FUZZY_SEARCH_H +#define TEST_FUZZY_SEARCH_H + +#include "core/string/fuzzy_search.h" +#include "tests/test_macros.h" + +namespace TestFuzzySearch { + +struct FuzzySearchTestCase { + String query; + String expected; +}; + +// Ideally each of these test queries should represent a different aspect, and potentially bottleneck, of the search process. +const FuzzySearchTestCase test_cases[] = { + // Short query, many matches, few adjacent characters + { "///gd", "./menu/hud/hud.gd" }, + // Filename match with typo + { "sm.png", "./entity/blood_sword/sam.png" }, + // Multipart filename word matches + { "ham ", "./entity/game_trap/ha_missed_me.wav" }, + // Single word token matches + { "push background", "./entity/background_zone1/background/push.png" }, + // Long token matches + { "background_freighter background png", "./entity/background_freighter/background/background.png" }, + // Many matches, many short tokens + { "menu menu characters wav", "./menu/menu/characters/smoker/0.wav" }, + // Maximize total matches + { "entity gd", "./entity/entity_man.gd" } +}; + +Vector<String> load_test_data() { + Ref<FileAccess> fp = FileAccess::open(TestUtils::get_data_path("fuzzy_search/project_dir_tree.txt"), FileAccess::READ); + REQUIRE(fp.is_valid()); + return fp->get_as_utf8_string().split("\n"); +} + +TEST_CASE("[FuzzySearch] Test fuzzy search results") { + FuzzySearch search; + Vector<FuzzySearchResult> results; + Vector<String> targets = load_test_data(); + + for (FuzzySearchTestCase test_case : test_cases) { + search.set_query(test_case.query); + search.search_all(targets, results); + CHECK_GT(results.size(), 0); + CHECK_EQ(results[0].target, test_case.expected); + } +} + +} //namespace TestFuzzySearch + +#endif // TEST_FUZZY_SEARCH_H diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 49afc55c64..9adc97e845 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -389,6 +389,19 @@ TEST_CASE("[String] Find") { MULTICHECK_STRING_INT_EQ(s, rfind, "", 15, -1); } +TEST_CASE("[String] Find character") { + String s = "racecar"; + CHECK_EQ(s.find_char('r'), 0); + CHECK_EQ(s.find_char('r', 1), 6); + CHECK_EQ(s.find_char('e'), 3); + CHECK_EQ(s.find_char('e', 4), -1); + + CHECK_EQ(s.rfind_char('r'), 6); + CHECK_EQ(s.rfind_char('r', 5), 0); + CHECK_EQ(s.rfind_char('e'), 3); + CHECK_EQ(s.rfind_char('e', 2), -1); +} + TEST_CASE("[String] Find case insensitive") { String s = "Pretty Whale Whale"; MULTICHECK_STRING_EQ(s, findn, "WHA", 7); @@ -1254,6 +1267,12 @@ TEST_CASE("[String] is_subsequence_of") { CHECK(String("Sub").is_subsequence_ofn(a)); } +TEST_CASE("[String] is_lowercase") { + CHECK(String("abcd1234 !@#$%^&*()_-=+,.<>/\\|[]{};':\"`~").is_lowercase()); + CHECK(String("").is_lowercase()); + CHECK(!String("abc_ABC").is_lowercase()); +} + TEST_CASE("[String] match") { CHECK(String("img1.png").match("*.png")); CHECK(!String("img1.jpeg").match("*.png")); diff --git a/tests/data/fuzzy_search/project_dir_tree.txt b/tests/data/fuzzy_search/project_dir_tree.txt new file mode 100644 index 0000000000..153dd8802a --- /dev/null +++ b/tests/data/fuzzy_search/project_dir_tree.txt @@ -0,0 +1,999 @@ +./menu/home/home_menu.tscn +./menu/tooltips/tooltip_server.tscn +./menu/tooltips/tooltip_server.gd +./menu/tooltips/tooltip.gd +./menu/menu/characters/smoker/4.wav +./menu/menu/characters/smoker/6.wav +./menu/menu/characters/smoker/10.wav +./menu/menu/characters/smoker/smoker.tscn +./menu/menu/characters/smoker/8.wav +./menu/menu/characters/smoker/type.gd +./menu/menu/characters/smoker/9.wav +./menu/menu/characters/smoker/5.wav +./menu/menu/characters/smoker/0.wav +./menu/menu/characters/smoker/back_light.png +./menu/menu/characters/smoker/glasses.png +./menu/menu/characters/smoker/smoker.gd +./menu/menu/characters/smoker/cig.gd +./menu/menu/characters/smoker/eyes.png +./menu/menu/characters/smoker/3.wav +./menu/menu/characters/smoker/to_pixelate.gd +./menu/menu/characters/smoker/7.wav +./menu/menu/characters/smoker/cig.png +./menu/menu/characters/smoker/2.wav +./menu/menu/characters/smoker/1.wav +./menu/menu/characters/smoke.png +./menu/menu/characters/space_bandit.tres +./menu/menu/characters/dead_guy/blood_texture.png +./menu/menu/characters/dead_guy/head_gibbed.png +./menu/menu/characters/dead_guy/back_light.png +./menu/menu/characters/dead_guy/smoker.gd +./menu/menu/characters/dead_guy/eyes.png +./menu/menu/characters/dead_guy/to_pixelate.gd +./menu/menu/characters/dead_guy/dead_guy.gd +./menu/menu/characters/dead_guy/eyes.gd +./menu/menu/characters/dead_guy/x.png +./menu/menu/characters/dead_guy/dead_guy.tscn +./menu/menu/characters/dead_guy/mouth.png +./menu/menu/characters/dead_guy/dead_guy.tres +./menu/menu/characters/Label.gd +./menu/menu/characters/guns2.png +./menu/menu/characters/c.gd +./menu/menu/characters/smoke.gd +./menu/menu/characters/character.gd +./menu/menu/characters/space_bandit/eyes.tres +./menu/menu/characters/space_bandit/space_bandit_face_happy.png +./menu/menu/characters/space_bandit/space_bandit.gd +./menu/menu/characters/space_bandit/space_bandit.tscn +./menu/menu/characters/boss/smoker.tscn +./menu/menu/characters/boss/back_light.png +./menu/menu/characters/boss/glasses.png +./menu/menu/characters/boss/smoker.gd +./menu/menu/characters/boss/cig.gd +./menu/menu/characters/boss/eyes.png +./menu/menu/characters/boss/to_pixelate.gd +./menu/menu/characters/boss/x.png +./menu/menu/characters/boss/cig.png +./menu/menu/characters/eye.gd +./menu/menu/characters/space_bandit_face_happy.png +./menu/menu/characters/face.gd +./menu/menu/characters/color.tres +./menu/menu/characters/space_bandit.tscn +./menu/menu/characters/space_bandit_face_bloody.png +./menu/menu/characters/guns.png +./menu/menu/characters/eyes2.tres +./menu/options/controls/use.tres +./menu/options/controls/input_map_button.gd +./menu/options/controls/swap.tres +./menu/options/controls/teleport.tres +./menu/options/controls/joy_controls.tscn +./menu/options/controls/mouse_and_keyboard_controls.tscn +./menu/options/controls/input_map_button.tscn +./menu/options/controls/special.tres +./menu/options/controls/throw.tres +./menu/options/controls/center.tres +./menu/options/controls/input_action.gd +./menu/options/controls/move.tres +./menu/options/controls/melee.tres +./menu/options/controls/controls.gd +./menu/options/options.gd +./menu/options/options.tscn +./menu/options/graphics/graphics.tscn +./menu/options/graphics/graphics.gd +./menu/options/audio/audio.gd +./menu/options/audio/audio.tscn +./menu/options/game/game.gd +./menu/options/game/game.tscn +./menu/circle.tres +./menu/fonts/keys.png +./menu/fonts/rainbow_font.tres +./menu/fonts/fallback_font.tres +./menu/fonts/taxi_Driver.png +./menu/fonts/NotoSansJP-Regular.ttf +./menu/fonts/taxi_Driver_noise.png +./menu/fonts/rainbow_font_shader.tres +./menu/fonts/m5x7.ttf +./menu/colors.gd +./menu/toast_enter.wav +./menu/ui_colors.tres +./menu/pause/pause.gd +./menu/pause/rainbow.tres +./menu/pause/Label.gd +./menu/pause/label.tscn +./menu/pause/pause.tscn +./menu/hoola.wav +./menu/in_game_fallback.tres +./menu/widgets/next_unlock.gd +./menu/widgets/slider.gd +./menu/widgets/fade.tscn +./menu/widgets/background_hint.gd +./menu/widgets/panel_container_smoke.gd +./menu/widgets/wishlist_sticker.gd +./menu/widgets/smoke.tres +./menu/widgets/color_grade.gd +./menu/widgets/rich_text_button.gd +./menu/widgets/panel_container_smok2.tscn +./menu/widgets/slider.tscn +./menu/widgets/rich_text_heading.gd +./menu/widgets/background_hint.tscn +./menu/widgets/tip.tscn +./menu/widgets/rich_text_button.tscn +./menu/widgets/toggle.tscn +./menu/widgets/heading.tscn +./menu/widgets/hover.tscn +./menu/widgets/toggle.gd +./menu/widgets/smoke_panel_material.tres +./menu/widgets/confirm.gd +./menu/widgets/tip.gd +./menu/widgets/panel.gd +./menu/widgets/modal.gd +./menu/widgets/NinePatchRect.gd +./menu/widgets/smoke.shader +./menu/widgets/9patch.png +./menu/widgets/big_hint.gd +./menu/widgets/TDVB1i.png +./menu/widgets/color_grade.tscn +./menu/widgets/text.gd +./menu/widgets/panel_container_smoke.tscn +./menu/widgets/1x1.png +./menu/widgets/confirm.tscn +./menu/widgets/RichTextPanel.tscn +./menu/hud/cursor.png +./menu/hud/inventory/draggable.gd +./menu/hud/inventory/menu/characters/color.tres +./menu/hud/inventory/drop_zone.tscn +./menu/hud/inventory/RichTextLabel.gd +./menu/hud/inventory/hud_icon_mutation.tscn +./menu/hud/inventory/use_count.gd +./menu/hud/inventory/draggable.tscn +./menu/hud/inventory/black_shadow_font.tres +./menu/hud/inventory/x.png +./menu/hud/inventory/hud_icon_mutation.gd +./menu/hud/inventory/flash_parent.gd +./menu/hud/inventory/TextureRect4.gd +./menu/hud/cursor.tscn +./menu/hud/hud.tscn +./menu/hud/cursor.gd +./menu/hud/hud.gd +./menu/metal_text.tres +./menu/rich_text_effects/RichTextType.gd +./menu/rich_text_effects/RichTextPanel.gd +./menu/rich_text_effects/RichTextFlash.gd +./menu/rich_text_effects/RichTextTranslate.gd +./menu/in_game.tres +./menu/lcd_screen_font.tres +./menu/toast_exit.wav +./menu/stack/ahses_material.tres +./menu/stack/home.kra +./menu/stack/fade.gd +./menu/stack/stack.tscn +./menu/stack/stack.gd +./menu/stack/version.gd +./menu/stack/art.kra +./entity/unlock_skin_classic/icon.png +./entity/use.gd +./entity/chair/entity.tscn +./entity/chair/icon.png +./entity/chair/data.gd +./entity/man_desert/entity.tscn +./entity/man_desert/icon.png +./entity/man_desert/teleprompts/need_medbay.wav +./entity/man_desert/teleprompts/me_too.wav +./entity/man_desert/teleprompts/get_up_alt.wav +./entity/man_desert/teleprompts/getting_a_medpack.wav +./entity/man_desert/teleprompts/firstaid-incoming.wav +./entity/man_desert/teleprompts/batch_name.py +./entity/man_desert/teleprompts/what.wav +./entity/man_desert/teleprompts/oo.wav +./entity/man_desert/teleprompts/yell.wav +./entity/man_desert/teleprompts/rushing.wav +./entity/man_desert/teleprompts/ooo.wav +./entity/man_desert/teleprompts/coming_to_heal_ya.wav +./entity/man_desert/teleprompts/where_is_the_medpack.wav +./entity/man_desert/teleprompts/ah.wav +./entity/man_desert/teleprompts/no.wav +./entity/man_desert/teleprompts/going_to_camp_medbay.wav +./entity/man_desert/teleprompts/aa.wav +./entity/man_desert/teleprompts/pirate_alt.wav +./entity/man_desert/teleprompts/take_morphine.wav +./entity/man_desert/teleprompts/ee.wav +./entity/man_desert/teleprompts/get_up.wav +./entity/man_desert/teleprompts/aw.wav +./entity/man_desert/teleprompts/easy.wav +./entity/man_desert/teleprompts/intruder.wav +./entity/man_desert/teleprompts/amateur.wav +./entity/man_desert/teleprompts/hes_not_moving.wav +./entity/man_desert/teleprompts/pirate.wav +./entity/man_desert/teleprompts/i_dont_know.wav +./entity/man_desert/teleprompts/index.txt +./entity/man_desert/teleprompts/move.wav +./entity/man_desert/teleprompts/hes_stuck.wav +./entity/man_desert/teleprompts/how.wav +./entity/man_desert/teleprompts/uu.wav +./entity/man_desert/teleprompts/where_is_the_gun.wav +./entity/man_desert/teleprompts/getting_a_gun.wav +./entity/man_desert/data.gd +./entity/man_desert/hand.png +./entity/barrel_side_smoke/entity.tscn +./entity/barrel_side_smoke/icon.png +./entity/barrel_side_smoke/data.gd +./entity/barrel_smoke/entity.tscn +./entity/barrel_smoke/icon.png +./entity/barrel_smoke/data.gd +./entity/project_box/entity.tscn +./entity/project_box/icon.png +./entity/project_box/data.gd +./entity/mutation_saw/entity.tscn +./entity/mutation_saw/icon.png +./entity/mutation_saw/special.gd +./entity/mutation_saw/data.gd +./entity/lift_entrance/entity.tscn +./entity/lift_entrance/icon.png +./entity/lift_entrance/special.gd +./entity/lift_entrance/data.gd +./entity/mutation_accuracy_boost_DELETE/entity.tscn +./entity/mutation_accuracy_boost_DELETE/icon.png +./entity/mutation_accuracy_boost_DELETE/special.gd +./entity/mutation_accuracy_boost_DELETE/data.gd +./entity/skin_ruffle/entity.tscn +./entity/skin_ruffle/icon.png +./entity/skin_ruffle/carried.png +./entity/skin_ruffle/data.gd +./entity/editor_only_icon.gd +./entity/console_dark/entity.tscn +./entity/console_dark/icon.png +./entity/console_dark/data.gd +./entity/console_dark/animation.png +./entity/smg2/entity.tscn +./entity/smg2/used.wav +./entity/smg2/icon.png +./entity/smg2/data.gd +./entity/smg2/debug.gd +./entity/grenade_launcher/entity.tscn +./entity/grenade_launcher/used.wav +./entity/grenade_launcher/icon.png +./entity/grenade_launcher/special.gd +./entity/grenade_launcher/data.gd +./entity/floor_tile_full_square/entity.tscn +./entity/floor_tile_full_square/icon.png +./entity/floor_tile_full_square/data.gd +./entity/grate_1/entity.tscn +./entity/grate_1/icon.png +./entity/grate_1/data.gd +./entity/bed_bunk_corner/entity.tscn +./entity/bed_bunk_corner/icon.png +./entity/bed_bunk_corner/data.gd +./entity/kill_streak_rail_gun_level_3/entity.tscn +./entity/kill_streak_rail_gun_level_3/data.gd +./entity/teleporter_random_weak/entity.tscn +./entity/teleporter_random_weak/teleporter_model.gd +./entity/teleporter_random_weak/used.wav +./entity/teleporter_random_weak/icon.png +./entity/teleporter_random_weak/special.gd +./entity/teleporter_random_weak/ray.gd +./entity/teleporter_random_weak/data.gd +./entity/teleporter_random_weak/flap.png +./entity/entities.kra +./entity/jerry_can/entity.tscn +./entity/jerry_can/icon.png +./entity/jerry_can/data.gd +./entity/kill_streak_helmet_full/entity.tscn +./entity/kill_streak_helmet_full/data.gd +./entity/background_derelict/background2.gd +./entity/background_derelict/entity.tscn +./entity/background_derelict/icon.png +./entity/background_derelict/background/space.png +./entity/background_derelict/background/line.png +./entity/background_derelict/background/overlay.png +./entity/background_derelict/background/background2.png +./entity/background_derelict/background/background.png +./entity/background_derelict/background/engine_glow.tscn +./entity/background_derelict/background/lines3.png +./entity/background_derelict/background/background.tscn +./entity/background_derelict/background/lines.tres +./entity/background_derelict/background/xx.gd +./entity/background_derelict/background/background.gd +./entity/background_derelict/background/bayer16tile2.png +./entity/background_derelict/background/push.png +./entity/background_derelict/background/palette_mono.png +./entity/background_derelict/background/stars.gd +./entity/background_derelict/background/lines2.png +./entity/background_derelict/background/lines.shader +./entity/background_derelict/background/ambience.gd +./entity/background_derelict/background/space_ship_ambience.ogg +./entity/background_derelict/background/stars.png +./entity/background_derelict/data.gd +./entity/smoker/entity.tscn +./entity/smoker/right_hand.png +./entity/smoker/eyes.png +./entity/smoker/data.gd +./entity/smoker/animate.gd +./entity/smoker/left_hand.png +./entity/EntityStatic.gd +./entity/level_model.gd +./entity/class_teleporter_drop_chance/entity.tscn +./entity/class_teleporter_drop_chance/icon.png +./entity/class_teleporter_drop_chance/special.gd +./entity/class_teleporter_drop_chance/data.gd +./entity/smg4/entity.tscn +./entity/smg4/used.wav +./entity/smg4/icon.png +./entity/smg4/data.gd +./entity/medpack/entity.tscn +./entity/medpack/icon.png +./entity/medpack/dead.png +./entity/medpack/data.gd +./entity/model.gd +./entity/doom_transition/entity.tscn +./entity/doom_transition/icon.png +./entity/doom_transition/special.gd +./entity/doom_transition/Screenshot from 2021-12-08 18-25-03.png +./entity/doom_transition/data.gd +./entity/glass_block_exploding/entity.tscn +./entity/glass_block_exploding/icon.png +./entity/glass_block_exploding/special.gd +./entity/glass_block_exploding/dead.png +./entity/glass_block_exploding/data.gd +./entity/floor_ting/entity.tscn +./entity/floor_ting/icon.png +./entity/floor_ting/data.gd +./entity/background_crashed_ship/entity.tscn +./entity/background_crashed_ship/icon.png +./entity/background_crashed_ship/background/background2.kra +./entity/background_crashed_ship/background/dust_storm_negative.png +./entity/background_crashed_ship/background/background2.png +./entity/background_crashed_ship/background/background2 (copy 1).png +./entity/background_crashed_ship/background/dust_bowl.ogg +./entity/background_crashed_ship/background/background.tscn +./entity/background_crashed_ship/background/background.kra +./entity/background_crashed_ship/data.gd +./entity/game_aim_hack_boss/entity.tscn +./entity/game_aim_hack_boss/icon.png +./entity/game_aim_hack_boss/special.gd +./entity/game_aim_hack_boss/give_my_arm_back.wav +./entity/game_aim_hack_boss/my_arm_came_off.wav +./entity/game_aim_hack_boss/data.gd +./entity/sink/entity.tscn +./entity/sink/icon.png +./entity/sink/data.gd +./entity/grate_2/entity.tscn +./entity/grate_2/icon.png +./entity/grate_2/data.gd +./entity/barrel_side/entity.tscn +./entity/barrel_side/icon.png +./entity/barrel_side/data.gd +./entity/oxygen/entity.tscn +./entity/oxygen/icon.png +./entity/oxygen/shadow.png +./entity/oxygen/data.gd +./entity/oxygen/normal.png +./entity/unlock_skin_robo/entity.tscn +./entity/unlock_skin_robo/icon.png +./entity/unlock_skin_robo/special.gd +./entity/unlock_skin_robo/data.gd +./entity/entity_agency_model.gd +./entity/floor_tile_wood/entity.tscn +./entity/floor_tile_wood/icon.png +./entity/floor_tile_wood/data.gd +./entity/qr_code/entity.tscn +./entity/qr_code/icon.png +./entity/qr_code/data.gd +./entity/background_sun/overlay.png +./entity/background_sun/entity.tscn +./entity/background_sun/c.gd +./entity/background_sun/kill.tscn +./entity/background_sun/icon.png +./entity/background_sun/special.gd +./entity/background_sun/wtf.tres +./entity/background_sun/background/background2.png +./entity/background_sun/background/background.tscn +./entity/background_sun/background/color2s.tres +./entity/background_sun/background/background_glow.png +./entity/background_sun/data.gd +./entity/background_sun/kill.gd +./entity/background_sun/stars.png +./entity/background_zone_intro/overlay.png +./entity/background_zone_intro/entity.tscn +./entity/background_zone_intro/icon.png +./entity/background_zone_intro/special.gd +./entity/background_zone_intro/background/space.png +./entity/background_zone_intro/background/line.png +./entity/background_zone_intro/background/background2.png +./entity/background_zone_intro/background/background.png +./entity/background_zone_intro/background/engine_glow.tscn +./entity/background_zone_intro/background/lines3.png +./entity/background_zone_intro/background/background.tscn +./entity/background_zone_intro/background/lines.tres +./entity/background_zone_intro/background/background.gd +./entity/background_zone_intro/background/bayer16tile2.png +./entity/background_zone_intro/background/push.png +./entity/background_zone_intro/background/palette_mono.png +./entity/background_zone_intro/background/stars.gd +./entity/background_zone_intro/background/lines2.png +./entity/background_zone_intro/background/lines.shader +./entity/background_zone_intro/background/ambience.gd +./entity/background_zone_intro/background/space_ship_ambience.ogg +./entity/background_zone_intro/background/stars.png +./entity/background_zone_intro/background_end.png +./entity/background_zone_intro/data.gd +./entity/background_zone_intro/tinge.png +./entity/closet_alt/entity.tscn +./entity/closet_alt/icon.png +./entity/closet_alt/data.gd +./entity/meta_random_sound/entity.tscn +./entity/meta_random_sound/giberish.wav +./entity/meta_random_sound/icon.png +./entity/meta_random_sound/special.gd +./entity/meta_random_sound/who.wav +./entity/meta_random_sound/data.gd +./entity/meta_random_sound/hoola_boola.wav +./entity/meta_random_sound/space_bandit.wav +./entity/lines/entity.tscn +./entity/lines/icon.png +./entity/lines/data.gd +./entity/teleporter_random_avoid_ray/entity.tscn +./entity/teleporter_random_avoid_ray/used.wav +./entity/teleporter_random_avoid_ray/icon.png +./entity/teleporter_random_avoid_ray/ray.gd +./entity/teleporter_random_avoid_ray/data.gd +./entity/teleporter_random_avoid_ray/flap.png +./entity/teleporter_random_avoid_ray/RayCast2D.gd +./entity/teleporter_random_avoid_ray/area.gd +./entity/teleporter_random_avoid_ray/flap.gd +./entity/saw/blades.gd +./entity/saw/entity.tscn +./entity/saw/used.wav +./entity/saw/icon.png +./entity/saw/special.gd +./entity/saw/carried.png +./entity/saw/data.gd +./entity/saw/used (copy 1).wav +./entity/saw/saw.wav +./entity/saw/carried_blades.png +./entity/floor_tile_checkerdboard/damage.png +./entity/floor_tile_checkerdboard/entity.tscn +./entity/floor_tile_checkerdboard/icon.png +./entity/floor_tile_checkerdboard/entity.tres +./entity/floor_tile_checkerdboard/data.gd +./entity/mutation_smoke_grenade_upgrade/entity.tscn +./entity/mutation_smoke_grenade_upgrade/icon.png +./entity/mutation_smoke_grenade_upgrade/special.gd +./entity/mutation_smoke_grenade_upgrade/data.gd +./entity/mutation_smoke_grenade_upgrade/mutation_model.gd +./entity/helmet_full/entity.tscn +./entity/helmet_full/pick_up.wav +./entity/helmet_full/icon.png +./entity/helmet_full/data.gd +./entity/helmet_full/helmet-ping.wav +./entity/barrel_explosive/entity.tscn +./entity/barrel_explosive/icon.png +./entity/barrel_explosive/data.gd +./entity/bank/entity.tscn +./entity/bank/icon.png +./entity/bank/special.gd +./entity/bank/data.gd +./entity/kick/entity.tscn +./entity/kick/swipe.png +./entity/kick/used.wav +./entity/kick/icon.png +./entity/kick/AnimatedSprite.gd +./entity/kick/data.gd +./entity/battery/entity.tscn +./entity/battery/icon.png +./entity/battery/data.gd +./entity/lift/entity.tscn +./entity/lift/opening.wav +./entity/lift/doors_open.png +./entity/lift/RichTextLabel.gd +./entity/lift/icon.png +./entity/lift/open.wav +./entity/lift/elevator_end.wav +./entity/lift/lift_model.gd +./entity/lift/label.tscn +./entity/lift/rumble.gd +./entity/lift/level_portal_model.gd +./entity/lift/data.gd +./entity/lift/doors.png +./entity/lift/area.gd +./entity/snes/entity.tscn +./entity/snes/icon.png +./entity/snes/data.gd +./entity/passive_disarm/entity.tscn +./entity/passive_disarm/icon.png +./entity/passive_disarm/special.gd +./entity/passive_disarm/data.gd +./entity/mutation_lots_of_shot/entity.tscn +./entity/mutation_lots_of_shot/icon.png +./entity/mutation_lots_of_shot/special.gd +./entity/mutation_lots_of_shot/data.gd +./entity/pallet2/entity.tscn +./entity/pallet2/icon.png +./entity/pallet2/data.gd +./entity/kill_streak_sword/entity.tscn +./entity/kill_streak_sword/data.gd +./entity/rain/entity.tscn +./entity/rain/icon.png +./entity/rain/special.gd +./entity/rain/rain.png +./entity/rain/rain.tscn +./entity/rain/data.gd +./entity/rain/rain.gd +./entity/white_line/entity.tscn +./entity/white_line/icon.png +./entity/white_line/data.gd +./entity/game_break_sword/entity.tscn +./entity/game_break_sword/icon.png +./entity/game_break_sword/special.gd +./entity/game_break_sword/data.gd +./entity/background_zone1/overlay.png +./entity/background_zone1/entity.tscn +./entity/background_zone1/icon.png +./entity/background_zone1/special.gd +./entity/background_zone1/background/space.png +./entity/background_zone1/background/line.png +./entity/background_zone1/background/background2.png +./entity/background_zone1/background/background.png +./entity/background_zone1/background/engine_glow.tscn +./entity/background_zone1/background/lines3.png +./entity/background_zone1/background/background.tscn +./entity/background_zone1/background/lines.tres +./entity/background_zone1/background/background.gd +./entity/background_zone1/background/bayer16tile2.png +./entity/background_zone1/background/push.png +./entity/background_zone1/background/palette_mono.png +./entity/background_zone1/background/stars.gd +./entity/background_zone1/background/lines2.png +./entity/background_zone1/background/lines.shader +./entity/background_zone1/background/ambience.gd +./entity/background_zone1/background/space_ship_ambience.ogg +./entity/background_zone1/background/stars.png +./entity/background_zone1/data.gd +./entity/background_zone1/tinge.png +./entity/mutation_throw_trap_DELETE/entity.tscn +./entity/mutation_throw_trap_DELETE/icon.png +./entity/mutation_throw_trap_DELETE/special.gd +./entity/mutation_throw_trap_DELETE/data.gd +./entity/agency.gd +./entity/skin_cheese/entity.tscn +./entity/skin_cheese/icon.png +./entity/skin_cheese/carried.png +./entity/skin_cheese/data.gd +./entity/toilet/entity.tscn +./entity/toilet/icon.png +./entity/toilet/special.gd +./entity/toilet/water.png +./entity/toilet/drink.wav +./entity/toilet/data.gd +./entity/smg3/entity.tscn +./entity/smg3/used.wav +./entity/smg3/icon.png +./entity/smg3/dead.png +./entity/smg3/data.gd +./entity/smg3/debug.gd +./entity/teleporter_super/entity.tscn +./entity/teleporter_super/icon.png +./entity/teleporter_super/data.gd +./entity/background_zone_end/overlay.png +./entity/background_zone_end/entity.tscn +./entity/background_zone_end/icon.png +./entity/background_zone_end/special.gd +./entity/background_zone_end/stars2.png +./entity/background_zone_end/background_end.png +./entity/background_zone_end/data.gd +./entity/background_zone_end/tinge.png +./entity/kill_streak_barricade/entity.tscn +./entity/kill_streak_barricade/data.gd +./entity/game_zone_4_boss_1/entity.tscn +./entity/game_zone_4_boss_1/icon.png +./entity/game_zone_4_boss_1/special.gd +./entity/game_zone_4_boss_1/data.gd +./entity/game_zone_4_boss_1/kill_me_and_explode_ship.wav +./entity/mutation_remove_melee/entity.tscn +./entity/mutation_remove_melee/icon.png +./entity/mutation_remove_melee/special.gd +./entity/mutation_remove_melee/data.gd +./entity/he_grenade_level_2/entity.tscn +./entity/he_grenade_level_2/icon.png +./entity/he_grenade_level_2/data.gd +./entity/background_zone_2/entity.tscn +./entity/background_zone_2/icon.png +./entity/background_zone_2/background/background2.kra +./entity/background_zone_2/background/grad.png +./entity/background_zone_2/background/background2.png +./entity/background_zone_2/background/background.png +./entity/background_zone_2/background/background2 (copy 1).png +./entity/background_zone_2/background/backgrounds.gd +./entity/background_zone_2/background/wall_overlay.png +./entity/background_zone_2/background/background.tscn +./entity/background_zone_2/background/Screenshot from 2022-07-07 10-58-48.png +./entity/background_zone_2/background/background.gd +./entity/background_zone_2/background/shadow.png +./entity/background_zone_2/background/engine smoke.png +./entity/background_zone_2/background/background.kra +./entity/background_zone_2/background/sea.ogg +./entity/background_zone_2/background/background2blur.png +./entity/background_zone_2/background/test.gd +./entity/background_zone_2/background/grad3.png +./entity/background_zone_2/background/lines2.png +./entity/background_zone_2/background/smoke.tscn +./entity/background_zone_2/background/left_water.tscn +./entity/background_zone_2/background/grad2.png +./entity/background_zone_2/background/para.png +./entity/background_zone_2/data.gd +./entity/pipe_corner/entity.tscn +./entity/pipe_corner/icon.png +./entity/pipe_corner/data.gd +./entity/floor_tile_metal_cow_trap/entity.tscn +./entity/floor_tile_metal_cow_trap/icon.png +./entity/floor_tile_metal_cow_trap/data.gd +./entity/skin_naked/entity.tscn +./entity/skin_naked/icon.png +./entity/skin_naked/carried.png +./entity/skin_naked/data.gd +./entity/valve/entity.tscn +./entity/valve/icon.png +./entity/valve/.icon.png-autosave.kra +./entity/valve/data.gd +./entity/bed/entity.tscn +./entity/bed/icon.png +./entity/bed/data.gd +./entity/game_invisible_guy/entity.tscn +./entity/game_invisible_guy/icon.png +./entity/game_invisible_guy/special.gd +./entity/game_invisible_guy/data.gd +./entity/smg/entity.tscn +./entity/smg/used.wav +./entity/smg/icon.png +./entity/smg/data.gd +./entity/skin_robo/entity.tscn +./entity/skin_robo/icon.png +./entity/skin_robo/carried.png +./entity/skin_robo/data.gd +./entity/bandana/entity.tscn +./entity/bandana/bob.gd +./entity/bandana/icon.png +./entity/bandana/special.gd +./entity/bandana/carried.png +./entity/bandana/data.gd +./entity/bandana/pixel.png +./entity/floor_plug/entity.tscn +./entity/floor_plug/icon.png +./entity/floor_plug/data.gd +./entity/bench/entity.tscn +./entity/bench/icon.png +./entity/bench/data.gd +./entity/meta_strip_items/entity.tscn +./entity/meta_strip_items/special.gd +./entity/meta_strip_items/meta_strip_items_model.gd +./entity/meta_strip_items/data.gd +./entity/crate_teleporter/entity.tscn +./entity/crate_teleporter/icon.png +./entity/crate_teleporter/data.gd +./entity/crate_teleporter/satellite.kra +./entity/crate_garbage/entity.tscn +./entity/crate_garbage/icon.png +./entity/crate_garbage/data.gd +./entity/crate_garbage/gibbed.png +./entity/meta_stats/entity.tscn +./entity/meta_stats/letters.tres +./entity/meta_stats/icon.png +./entity/meta_stats/special.gd +./entity/meta_stats/data.gd +./entity/meta_stats/meta_stats_model.gd +./entity/rail_gun/entity.tscn +./entity/rail_gun/used.wav +./entity/rail_gun/icon.png +./entity/rail_gun/special.gd +./entity/rail_gun/carried.png +./entity/rail_gun/data.gd +./entity/drop_ship_door/entity.tscn +./entity/drop_ship_door/icon.png +./entity/drop_ship_door/data.gd +./entity/floor_lines/entity.tscn +./entity/floor_lines/icon.png +./entity/floor_lines/data.gd +./entity/game_trap/entity.tscn +./entity/game_trap/you_blew_up_my_force_field.wav +./entity/game_trap/droped_my_grenade_2.wav +./entity/game_trap/icon.png +./entity/game_trap/special.gd +./entity/game_trap/droped_my_grenade_0.wav +./entity/game_trap/shock.wav +./entity/game_trap/uh_my_helmet.wav +./entity/game_trap/ha_missed_me.wav +./entity/game_trap/data.gd +./entity/game_trap/try_beat_this_force_field.wav +./entity/game_trap/droped_my_grenade_1.wav +./entity/blood_sword/entity.tscn +./entity/blood_sword/pick_up.wav +./entity/blood_sword/used.wav +./entity/blood_sword/sam2.png +./entity/blood_sword/icon.png +./entity/blood_sword/special.gd +./entity/blood_sword/hit_bar.gd +./entity/blood_sword/data.gd +./entity/blood_sword/sam.png +./entity/blood_sword/dead.wav +./entity/blood_sword/animation.png +./entity/auto_cables_thick/entity.tscn +./entity/auto_cables_thick/data.gd +./entity/auto_cables_thick/wires2.png +./entity/shield/entity.tscn +./entity/shield/pick_up.wav +./entity/shield/icon.png +./entity/shield/carried.png +./entity/shield/data.gd +./entity/shield/helmet-ping.wav +./entity/game_teleport_in/entity.tscn +./entity/game_teleport_in/icon.png +./entity/game_teleport_in/special.gd +./entity/game_teleport_in/data.gd +./entity/shotgun_super/entity.tscn +./entity/shotgun_super/icon.png +./entity/shotgun_super/data.gd +./entity/bottle/entity.tscn +./entity/bottle/icon.png +./entity/bottle/data.gd +./entity/bottle/normal.png +./entity/bottle/icon_shadow.png +./entity/kill_streak_p90/entity.tscn +./entity/kill_streak_p90/data.gd +./entity/drain/entity.tscn +./entity/drain/icon.png +./entity/drain/data.gd +./entity/auto_wires_three/entity.tscn +./entity/auto_wires_three/data.gd +./entity/light/entity.tscn +./entity/light/icon.png +./entity/light/special.gd +./entity/light/light.wav +./entity/light/data.gd +./entity/debris/entity.tscn +./entity/debris/icon.png +./entity/debris/data.gd +./entity/debris/gibbed.png +./entity/mutation_rail_gun_upgrade/entity.tscn +./entity/mutation_rail_gun_upgrade/icon.png +./entity/mutation_rail_gun_upgrade/special.gd +./entity/mutation_rail_gun_upgrade/data.gd +./entity/mutation_rail_gun_upgrade/mutation_model.gd +./entity/auto_cables/entity.tscn +./entity/auto_cables/data.gd +./entity/auto_cables/wires2.png +./entity/stealth_camo/entity.tscn +./entity/stealth_camo/special.gd +./entity/stealth_camo/data.gd +./entity/colt_45/entity.tscn +./entity/colt_45/used.wav +./entity/colt_45/icon.png +./entity/colt_45/dead.png +./entity/colt_45/data.gd +./entity/quantum_suicide_drive/entity.tscn +./entity/quantum_suicide_drive/heart.ogg +./entity/quantum_suicide_drive/icon.png +./entity/quantum_suicide_drive/special.gd +./entity/quantum_suicide_drive/qsd_model.gd +./entity/quantum_suicide_drive/multi.gd +./entity/quantum_suicide_drive/multi.tscn +./entity/quantum_suicide_drive/CenterContainer.gd +./entity/quantum_suicide_drive/carried.png +./entity/quantum_suicide_drive/data.gd +./entity/helmet/entity.tscn +./entity/helmet/pick_up.wav +./entity/helmet/icon.png +./entity/helmet/special.gd +./entity/helmet/die.wav +./entity/helmet/carried.png +./entity/helmet/data.gd +./entity/helmet/helmet-ping.wav +./entity/ammo_box/entity.tscn +./entity/ammo_box/icon.png +./entity/ammo_box/data.gd +./entity/rail_gun_level_2/entity.tscn +./entity/rail_gun_level_2/icon.png +./entity/rail_gun_level_2/data.gd +./entity/glass_block_backup/entity.tscn +./entity/glass_block_backup/icon.png +./entity/glass_block_backup/data.gd +./entity/closet/entity.tscn +./entity/closet/icon.png +./entity/closet/data.gd +./entity/little_boxes/entity.tscn +./entity/little_boxes/icon.png +./entity/little_boxes/data.gd +./entity/meta_health_bar/entity.tscn +./entity/meta_health_bar/health_bar_model.gd +./entity/meta_health_bar/icon.png +./entity/meta_health_bar/special.gd +./entity/meta_health_bar/invunerable.png +./entity/meta_health_bar/data.gd +./entity/night_stand/entity.tscn +./entity/night_stand/icon_normal.png +./entity/night_stand/icon.png +./entity/night_stand/shadow.png +./entity/night_stand/data.gd +./entity/fan/entity.tscn +./entity/fan/flap2.png +./entity/fan/flaps.gd +./entity/fan/icon.png +./entity/fan/data.gd +./entity/fan/flap.png +./entity/fan/icon_shadow.png +./entity/fan/animation.png +./entity/fan/gibbed.png +./entity/game_tutorial_end/entity.tscn +./entity/game_tutorial_end/icon.png +./entity/game_tutorial_end/special.gd +./entity/game_tutorial_end/data.gd +./entity/mutation_disarmament/entity.tscn +./entity/mutation_disarmament/icon.png +./entity/mutation_disarmament/special.gd +./entity/mutation_disarmament/data.gd +./entity/air_lock/icon_open.png +./entity/air_lock/entity.tscn +./entity/air_lock/door_close.wav +./entity/air_lock/icon.png +./entity/air_lock/special.gd +./entity/air_lock/air_lock_model.gd +./entity/air_lock/data.gd +./entity/scorpion/entity.tscn +./entity/scorpion/used.wav +./entity/scorpion/laser.gd +./entity/scorpion/icon.png +./entity/scorpion/data.gd +./entity/kill_streak_aim_hack/entity.tscn +./entity/kill_streak_aim_hack/data.gd +./entity/dungeon_proc_debug/entity.tscn +./entity/dungeon_proc_debug/icon.png +./entity/dungeon_proc_debug/data.gd +./entity/dungeon_proc_debug/debug.gd +./entity/dungeon_proc_debug/debug.tscn +./entity/tarp/entity.tscn +./entity/tarp/icon.png +./entity/tarp/data.gd +./entity/hit_indicator/entity.tscn +./entity/hit_indicator/data.gd +./entity/console_corner/entity.tscn +./entity/console_corner/animation2.tscn +./entity/console_corner/icon.png +./entity/console_corner/data.gd +./entity/console_corner/animation.tscn +./entity/icon.png +./entity/couch_corner/entity.tscn +./entity/couch_corner/icon.png +./entity/couch_corner/data.gd +./entity/m4/entity.tscn +./entity/m4/used.wav +./entity/m4/icon.png +./entity/m4/data.gd +./entity/game_hud/entity.tscn +./entity/game_hud/icon.png +./entity/game_hud/data.gd +./entity/game_hud/inventory_game.tscn +./entity/prototypes.gd +./entity/agent_chicken/emotes.png +./entity/agent_chicken/entity.tscn +./entity/agent_chicken/sound_board.gd +./entity/agent_chicken/bones.tscn +./entity/agent_chicken/bones.gd +./entity/agent_chicken/barks.gd +./entity/agent_chicken/emote.gd +./entity/agent_chicken/icon.png +./entity/agent_chicken/special.gd +./entity/agent_chicken/bark.gd +./entity/agent_chicken/deaad.png +./entity/agent_chicken/icon.gd +./entity/agent_chicken/data.gd +./entity/agent_chicken/animation.tscn +./entity/agent_chicken/emote.tscn +./entity/agent_chicken/hand.png +./entity/velocity/entity.tscn +./entity/velocity/icon.png +./entity/velocity/special.gd +./entity/velocity/data.gd +./entity/aircon/entity.tscn +./entity/aircon/grate.png +./entity/aircon/icon.png +./entity/aircon/data.gd +./entity/aircon/animation.png +./entity/floor_tile_bricks/entity.tscn +./entity/floor_tile_bricks/icon.png +./entity/floor_tile_bricks/data.gd +./entity/pallet/entity.tscn +./entity/pallet/icon.png +./entity/pallet/data.gd +./entity/barricade_deployed/debug.png +./entity/barricade_deployed/field.tscn +./entity/barricade_deployed/entity.tscn +./entity/barricade_deployed/ambience.ogg +./entity/barricade_deployed/icon.png +./entity/barricade_deployed/field.gd +./entity/barricade_deployed/field_material.tres +./entity/barricade_deployed/debug2.png +./entity/barricade_deployed/data.gd +./entity/barricade_deployed/field_material_invert.tres +./entity/barricade_deployed/field_material.gd +./entity/barricade_deployed/gibbed.png +./entity/helmet_nv/entity.tscn +./entity/helmet_nv/pick_up.wav +./entity/helmet_nv/icon.png +./entity/helmet_nv/special.gd +./entity/helmet_nv/carried.png +./entity/helmet_nv/eyes.png +./entity/helmet_nv/data.gd +./entity/helmet_nv/helmet-ping.wav +./entity/helmet_nv/eyes.gd +./entity/mutation_sword/entity.tscn +./entity/mutation_sword/icon.png +./entity/mutation_sword/special.gd +./entity/mutation_sword/data.gd +./entity/field_full_super/entity.tscn +./entity/field_full_super/icon.png +./entity/field_full_super/special.gd +./entity/field_full_super/carried.png +./entity/field_full_super/data.gd +./entity/entity_man.gd +./entity/couch/entity.tscn +./entity/couch/icon.png +./entity/couch/data.gd +./entity/teleporter_lil_hunter/entity.tscn +./entity/teleporter_lil_hunter/icon.png +./entity/teleporter_lil_hunter/tubes.png +./entity/teleporter_lil_hunter/osc_shader.tres +./entity/teleporter_lil_hunter/eyes.png +./entity/teleporter_lil_hunter/data.gd +./entity/teleporter_lil_hunter/osc.tres +./entity/game_tutorial_melee_zone/entity.tscn +./entity/game_tutorial_melee_zone/icon.png +./entity/game_tutorial_melee_zone/special.gd +./entity/game_tutorial_melee_zone/data.gd +./entity/kill_streak_glock/entity.tscn +./entity/kill_streak_glock/data.gd +./entity/skin_mime/entity.tscn +./entity/skin_mime/icon.png +./entity/skin_mime/special.gd +./entity/skin_mime/carried.png +./entity/skin_mime/data.gd +./entity/medpack_hard/entity.tscn +./entity/medpack_hard/icon.png +./entity/medpack_hard/data.gd +./entity/teleporter_overload/entity.tscn +./entity/teleporter_overload/icon.png +./entity/teleporter_overload/special.gd +./entity/teleporter_overload/carried.png +./entity/teleporter_overload/data.gd +./entity/background_freighter/overlay.png +./entity/background_freighter/entity.tscn +./entity/background_freighter/icon.png +./entity/background_freighter/Master.ogg +./entity/background_freighter/background/space.png +./entity/background_freighter/background/line.png +./entity/background_freighter/background/background2.gd +./entity/background_freighter/background/good create.png +./entity/background_freighter/background/backgip.png +./entity/background_freighter/background/background2.png +./entity/background_freighter/background/background.png +./entity/background_freighter/background/engine_glow.tscn +./entity/background_freighter/background/gra2d.png +./entity/background_freighter/background/lines3.png +./entity/background_freighter/background/background.tscn +./entity/background_freighter/background/lines.tres +./entity/background_freighter/background/background.gd +./entity/background_freighter/background/bayer16tile2.png +./entity/background_freighter/background/goodcrate.png +./entity/background_freighter/background/push.png +./entity/background_freighter/background/background_floor.png +./entity/background_freighter/background/palette_mono.png +./entity/background_freighter/background/stars.gd +./entity/background_freighter/background/lines2.png +./entity/background_freighter/background/lines.shader +./entity/background_freighter/background/ambience.gd +./entity/background_freighter/background/bacsdas.png +./entity/background_freighter/background/space_ship_ambience.ogg +./entity/background_freighter/background/stars.png +./entity/background_freighter/data.gd +./entity/auto_wires/entity.tscn +./entity/auto_wires/data.gd +./entity/kill_streak/entity.tscn +./entity/kill_streak/kill_streak_toast.tscn +./entity/kill_streak/icon.png diff --git a/tests/scene/test_primitives.h b/tests/scene/test_primitives.h index 59f23983e5..7426a9ce29 100644 --- a/tests/scene/test_primitives.h +++ b/tests/scene/test_primitives.h @@ -104,8 +104,9 @@ TEST_CASE("[SceneTree][Primitive][Capsule] Capsule Primitive") { float dist_to_yaxis = 0.f; for (Vector3 point : points) { float new_dist_to_y = point.x * point.x + point.z * point.z; - if (new_dist_to_y > dist_to_yaxis) + if (new_dist_to_y > dist_to_yaxis) { dist_to_yaxis = new_dist_to_y; + } } CHECK(dist_to_yaxis <= radius * radius); @@ -114,10 +115,12 @@ TEST_CASE("[SceneTree][Primitive][Capsule] Capsule Primitive") { float max_y{ 0.f }; float min_y{ 0.f }; for (Vector3 point : points) { - if (point.y > max_y) + if (point.y > max_y) { max_y = point.y; - if (point.y < min_y) + } + if (point.y < min_y) { min_y = point.y; + } } CHECK(max_y - min_y <= height); @@ -196,12 +199,14 @@ TEST_CASE("[SceneTree][Primitive][Box] Box Primitive") { for (const Vector3 &normal : normals) { bool add_normal{ true }; for (const Vector3 &vec : distinct_normals) { - if (vec.is_equal_approx(normal)) + if (vec.is_equal_approx(normal)) { add_normal = false; + } } - if (add_normal) + if (add_normal) { distinct_normals.push_back(normal); + } } CHECK_MESSAGE(distinct_normals.size() == 6, @@ -218,8 +223,9 @@ TEST_CASE("[SceneTree][Primitive][Box] Box Primitive") { break; } } - if (!normal_correct_direction) + if (!normal_correct_direction) { break; + } } CHECK_MESSAGE(normal_correct_direction, diff --git a/tests/servers/test_navigation_server_3d.h b/tests/servers/test_navigation_server_3d.h index 4411b1aae5..1b2a5e0db2 100644 --- a/tests/servers/test_navigation_server_3d.h +++ b/tests/servers/test_navigation_server_3d.h @@ -49,7 +49,7 @@ public: } unsigned function1_calls{ 0 }; - Variant function1_latest_arg0{}; + Variant function1_latest_arg0; }; static inline Array build_array() { diff --git a/tests/test_macros.h b/tests/test_macros.h index d32b26f111..9cc075b6d3 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -474,6 +474,6 @@ public: for (int i = 0; i < string_list.size(); ++i) { \ CHECK(string_list[i] == m_slices[i]); \ } \ - } while (0) + } while (false) #endif // TEST_MACROS_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 979aee8001..65d45ae92f 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -82,6 +82,7 @@ #include "tests/core/object/test_object.h" #include "tests/core/object/test_undo_redo.h" #include "tests/core/os/test_os.h" +#include "tests/core/string/test_fuzzy_search.h" #include "tests/core/string/test_node_path.h" #include "tests/core/string/test_string.h" #include "tests/core/string/test_translation.h" diff --git a/thirdparty/README.md b/thirdparty/README.md index 87f8782e7f..7a95e3c724 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -99,9 +99,14 @@ Files extracted from upstream source: ## certs - Upstream: Mozilla, via https://github.com/bagder/ca-bundle -- Version: git (c5a419971b1bec220368c619aaafd0b818aa119f, 2024) +- Version: git (4d3fe6683f651d96be1bbef316b201e9b33b274d, 2024), + generated from mozilla-release changeset b8ea2342548b8571e58f9176d9555ccdb5ec199f - License: MPL 2.0 +Files extracted from upstream source: + +- `ca-bundle.crt` renamed to `ca-certificates.crt` + ## clipper2 @@ -551,8 +556,11 @@ File extracted from upstream release tarball: - All `.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/` and all `.h` from `include/psa/` to `thirdparty/mbedtls/include/psa/` -- All `.c` and `.h` from `library/` to `thirdparty/mbedtls/library/` except - for the `psa_*.c` source files +- All `.c` and `.h` from `library/` to `thirdparty/mbedtls/library/` +- From `library/` to `thirdparty/mbedtls/library/`: + - All `.c` and `.h` files + - Except `bignum_mod.c`, `block_cipher.c`, `ecp_curves_new.c`, `lmots.c`, + `lms.c` - The `LICENSE` file (edited to keep only the Apache 2.0 variant) - Applied the patch `msvc-redeclaration-bug.diff` to fix a compilation error with some MSVC versions @@ -709,7 +717,7 @@ Collection of single-file libraries used in Godot components. * Modifications: use `const char*` instead of `char*` for input string - `smolv.{cpp,h}` * Upstream: https://github.com/aras-p/smol-v - * Version: git (4b52c165c13763051a18e80ffbc2ee436314ceb2, 2020) + * Version: git (9dd54c379ac29fa148cb1b829bb939ba7381d8f4, 2024) * License: Public Domain or MIT - `stb_rect_pack.h` * Upstream: https://github.com/nothings/stb @@ -1063,7 +1071,7 @@ Files extracted from upstream source: Files extracted from upstream source: -- All `.c` and `.h` files, minus `infback.c` +- All `.c` and `.h` files, except `gz*.c` and `infback.c` - `LICENSE` diff --git a/thirdparty/certs/ca-certificates.crt b/thirdparty/certs/ca-certificates.crt index f437587091..c559ab795b 100644 --- a/thirdparty/certs/ca-certificates.crt +++ b/thirdparty/certs/ca-certificates.crt @@ -1,7 +1,9 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Mon Mar 11 15:15:21 2024 GMT +## Certificate data from Mozilla as of: Sat Oct 19 21:26:09 2024 GMT +## +## Find updated versions here: https://curl.se/docs/caextract.html ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +16,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 4d96bd539f4719e9ace493757afbe4a23ee8579de1c97fbebc50bba3c12e8c1e +## SHA256: 36105b01631f9fc03b1eca779b44a30a1a5890b9bf8dc07ccb001a07301e01cf ## @@ -2600,36 +2602,6 @@ vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ CAezNIm8BZ/3Hobui3A= -----END CERTIFICATE----- -GLOBALTRUST 2020 -================ ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx -IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT -VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh -BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy -MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi -D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO -VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM -CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm -fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA -A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR -JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG -DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU -clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ -mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud -IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw -4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 -iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS -8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 -HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS -vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 -oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF -YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl -gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------END CERTIFICATE----- - ANF Secure Server Root CA ========================= -----BEGIN CERTIFICATE----- @@ -3579,3 +3551,116 @@ wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0 o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A= -----END CERTIFICATE----- + +FIRMAPROFESIONAL CA ROOT-A WEB +============================== +-----BEGIN CERTIFICATE----- +MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF +UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4 +MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2 +WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h +bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM +IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6 +iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg +st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD +Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB +/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL +cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ +pYXFuXqUPoeovQA= +-----END CERTIFICATE----- + +TWCA CYBER Root CA +================== +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s +Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh +V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT +o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT +Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK +/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH +IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM +fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF +2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR +wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83 +QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN +c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x +X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR +IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq +/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R +FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe +Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv +It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl +IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +SecureSign Root CA12 +==================== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3 +emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mtp7JIKwcc +J/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zdJ1M3s6oYwlkm7Fsf0uZl +fO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gurFzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBF +EaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1Uef +NzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOC +AQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQi +LUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpce +mik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPS +vWKErI4cqc1avTc7bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhga +aaI5gdka9at/yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +SecureSign Root CA14 +==================== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh +1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn +bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb +1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa +/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE +kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx +jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz +ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0 +dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY +AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq +YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA +ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds +Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG +FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q +nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/ +OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa +OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO +pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN +eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S +-----END CERTIFICATE----- + +SecureSign Root CA15 +==================== +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE +BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1 +cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV +BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj +dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G +dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB +2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J +fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ +SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- diff --git a/thirdparty/mbedtls/library/bignum_mod.c b/thirdparty/mbedtls/library/bignum_mod.c deleted file mode 100644 index dfd332a703..0000000000 --- a/thirdparty/mbedtls/library/bignum_mod.c +++ /dev/null @@ -1,394 +0,0 @@ -/** - * Modular bignum functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT) - -#include <string.h> - -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/bignum.h" - -#include "mbedtls/platform.h" - -#include "bignum_core.h" -#include "bignum_mod.h" -#include "bignum_mod_raw.h" -#include "constant_time_internal.h" - -int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *p, - size_t p_limbs) -{ - if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - r->limbs = N->limbs; - r->p = p; - - return 0; -} - -void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r) -{ - if (r == NULL) { - return; - } - - r->limbs = 0; - r->p = NULL; -} - -void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N) -{ - if (N == NULL) { - return; - } - - N->p = NULL; - N->limbs = 0; - N->bits = 0; - N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID; -} - -void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N) -{ - if (N == NULL) { - return; - } - - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - if (N->rep.mont.rr != NULL) { - mbedtls_zeroize_and_free((mbedtls_mpi_uint *) N->rep.mont.rr, - N->limbs * sizeof(mbedtls_mpi_uint)); - N->rep.mont.rr = NULL; - } - N->rep.mont.mm = 0; - break; - case MBEDTLS_MPI_MOD_REP_OPT_RED: - N->rep.ored.modp = NULL; - break; - case MBEDTLS_MPI_MOD_REP_INVALID: - break; - } - - N->p = NULL; - N->limbs = 0; - N->bits = 0; - N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID; -} - -static int set_mont_const_square(const mbedtls_mpi_uint **X, - const mbedtls_mpi_uint *A, - size_t limbs) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi N; - mbedtls_mpi RR; - *X = NULL; - - mbedtls_mpi_init(&N); - mbedtls_mpi_init(&RR); - - if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) { - goto cleanup; - } - - if (mbedtls_mpi_grow(&N, limbs)) { - goto cleanup; - } - - memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs); - - ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N); - - if (ret == 0) { - *X = RR.p; - RR.p = NULL; - } - -cleanup: - mbedtls_mpi_free(&N); - mbedtls_mpi_free(&RR); - ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0; - return ret; -} - -static inline void standard_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs, - mbedtls_mpi_mod_rep_selector int_rep) -{ - N->p = p; - N->limbs = p_limbs; - N->bits = mbedtls_mpi_core_bitlen(p, p_limbs); - N->int_rep = int_rep; -} - -int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs) -{ - int ret = 0; - standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_MONTGOMERY); - N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p); - ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs); - - if (ret != 0) { - mbedtls_mpi_mod_modulus_free(N); - } - - return ret; -} - -int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs, - mbedtls_mpi_modp_fn modp) -{ - standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_OPT_RED); - N->rep.ored.modp = modp; - return 0; -} - -int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N) -{ - if (N->limbs == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL); - if (T == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T); - - mbedtls_free(T); - - return 0; -} - -int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N) -{ - if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N); - - return 0; -} - -static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *working_memory) -{ - /* Input already in Montgomery form, so there's little to do */ - mbedtls_mpi_mod_raw_inv_prime(X->p, A->p, - N->p, N->limbs, - N->rep.mont.rr, - working_memory); - return 0; -} - -static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *working_memory) -{ - /* Need to convert input into Montgomery form */ - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_mpi_mod_modulus Nmont; - mbedtls_mpi_mod_modulus_init(&Nmont); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs)); - - /* We'll use X->p to hold the Montgomery form of the input A->p */ - mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs, - Nmont.rep.mont.mm, Nmont.rep.mont.rr, - working_memory); - - mbedtls_mpi_mod_raw_inv_prime(X->p, X->p, - Nmont.p, Nmont.limbs, - Nmont.rep.mont.rr, - working_memory); - - /* And convert back from Montgomery form */ - - mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs, - Nmont.rep.mont.mm, working_memory); - -cleanup: - mbedtls_mpi_mod_modulus_free(&Nmont); - return ret; -} - -int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N) -{ - if (X->limbs != N->limbs || A->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* Zero has the same value regardless of Montgomery form or not */ - if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - size_t working_limbs = - mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs); - - mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs, - sizeof(mbedtls_mpi_uint)); - if (working_memory == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory); - break; - case MBEDTLS_MPI_MOD_REP_OPT_RED: - ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory); - break; - default: - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - break; - } - - mbedtls_zeroize_and_free(working_memory, - working_limbs * sizeof(mbedtls_mpi_uint)); - - return ret; -} - -int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N) -{ - if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N); - - return 0; -} - -int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_mod_modulus *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - if (X->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng); -} - -int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - const unsigned char *buf, - size_t buflen, - mbedtls_mpi_mod_ext_rep ext_rep) -{ - int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - - /* Do our best to check if r and m have been set up */ - if (r->limbs == 0 || N->limbs == 0) { - goto cleanup; - } - if (r->limbs != N->limbs) { - goto cleanup; - } - - ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep); - if (ret != 0) { - goto cleanup; - } - - r->limbs = N->limbs; - - ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N); - -cleanup: - return ret; -} - -int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - unsigned char *buf, - size_t buflen, - mbedtls_mpi_mod_ext_rep ext_rep) -{ - /* Do our best to check if r and m have been set up */ - if (r->limbs == 0 || N->limbs == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - if (r->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi_uint *working_memory = r->p; - size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs; - - if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { - - working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint)); - - if (working_memory == NULL) { - ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; - goto cleanup; - } - - memcpy(working_memory, r->p, working_memory_len); - - ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N); - if (ret != 0) { - goto cleanup; - } - } - - ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep); - -cleanup: - - if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY && - working_memory != NULL) { - - mbedtls_zeroize_and_free(working_memory, working_memory_len); - } - - return ret; -} - -#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/thirdparty/mbedtls/library/block_cipher.c b/thirdparty/mbedtls/library/block_cipher.c deleted file mode 100644 index 51cdcdf46b..0000000000 --- a/thirdparty/mbedtls/library/block_cipher.c +++ /dev/null @@ -1,207 +0,0 @@ -/** - * \file block_cipher.c - * - * \brief Lightweight abstraction layer for block ciphers with 128 bit blocks, - * for use by the GCM and CCM modules. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -#include "psa/crypto.h" -#include "psa_crypto_core.h" -#include "psa_util_internal.h" -#endif - -#include "block_cipher_internal.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id) -{ - switch (cipher_id) { -#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - return PSA_KEY_TYPE_AES; -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - return PSA_KEY_TYPE_ARIA; -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - return PSA_KEY_TYPE_CAMELLIA; -#endif - default: - return PSA_KEY_TYPE_NONE; - } -} - -static int mbedtls_cipher_error_from_psa(psa_status_t status) -{ - return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors, - psa_generic_status_to_mbedtls); -} -#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ - -void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { - psa_destroy_key(ctx->psa_key_id); - return; - } -#endif - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - mbedtls_aes_free(&ctx->ctx.aes); - break; -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - mbedtls_aria_free(&ctx->ctx.aria); - break; -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - mbedtls_camellia_free(&ctx->ctx.camellia); - break; -#endif - default: - break; - } - ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; -} - -int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, - mbedtls_cipher_id_t cipher_id) -{ - ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES : - (cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA : - (cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA : - MBEDTLS_BLOCK_CIPHER_ID_NONE; - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id); - if (psa_key_type != PSA_KEY_TYPE_NONE && - psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) { - ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA; - return 0; - } - ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY; -#endif - - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - mbedtls_aes_init(&ctx->ctx.aes); - return 0; -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - mbedtls_aria_init(&ctx->ctx.aria); - return 0; -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - mbedtls_camellia_init(&ctx->ctx.camellia); - return 0; -#endif - default: - ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } -} - -int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, - const unsigned char *key, - unsigned key_bitlen) -{ -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; - - psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id)); - psa_set_key_bits(&key_attr, key_bitlen); - psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT); - - status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id); - if (status != PSA_SUCCESS) { - return mbedtls_cipher_error_from_psa(status); - } - psa_reset_key_attributes(&key_attr); - - return 0; - } -#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ - - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen); -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen); -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen); -#endif - default: - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } -} - -int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, - const unsigned char input[16], - unsigned char output[16]) -{ -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { - psa_status_t status; - size_t olen; - - status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING, - input, 16, output, 16, &olen); - if (status != PSA_SUCCESS) { - return mbedtls_cipher_error_from_psa(status); - } - return 0; - } -#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ - - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT, - input, output); -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output); -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia, - MBEDTLS_CAMELLIA_ENCRYPT, - input, output); -#endif - default: - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } -} - -#endif /* MBEDTLS_BLOCK_CIPHER_C */ diff --git a/thirdparty/mbedtls/library/ecp_curves_new.c b/thirdparty/mbedtls/library/ecp_curves_new.c deleted file mode 100644 index 035b23a1b4..0000000000 --- a/thirdparty/mbedtls/library/ecp_curves_new.c +++ /dev/null @@ -1,6036 +0,0 @@ -/* - * Elliptic curves over GF(p): curve-specific data and functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_ECP_WITH_MPI_UINT) - -#if defined(MBEDTLS_ECP_LIGHT) - -#include "mbedtls/ecp.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include "mbedtls/platform.h" - -#include "constant_time_internal.h" - -#include "bn_mul.h" -#include "bignum_core.h" -#include "ecp_invasive.h" - -#include <string.h> - -#if !defined(MBEDTLS_ECP_ALT) - -#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } - -#define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) - -#define ECP_POINT_INIT_XY_Z0(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(NULL, 0) } -#define ECP_POINT_INIT_XY_Z1(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(mpi_one, 1) } - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* For these curves, we build the group parameters dynamically. */ -#define ECP_LOAD_GROUP -static mbedtls_mpi_uint mpi_one[] = { 1 }; -#endif - -/* - * Note: the constants are in little-endian order - * to be directly usable in MPIs - */ - -/* - * Domain parameters for secp192r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static const mbedtls_mpi_uint secp192r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp192r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64), -}; -static const mbedtls_mpi_uint secp192r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), -}; -static const mbedtls_mpi_uint secp192r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), -}; -static const mbedtls_mpi_uint secp192r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp192r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), -}; -static const mbedtls_mpi_uint secp192r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), -}; -static const mbedtls_mpi_uint secp192r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x9E, 0xE3, 0x60, 0x59, 0xD1, 0xC4, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBD, 0x22, 0xD7, 0x2D, 0x07, 0xBD, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x2A, 0xCF, 0x33, 0xF0, 0xBE, 0xD1, 0xED), -}; -static const mbedtls_mpi_uint secp192r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x71, 0x4B, 0xA8, 0xED, 0x7E, 0xC9, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x2A, 0xF6, 0xDF, 0x0E, 0xE8, 0x4C, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x35, 0xF7, 0x8A, 0xC3, 0xEC, 0xDE, 0x1E), -}; -static const mbedtls_mpi_uint secp192r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0xC2, 0x1D, 0x32, 0x8F, 0x10, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x2D, 0x17, 0xF3, 0xE4, 0xFE, 0xD8, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x45, 0x10, 0x70, 0x2C, 0x3E, 0x52, 0x3E), -}; -static const mbedtls_mpi_uint secp192r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF1, 0x04, 0x5D, 0xEE, 0xD4, 0x56, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xB7, 0x38, 0x27, 0x61, 0xAA, 0x81, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0xD7, 0x0E, 0x29, 0x0E, 0x11, 0x14), -}; -static const mbedtls_mpi_uint secp192r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x35, 0x52, 0xC6, 0x31, 0xB7, 0x27, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xD4, 0x15, 0x98, 0x0F, 0xE7, 0xF3, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x31, 0x70, 0x35, 0x09, 0xA0, 0x2B, 0xC2), -}; -static const mbedtls_mpi_uint secp192r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x75, 0xA7, 0x4C, 0x88, 0xCF, 0x5B, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x17, 0x48, 0x8D, 0xF2, 0xF0, 0x86, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCF, 0xFE, 0x6B, 0xB0, 0xA5, 0x06, 0xAB), -}; -static const mbedtls_mpi_uint secp192r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x6A, 0xDC, 0x9A, 0x6D, 0x7B, 0x47, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xFC, 0x51, 0x12, 0x62, 0x66, 0x0B, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x40, 0x93, 0xA0, 0xB5, 0x5A, 0x58, 0xD7), -}; -static const mbedtls_mpi_uint secp192r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCB, 0xAF, 0xDC, 0x0B, 0xA1, 0x26, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x36, 0x9D, 0xA3, 0xD7, 0x3B, 0xAD, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x3B, 0x05, 0x9A, 0xA8, 0xAA, 0x69, 0xB2), -}; -static const mbedtls_mpi_uint secp192r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD9, 0xD1, 0x4D, 0x4A, 0x6E, 0x96, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x66, 0x32, 0x39, 0xC6, 0x57, 0x7D, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xA0, 0x36, 0xC2, 0x45, 0xF9, 0x00, 0x62), -}; -static const mbedtls_mpi_uint secp192r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xEF, 0x59, 0x46, 0xDC, 0x60, 0xD9, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xB0, 0xE9, 0x41, 0xA4, 0x87, 0x76, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xD4, 0x0E, 0xB2, 0xFA, 0x16, 0x56, 0xDC), -}; -static const mbedtls_mpi_uint secp192r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x62, 0xD2, 0xB1, 0x34, 0xB2, 0xF1, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xED, 0x55, 0xC5, 0x47, 0xB5, 0x07, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF6, 0x2F, 0x94, 0xC3, 0xDD, 0x54, 0x2F), -}; -static const mbedtls_mpi_uint secp192r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xA6, 0xD4, 0x8C, 0xA9, 0xCE, 0x4D, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x4B, 0x46, 0xCC, 0xB2, 0x55, 0xC8, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x31, 0xED, 0x89, 0x65, 0x59, 0x55), -}; -static const mbedtls_mpi_uint secp192r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x0A, 0xD1, 0x1A, 0xC5, 0xF6, 0xEA, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xFC, 0x0C, 0x1A, 0xFB, 0xA0, 0xC8, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xFD, 0x53, 0x6F, 0x6D, 0xBF, 0xBA, 0xAF), -}; -static const mbedtls_mpi_uint secp192r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xB0, 0x7D, 0x83, 0x96, 0xE3, 0xCB, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x6E, 0x55, 0x2C, 0x20, 0x53, 0x2F, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x66, 0x00, 0x17, 0x08, 0xFE, 0xAC, 0x31), -}; -static const mbedtls_mpi_uint secp192r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x12, 0x97, 0x3A, 0xC7, 0x57, 0x45, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x25, 0x99, 0x00, 0xF6, 0x97, 0xB4, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x74, 0xE6, 0xE6, 0xA3, 0xDF, 0x9C, 0xCC), -}; -static const mbedtls_mpi_uint secp192r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xF4, 0x76, 0xD5, 0x5F, 0x2A, 0xFD, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x80, 0x7E, 0x3E, 0xE5, 0xE8, 0xD6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xAD, 0x1E, 0x70, 0x79, 0x3E, 0x3D, 0x83), -}; -static const mbedtls_mpi_uint secp192r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x15, 0xBB, 0xB3, 0x42, 0x6A, 0xA1, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x58, 0xCB, 0x43, 0x25, 0x00, 0x14, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x4E, 0x93, 0x11, 0xE0, 0x32, 0x54, 0x98), -}; -static const mbedtls_mpi_uint secp192r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x52, 0xA2, 0xB4, 0x57, 0x32, 0xB9, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x43, 0xA1, 0xB1, 0xFB, 0x01, 0xE1, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xFB, 0x5A, 0x11, 0xB8, 0xC2, 0x03, 0xE5), -}; -static const mbedtls_mpi_uint secp192r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x2B, 0x71, 0x26, 0x4E, 0x7C, 0xC5, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF5, 0xD3, 0xA8, 0xE4, 0x95, 0x48, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAE, 0xD9, 0x5D, 0x9F, 0x6A, 0x22, 0xAD), -}; -static const mbedtls_mpi_uint secp192r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xCC, 0xA3, 0x4D, 0xA0, 0x1C, 0x34, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x3C, 0x62, 0xF8, 0x5E, 0xA6, 0x58, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x6E, 0x66, 0x8A, 0x3D, 0x17, 0xFF, 0x0F), -}; -static const mbedtls_mpi_uint secp192r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xCD, 0xA8, 0xDD, 0xD1, 0x20, 0x5C, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xFE, 0x17, 0xE2, 0xCF, 0xEA, 0x63, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x51, 0xC9, 0x16, 0xDE, 0xB4, 0xB2, 0xDD), -}; -static const mbedtls_mpi_uint secp192r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBE, 0x12, 0xD7, 0xA3, 0x0A, 0x50, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x87, 0xC5, 0x8A, 0x76, 0x57, 0x07, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x1F, 0xC6, 0x1B, 0x66, 0xC4, 0x3D, 0x8A), -}; -static const mbedtls_mpi_uint secp192r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xA4, 0x85, 0x13, 0x8F, 0xA7, 0x35, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x0D, 0xFD, 0xFF, 0x1B, 0xD1, 0xD6, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x7A, 0xD0, 0xC3, 0xB4, 0xEF, 0x39, 0x66), -}; -static const mbedtls_mpi_uint secp192r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xFE, 0xA5, 0x9C, 0x34, 0x30, 0x49, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xC5, 0x39, 0x26, 0x06, 0xE3, 0x01, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x2B, 0x66, 0xFC, 0x95, 0x5F, 0x35, 0xF7), -}; -static const mbedtls_mpi_uint secp192r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xCF, 0x54, 0x63, 0x99, 0x57, 0x05, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x6F, 0x00, 0x5F, 0x65, 0x08, 0x47, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x2A, 0x90, 0x6D, 0x67, 0xC6, 0xBC, 0x45), -}; -static const mbedtls_mpi_uint secp192r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x4D, 0x88, 0x0A, 0x35, 0x9E, 0x33, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x17, 0x0C, 0xF8, 0xE1, 0x7A, 0x49, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x44, 0x06, 0x8F, 0x0B, 0x70, 0x2F, 0x71), -}; -static const mbedtls_mpi_uint secp192r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4B, 0xCB, 0xF9, 0x8E, 0x6A, 0xDA, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x43, 0xA1, 0x3F, 0xCE, 0x17, 0xD2, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x0D, 0xD2, 0x6C, 0x82, 0x37, 0xE5, 0xFC), -}; -static const mbedtls_mpi_uint secp192r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x3C, 0xF4, 0x92, 0xB4, 0x8A, 0x95, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x96, 0xF1, 0x0A, 0x34, 0x2F, 0x74, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0xAA, 0xBA, 0x86, 0x77, 0x4F, 0xA2), -}; -static const mbedtls_mpi_uint secp192r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x7F, 0xEF, 0x60, 0x50, 0x80, 0xD7, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xAC, 0xC9, 0xFE, 0xEC, 0x0A, 0x1A, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x2F, 0xBE, 0x91, 0xD7, 0xB7, 0x38, 0x48), -}; -static const mbedtls_mpi_uint secp192r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xAE, 0x85, 0x98, 0xFE, 0x05, 0x7F, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBE, 0xFD, 0x11, 0x31, 0x3D, 0x14, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x75, 0xE8, 0x30, 0x01, 0xCB, 0x9B, 0x1C), -}; -static const mbedtls_ecp_point secp192r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp192r1_T_0_X, secp192r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_1_X, secp192r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_2_X, secp192r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_3_X, secp192r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_4_X, secp192r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_5_X, secp192r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_6_X, secp192r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_7_X, secp192r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_8_X, secp192r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_9_X, secp192r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_10_X, secp192r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_11_X, secp192r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_12_X, secp192r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_13_X, secp192r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_14_X, secp192r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_15_X, secp192r1_T_15_Y), -}; -#else -#define secp192r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -/* - * Domain parameters for secp224r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static const mbedtls_mpi_uint secp224r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_4(0x85, 0x0A, 0x05, 0xB4), -}; -static const mbedtls_mpi_uint secp224r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_4(0xBD, 0x0C, 0x0E, 0xB7), -}; -static const mbedtls_mpi_uint secp224r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_4(0x88, 0x63, 0x37, 0xBD), -}; -static const mbedtls_mpi_uint secp224r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp224r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x0C, 0x0E, 0xB7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x63, 0x37, 0xBD, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF9, 0xB8, 0xD0, 0x3D, 0xD2, 0xD3, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xFD, 0x99, 0x26, 0x19, 0xFE, 0x13, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x0E, 0x4C, 0x48, 0x7C, 0xA2, 0x17, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA3, 0x13, 0x57, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x16, 0x5C, 0x8F, 0xAA, 0xED, 0x0F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xC5, 0x43, 0x34, 0x93, 0x05, 0x2A, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE3, 0x6C, 0xCA, 0xC6, 0x14, 0xC2, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x43, 0x6C, 0xD7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x5A, 0x98, 0x1E, 0xC8, 0xA5, 0x42, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x49, 0x56, 0x78, 0xF8, 0xEF, 0xED, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xBB, 0x64, 0xB6, 0x4C, 0x54, 0x5F, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x0C, 0x33, 0xCC, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x79, 0xCB, 0x2E, 0x08, 0xFF, 0xD8, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x1F, 0xD4, 0xD7, 0x57, 0xE9, 0x39, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xD6, 0x3B, 0x0A, 0x1C, 0x87, 0xB7, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x30, 0xD8, 0x05, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x79, 0x74, 0x9A, 0xE6, 0xBB, 0xC2, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x5B, 0xA6, 0x67, 0xC1, 0x91, 0xE7, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xDF, 0x38, 0x82, 0x19, 0x2C, 0x4C, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x2E, 0x39, 0xC5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x36, 0x78, 0x4E, 0xAE, 0x5B, 0x02, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF6, 0x8B, 0xF8, 0xF4, 0x92, 0x6B, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x4D, 0x71, 0x35, 0xE7, 0x0C, 0x2C, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xA5, 0x1F, 0xAE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x1C, 0x4B, 0xDF, 0x5B, 0xF2, 0x51, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0xB1, 0x5A, 0xC6, 0x0F, 0x0E, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x24, 0x09, 0x62, 0xAF, 0xFC, 0xDB, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xE1, 0x80, 0x55, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x82, 0xFE, 0xAD, 0xC3, 0xE5, 0xCF, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xA2, 0x62, 0x17, 0x76, 0xF0, 0x5A, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB8, 0xE5, 0xAC, 0xB7, 0x66, 0x38, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xFD, 0x86, 0x05, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0x0C, 0x3C, 0xD1, 0x66, 0xB0, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x59, 0xB4, 0x8D, 0x90, 0x10, 0xB7, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x47, 0x9B, 0xE6, 0x55, 0x8A, 0xE4, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x49, 0xDB, 0x78, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x97, 0xED, 0xDE, 0xFF, 0xB3, 0xDF, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xB9, 0x83, 0xB7, 0xEB, 0xBE, 0x40, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xD3, 0xD3, 0xCD, 0x0E, 0x82, 0x79, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x83, 0x1B, 0xF0, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x22, 0xBB, 0x54, 0xD3, 0x31, 0x56, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0xE5, 0xE0, 0x89, 0x96, 0x8E, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xEF, 0x0A, 0xED, 0xD0, 0x11, 0x4A, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x00, 0x57, 0x27, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCA, 0x3D, 0xF7, 0x64, 0x9B, 0x6E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xE3, 0x70, 0x6B, 0x41, 0xD7, 0xED, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x44, 0x44, 0x80, 0xCE, 0x13, 0x37, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x73, 0x80, 0x79, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x4D, 0x70, 0x7D, 0x31, 0x0F, 0x1C, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x35, 0x88, 0x47, 0xC4, 0x24, 0x78, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF0, 0xCD, 0x91, 0x81, 0xB3, 0xDE, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xCE, 0xC6, 0xF7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x9C, 0x2D, 0xE8, 0xD2, 0x00, 0x8F, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x5E, 0x7C, 0x0E, 0x0C, 0x6E, 0x58, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x81, 0x21, 0xCE, 0x43, 0xF4, 0x24, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xBC, 0xF0, 0xF4, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x10, 0xC2, 0x74, 0x4A, 0x8F, 0x8A, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x67, 0xF4, 0x2B, 0x38, 0x2B, 0x35, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0C, 0xA9, 0xFA, 0x77, 0x5C, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x19, 0x2B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x3E, 0x96, 0x22, 0x53, 0xE1, 0xE9, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x13, 0xBC, 0xA1, 0x16, 0xEC, 0x01, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x00, 0xC9, 0x7A, 0xC3, 0x73, 0xA5, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xF4, 0x5E, 0xC1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x95, 0xD6, 0xD9, 0x32, 0x30, 0x2B, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x42, 0x09, 0x05, 0x61, 0x2A, 0x7E, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x84, 0xA2, 0x05, 0x88, 0x64, 0x65, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2D, 0x90, 0xB3, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE7, 0x2E, 0x85, 0x55, 0x80, 0x7C, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC1, 0xAC, 0x78, 0xB4, 0xAF, 0xFB, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xC3, 0x28, 0x8E, 0x79, 0x18, 0x1F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x46, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x5F, 0xA8, 0x6C, 0x46, 0x83, 0x43, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xA9, 0x93, 0x11, 0xB6, 0x07, 0x57, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x2A, 0x9D, 0x03, 0x89, 0x7E, 0xD7, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x8C, 0x62, 0xCF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x2C, 0x13, 0x59, 0xCC, 0xFA, 0x84, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB9, 0x48, 0xBC, 0x57, 0xC7, 0xB3, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x0A, 0x38, 0x24, 0x2E, 0x3A, 0x28, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x0A, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x25, 0xAB, 0xC1, 0xEE, 0x70, 0x3C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xDB, 0x45, 0x1D, 0x4A, 0x80, 0x75, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1F, 0x4D, 0x2D, 0x9A, 0x05, 0xF4, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x10, 0xF0, 0x5A, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x95, 0xE1, 0xDC, 0x15, 0x86, 0xC3, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xDC, 0x27, 0xD1, 0x56, 0xA1, 0x14, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x0B, 0xD6, 0x77, 0x4E, 0x44, 0xA2, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x42, 0x71, 0x1F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x86, 0xB2, 0xB0, 0xC8, 0x2F, 0x7B, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xEF, 0xCB, 0xDB, 0xBC, 0x9E, 0x3B, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x03, 0x86, 0xDD, 0x5B, 0xF5, 0x8D, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x95, 0x79, 0xD6, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x32, 0x14, 0xDA, 0x9B, 0x4F, 0x07, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x3E, 0xFB, 0x06, 0xEE, 0xA7, 0x40, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x1F, 0xDF, 0x71, 0x61, 0xFD, 0x8B, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x8B, 0xAB, 0x8B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x34, 0xB3, 0xB4, 0xBC, 0x9F, 0xB0, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x58, 0x48, 0xA8, 0x77, 0xBB, 0x13, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC6, 0xF7, 0x34, 0xCC, 0x89, 0x21, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x33, 0xDD, 0x1F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x81, 0xEF, 0xA4, 0xF2, 0x10, 0x0B, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF7, 0x6E, 0x72, 0x4A, 0xDF, 0xDD, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x23, 0x0A, 0x53, 0x03, 0x16, 0x62, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x76, 0xFD, 0x3C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x14, 0xA1, 0xFA, 0xA0, 0x18, 0xBE, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2A, 0xE1, 0xD7, 0xB0, 0x6C, 0xA0, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xC0, 0xB0, 0xC6, 0x63, 0x24, 0xCD, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x38, 0x2C, 0xB1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCD, 0x7D, 0x20, 0x0C, 0xFE, 0xAC, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x9F, 0xA2, 0xB6, 0x45, 0xF7, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x99, 0xF3, 0xD2, 0x20, 0x02, 0xEB, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x5B, 0x7B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xDD, 0x77, 0x91, 0x60, 0xEA, 0xFD, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xD3, 0xB5, 0xD6, 0x90, 0x17, 0x0E, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xF4, 0x28, 0xC1, 0xF2, 0x53, 0xF6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x58, 0xDC, 0x61, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x20, 0x01, 0xFB, 0xF1, 0xBD, 0x5F, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x7F, 0x06, 0xDA, 0x11, 0xCB, 0xBA, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x41, 0x00, 0xA4, 0x1B, 0x30, 0x33, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xFF, 0x27, 0xCA, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp224r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp224r1_T_0_X, secp224r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_1_X, secp224r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_2_X, secp224r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_3_X, secp224r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_4_X, secp224r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_5_X, secp224r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_6_X, secp224r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_7_X, secp224r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_8_X, secp224r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_9_X, secp224r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_10_X, secp224r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_11_X, secp224r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_12_X, secp224r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_13_X, secp224r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_14_X, secp224r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_15_X, secp224r1_T_15_Y), -}; -#else -#define secp224r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -/* - * Domain parameters for secp256r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static const mbedtls_mpi_uint secp256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A), -}; -static const mbedtls_mpi_uint secp256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), -}; -static const mbedtls_mpi_uint secp256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), -}; -static const mbedtls_mpi_uint secp256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp256r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), -}; -static const mbedtls_mpi_uint secp256r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), -}; -static const mbedtls_mpi_uint secp256r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xC8, 0xBA, 0x04, 0xB7, 0x4B, 0xD2, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC6, 0x23, 0x3A, 0xA0, 0x09, 0x3A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x9D, 0x4C, 0xF9, 0x58, 0x23, 0xCC, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xED, 0x7B, 0x29, 0x87, 0x0F, 0xFA, 0x3C), -}; -static const mbedtls_mpi_uint secp256r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x69, 0xF2, 0x40, 0x0B, 0xA3, 0x98, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xA8, 0x48, 0x02, 0x0D, 0x1C, 0x12, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xAF, 0x09, 0x83, 0x80, 0xAA, 0x58, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x12, 0xBE, 0x70, 0x94, 0x76, 0xE3, 0xE4), -}; -static const mbedtls_mpi_uint secp256r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x7D, 0xEF, 0x86, 0xFF, 0xE3, 0x37, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x86, 0x8B, 0x08, 0x27, 0x7C, 0xD7, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x54, 0x4C, 0x25, 0x4F, 0x9A, 0xFE, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xFD, 0xF0, 0x6D, 0x37, 0x03, 0x69, 0xD6), -}; -static const mbedtls_mpi_uint secp256r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xD5, 0xDA, 0xAD, 0x92, 0x49, 0xF0, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x73, 0x43, 0x9E, 0xAF, 0xA7, 0xD1, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x41, 0x07, 0xDF, 0x78, 0x95, 0x3E, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x3D, 0xD1, 0xE6, 0x3C, 0xA5, 0xE2, 0x20), -}; -static const mbedtls_mpi_uint secp256r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x6A, 0x5D, 0x52, 0x35, 0xD7, 0xBF, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xA2, 0xBE, 0x96, 0xF4, 0xF8, 0x02, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x20, 0x49, 0x54, 0xEA, 0xB3, 0x82, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0xDB, 0xEA, 0x02, 0xD1, 0x75, 0x1C, 0x62), -}; -static const mbedtls_mpi_uint secp256r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x85, 0xF4, 0x9E, 0x4C, 0xDC, 0x39, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x6D, 0xC4, 0x57, 0xD8, 0x03, 0x5D, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x7F, 0x2D, 0x52, 0x6F, 0xC9, 0xDA, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x64, 0xFA, 0xB4, 0xFE, 0xA4, 0xC4, 0xD7), -}; -static const mbedtls_mpi_uint secp256r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x37, 0xB9, 0xC0, 0xAA, 0x59, 0xC6, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x58, 0xD9, 0xED, 0x58, 0x99, 0x65, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x7D, 0x26, 0x8C, 0x4A, 0xF9, 0x05, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x73, 0x9A, 0xC9, 0xE7, 0x46, 0xDC, 0x00), -}; -static const mbedtls_mpi_uint secp256r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xD0, 0x55, 0xDF, 0x00, 0x0A, 0xF5, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xBF, 0x56, 0x81, 0x2D, 0x20, 0xEB, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC1, 0x28, 0x52, 0xAB, 0xE3, 0xD1, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x34, 0x79, 0x45, 0x57, 0xA5, 0x12, 0x03), -}; -static const mbedtls_mpi_uint secp256r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCF, 0xB8, 0x7E, 0xF7, 0x92, 0x96, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x01, 0x8C, 0x0D, 0x23, 0xF2, 0xE3, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x2E, 0xE3, 0x84, 0x52, 0x7A, 0x34, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xA1, 0xB0, 0x15, 0x90, 0xE2, 0x53, 0x3C), -}; -static const mbedtls_mpi_uint secp256r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x98, 0xE7, 0xFA, 0xA5, 0x7D, 0x8B, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x35, 0xD2, 0x00, 0xD1, 0x1B, 0x9F, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x69, 0x08, 0x9A, 0x72, 0xF0, 0xA9, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xFE, 0x0E, 0x14, 0xDA, 0x7C, 0x0E, 0xD3), -}; -static const mbedtls_mpi_uint secp256r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF6, 0xE8, 0xF8, 0x87, 0xF7, 0xFC, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xBE, 0x7F, 0x3F, 0x7A, 0x2B, 0xD7, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x32, 0xF2, 0x2D, 0x94, 0x6D, 0x42, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x9A, 0xE3, 0x5F, 0x42, 0xBB, 0x84, 0xED), -}; -static const mbedtls_mpi_uint secp256r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x95, 0x29, 0x73, 0xA1, 0x67, 0x3E, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x30, 0x54, 0x35, 0x8E, 0x0A, 0xDD, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xD7, 0xA1, 0x97, 0x61, 0x3B, 0xF8, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x33, 0x3C, 0x58, 0x55, 0x34, 0x23, 0xA3), -}; -static const mbedtls_mpi_uint secp256r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x5D, 0x16, 0x5F, 0x7B, 0xBC, 0xBB, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xEE, 0x4E, 0x8A, 0xC1, 0x51, 0xCC, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0D, 0x4D, 0x1B, 0x53, 0x23, 0x1D, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x2A, 0x38, 0x66, 0x52, 0x84, 0xE1, 0x95), -}; -static const mbedtls_mpi_uint secp256r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x9B, 0x83, 0x0A, 0x81, 0x4F, 0xAD, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xFF, 0x42, 0x41, 0x6E, 0xA9, 0xA2, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA1, 0x4F, 0x1F, 0x89, 0x82, 0xAA, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xB8, 0x0F, 0x6B, 0x8F, 0x8C, 0xD6, 0x68), -}; -static const mbedtls_mpi_uint secp256r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0xB3, 0xBB, 0x51, 0x69, 0xA2, 0x11, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x4F, 0x0F, 0x8D, 0xBD, 0x26, 0x0F, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xCB, 0xEC, 0x6B, 0x34, 0xC3, 0x3D, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x5D, 0x1E, 0x10, 0xD5, 0x44, 0xE2, 0x54), -}; -static const mbedtls_mpi_uint secp256r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x9E, 0xB1, 0xF1, 0x6E, 0x4C, 0xAD, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE3, 0xC2, 0x58, 0xC0, 0xFB, 0x34, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x9C, 0xDF, 0x35, 0x07, 0x41, 0xBD, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x10, 0xEC, 0x0E, 0xEC, 0xBB, 0xD6), -}; -static const mbedtls_mpi_uint secp256r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xCF, 0xEF, 0x3F, 0x83, 0x1A, 0x88, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x29, 0xB5, 0xB9, 0xE0, 0xC9, 0xA3, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x46, 0x1E, 0x77, 0xCD, 0x7E, 0xB3, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x21, 0xD0, 0xD4, 0xA3, 0x16, 0x08, 0xEE), -}; -static const mbedtls_mpi_uint secp256r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xCA, 0xA8, 0xB3, 0xBF, 0x29, 0x99, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF2, 0x05, 0xC1, 0xCF, 0x5D, 0x91, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x01, 0x49, 0xDB, 0x82, 0xDF, 0x5F, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x06, 0x90, 0xAD, 0xE3, 0x38, 0xA4, 0xC4), -}; -static const mbedtls_mpi_uint secp256r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xD2, 0x3A, 0xE8, 0x03, 0xC5, 0x6D, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x35, 0xD0, 0xAE, 0x1D, 0x7A, 0x9F, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x1E, 0xD2, 0xCB, 0xAC, 0x88, 0x27, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x9C, 0xE0, 0x31, 0xDD, 0x99, 0x86), -}; -static const mbedtls_mpi_uint secp256r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF9, 0x9B, 0x32, 0x96, 0x41, 0x58, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x5A, 0x2A, 0xB8, 0x96, 0x0E, 0xB2, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x78, 0x2C, 0xC7, 0x08, 0x99, 0x19, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x59, 0x28, 0xE9, 0x84, 0x54, 0xE6, 0x16), -}; -static const mbedtls_mpi_uint secp256r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x38, 0x30, 0xDB, 0x70, 0x2C, 0x0A, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x5C, 0x9D, 0xE9, 0xD5, 0x46, 0x0B, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x0B, 0x60, 0x4B, 0x37, 0x7D, 0xB9, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x24, 0xF3, 0x3D, 0x79, 0x7F, 0x6C, 0x18), -}; -static const mbedtls_mpi_uint secp256r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7F, 0xE5, 0x1C, 0x4F, 0x60, 0x24, 0xF7, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xD8, 0xE2, 0x91, 0x7F, 0x89, 0x49, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xA7, 0x2E, 0x8D, 0x6A, 0xB3, 0x39, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x89, 0xB5, 0x9A, 0xB8, 0x8D, 0x42, 0x9C), -}; -static const mbedtls_mpi_uint secp256r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x45, 0xE6, 0x4B, 0x3F, 0x4F, 0x1E, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x65, 0x5E, 0x59, 0x22, 0xCC, 0x72, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x93, 0x1A, 0x27, 0x1E, 0x34, 0xC5, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xF2, 0xA5, 0x58, 0x5C, 0x15, 0x2E, 0xC6), -}; -static const mbedtls_mpi_uint secp256r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x7F, 0xBA, 0x58, 0x5A, 0x84, 0x6F, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA6, 0x36, 0x7E, 0xDC, 0xF7, 0xE1, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x4D, 0xAA, 0xEE, 0x57, 0x76, 0x3A, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x7E, 0x26, 0x18, 0x22, 0x23, 0x9F, 0xFF), -}; -static const mbedtls_mpi_uint secp256r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x4C, 0x64, 0xC7, 0x55, 0x02, 0x3F, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x02, 0x90, 0xBB, 0xC3, 0xEC, 0x30, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x6F, 0x64, 0xF4, 0x16, 0x69, 0x48, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x44, 0x9C, 0x95, 0x0C, 0x7D, 0x67, 0x5E), -}; -static const mbedtls_mpi_uint secp256r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x91, 0x8B, 0xD8, 0xD0, 0xD7, 0xE7, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF9, 0x48, 0x62, 0x6F, 0xA8, 0x93, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x3A, 0x99, 0x02, 0xD5, 0x0B, 0x3D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xD3, 0x00, 0x31, 0xE6, 0x0C, 0x9F, 0x44), -}; -static const mbedtls_mpi_uint secp256r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xB2, 0xAA, 0xFD, 0x88, 0x15, 0xDF, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0x35, 0x27, 0x31, 0x44, 0xCD, 0xC0, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xF8, 0x91, 0xA5, 0x71, 0x94, 0x84, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xCB, 0xD0, 0x93, 0xE9, 0x88, 0xDA, 0xE4), -}; -static const mbedtls_mpi_uint secp256r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC6, 0x39, 0x16, 0x5D, 0xA3, 0x1E, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x07, 0x37, 0x26, 0x36, 0x2A, 0xFE, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xBC, 0xF3, 0xD0, 0xDE, 0x50, 0xFC, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x2E, 0x06, 0x10, 0x15, 0x4D, 0xFA, 0xF7), -}; -static const mbedtls_mpi_uint secp256r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x65, 0x69, 0x5B, 0x66, 0xA2, 0x75, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x16, 0x00, 0x5A, 0xB0, 0x30, 0x25, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xFB, 0x86, 0x42, 0x80, 0xC1, 0xC4, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x1D, 0x83, 0x8E, 0x94, 0x01, 0x5F, 0x82), -}; -static const mbedtls_mpi_uint secp256r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x37, 0x70, 0xEF, 0x1F, 0xA1, 0xF0, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x5B, 0xCE, 0xC4, 0x9B, 0x6F, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x11, 0x11, 0x24, 0x4F, 0x4C, 0x79, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x3A, 0x72, 0xBC, 0xFE, 0x72, 0x58, 0x43), -}; -static const mbedtls_ecp_point secp256r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp256r1_T_0_X, secp256r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_1_X, secp256r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_2_X, secp256r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_3_X, secp256r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_4_X, secp256r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_5_X, secp256r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_6_X, secp256r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_7_X, secp256r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_8_X, secp256r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_9_X, secp256r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_10_X, secp256r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_11_X, secp256r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_12_X, secp256r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_13_X, secp256r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_14_X, secp256r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_15_X, secp256r1_T_15_Y), -}; -#else -#define secp256r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -/* - * Domain parameters for secp384r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static const mbedtls_mpi_uint secp384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3), -}; -static const mbedtls_mpi_uint secp384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), -}; -static const mbedtls_mpi_uint secp384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp384r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), -}; -static const mbedtls_mpi_uint secp384r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x92, 0x00, 0x2C, 0x78, 0xDB, 0x1F, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF3, 0xEB, 0xB7, 0x06, 0xF7, 0xB6, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBC, 0x2C, 0xCF, 0xD8, 0xED, 0x53, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x75, 0x7B, 0xA3, 0xAB, 0xC3, 0x2C, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x9D, 0x78, 0x41, 0xF6, 0x76, 0x84, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x56, 0xE8, 0x52, 0xB3, 0xCB, 0xA8, 0xBD), -}; -static const mbedtls_mpi_uint secp384r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xF2, 0xAE, 0xA4, 0xB6, 0x89, 0x1B, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0xCE, 0x1C, 0x7C, 0xF6, 0x50, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xEB, 0x90, 0xE6, 0x4D, 0xC7, 0xD4, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x49, 0x2D, 0x8A, 0x01, 0x99, 0x60, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x80, 0x9B, 0x9B, 0x6A, 0xB0, 0x07, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xA2, 0xEE, 0x59, 0xBE, 0x95, 0xBC, 0x23), -}; -static const mbedtls_mpi_uint secp384r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x9D, 0x56, 0xAE, 0x59, 0xFB, 0x1F, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xAC, 0x91, 0x80, 0x87, 0xA8, 0x6E, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x08, 0xA7, 0x08, 0x94, 0x32, 0xFC, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x29, 0x9E, 0x84, 0xF4, 0xE5, 0x6E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x21, 0xB9, 0x50, 0x24, 0xF8, 0x9C, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x04, 0x01, 0xC2, 0xFB, 0x77, 0x3E, 0xDE), -}; -static const mbedtls_mpi_uint secp384r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x38, 0xEE, 0xE3, 0xC7, 0x9D, 0xEC, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x88, 0xCF, 0x43, 0xFA, 0x92, 0x5E, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xCA, 0x43, 0xF8, 0x3B, 0x49, 0x7E, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xE7, 0xEB, 0x17, 0x45, 0x86, 0xC2, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x69, 0x57, 0x32, 0xE0, 0x9C, 0xD1, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x10, 0xB8, 0x4D, 0xB8, 0xF4, 0x0D, 0xE3), -}; -static const mbedtls_mpi_uint secp384r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0xDC, 0x9A, 0xB2, 0x79, 0x39, 0x27, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x71, 0xE4, 0x3B, 0x4D, 0x60, 0x0C, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xBD, 0x19, 0x40, 0xFA, 0x19, 0x2A, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xF8, 0x1E, 0x43, 0xA1, 0x50, 0x8D, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x18, 0x7C, 0x41, 0xFA, 0x7C, 0x1B, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x24, 0xC4, 0xE9, 0xB7, 0xD3, 0xAD), -}; -static const mbedtls_mpi_uint secp384r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x01, 0x3D, 0x63, 0x54, 0x45, 0x6F, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xB2, 0x19, 0xA3, 0x86, 0x1D, 0x42, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x02, 0x87, 0x18, 0x92, 0x52, 0x1A, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x18, 0xB1, 0x5D, 0x18, 0x1B, 0x37, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x74, 0x61, 0xBA, 0x18, 0xAF, 0x40, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7D, 0x3C, 0x52, 0x0F, 0x07, 0xB0, 0x6F), -}; -static const mbedtls_mpi_uint secp384r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x39, 0x13, 0xAA, 0x60, 0x15, 0x99, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x00, 0xCB, 0xC6, 0xB1, 0xDB, 0x97, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xFA, 0x60, 0xB8, 0x24, 0xE4, 0x7D, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x75, 0xB3, 0x70, 0xB2, 0x83, 0xB1, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xE3, 0x6C, 0xCD, 0x33, 0x62, 0x7A, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x30, 0xDC, 0x0F, 0x9F, 0xBB, 0xB8, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD5, 0x0A, 0x60, 0x81, 0xB9, 0xC5, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xAA, 0x2F, 0xD6, 0xF2, 0x73, 0xDF, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x7B, 0x74, 0xC9, 0xB3, 0x5B, 0x95, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x04, 0xEB, 0x15, 0xC8, 0x5F, 0x00, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x50, 0x20, 0x28, 0xD1, 0x01, 0xAF, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x4F, 0x31, 0x81, 0x2F, 0x94, 0x48), -}; -static const mbedtls_mpi_uint secp384r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2F, 0xD8, 0xB6, 0x63, 0x7C, 0xE9, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x8C, 0xB9, 0x14, 0xD9, 0x37, 0x63, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x02, 0xB8, 0x46, 0xAD, 0xCE, 0x7B, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x47, 0x2D, 0x66, 0xA7, 0xE9, 0x33, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF9, 0x93, 0x94, 0xA8, 0x48, 0xB3, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x4A, 0xAC, 0x51, 0x08, 0x72, 0x2F, 0x1A), -}; -static const mbedtls_mpi_uint secp384r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xAD, 0xA0, 0xF9, 0x81, 0xE1, 0x78, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9A, 0x63, 0xD8, 0xBA, 0x79, 0x1A, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x31, 0x7B, 0x7A, 0x5A, 0x5D, 0x7D, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x96, 0x12, 0x4B, 0x19, 0x09, 0xE0, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8A, 0x57, 0xEE, 0x4E, 0x6E, 0x7E, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x9D, 0x69, 0xDC, 0xB3, 0xDA, 0xD8, 0x08), -}; -static const mbedtls_mpi_uint secp384r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x49, 0x03, 0x03, 0x33, 0x6F, 0x28, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xDB, 0xA7, 0x05, 0x8C, 0xF3, 0x4D, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x92, 0xB1, 0xA8, 0xEC, 0x0D, 0x64, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0xFC, 0xFD, 0xD0, 0x4B, 0x88, 0x1B, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x9C, 0x51, 0x69, 0xCE, 0x71, 0x73, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5A, 0x14, 0x23, 0x1A, 0x46, 0x63, 0x5F), -}; -static const mbedtls_mpi_uint secp384r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x4C, 0x70, 0x44, 0x18, 0xCD, 0xEF, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x49, 0xDD, 0x64, 0x7E, 0x7E, 0x4D, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x32, 0x7C, 0x09, 0xD0, 0x3F, 0xD6, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE0, 0x4F, 0x65, 0x0C, 0x7A, 0x54, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFA, 0xFB, 0x4A, 0xB4, 0x79, 0x5A, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x1B, 0x2B, 0xDA, 0xBC, 0x9A, 0x74), -}; -static const mbedtls_mpi_uint secp384r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xAC, 0x56, 0xF7, 0x5F, 0x51, 0x68, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xE0, 0x1D, 0xBC, 0x13, 0x4E, 0xAC, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF5, 0xC5, 0xE6, 0xD2, 0x88, 0xBA, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x0E, 0x28, 0x23, 0x58, 0x67, 0xFA, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x80, 0x4B, 0xD8, 0xC4, 0xDF, 0x15, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x0E, 0x58, 0xE6, 0x2C, 0x59, 0xC2, 0x03), -}; -static const mbedtls_mpi_uint secp384r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x26, 0x27, 0x99, 0x16, 0x2B, 0x22, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF3, 0x8F, 0xC3, 0x2A, 0x9B, 0xFC, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2E, 0x83, 0x3D, 0xFE, 0x9E, 0x3C, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0xCD, 0x2D, 0xC1, 0x49, 0x38, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x42, 0x8B, 0x33, 0x89, 0x1F, 0xEA, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x1D, 0x13, 0xD7, 0x50, 0xBB, 0x3E, 0xEB), -}; -static const mbedtls_mpi_uint secp384r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x9A, 0x52, 0xD2, 0x54, 0x7C, 0x97, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x6E, 0xED, 0xD9, 0x87, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x35, 0x7E, 0x16, 0x40, 0x15, 0x83, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x2B, 0xA4, 0xAB, 0x03, 0x91, 0xEA, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x47, 0x39, 0xEF, 0x05, 0x59, 0xD0, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x24, 0x0D, 0x76, 0x11, 0x53, 0x08, 0xAF), -}; -static const mbedtls_mpi_uint secp384r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x2F, 0xDD, 0xBD, 0x50, 0x48, 0xB1, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x1C, 0x84, 0x55, 0x78, 0x14, 0xEB, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x5E, 0x3E, 0xA6, 0xAF, 0xF6, 0xC7, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x11, 0xE2, 0x65, 0xCA, 0x41, 0x95, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x83, 0xD8, 0xE6, 0x4D, 0x22, 0x06, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x7F, 0x25, 0x2A, 0xAA, 0x28, 0x46, 0x97), -}; -static const mbedtls_mpi_uint secp384r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xDB, 0x15, 0x56, 0x84, 0xCB, 0xC0, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xDB, 0x0E, 0x08, 0xC9, 0xF5, 0xD4, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x62, 0xD0, 0x1A, 0x7C, 0x13, 0xD5, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xAD, 0x53, 0xE0, 0x32, 0x21, 0xA0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x38, 0x81, 0x21, 0x23, 0x0E, 0xD2, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x51, 0x05, 0xD0, 0x1E, 0x82, 0xA9, 0x71), -}; -static const mbedtls_mpi_uint secp384r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xC3, 0x27, 0xBF, 0xC6, 0xAA, 0xB7, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x65, 0x45, 0xDF, 0xB9, 0x46, 0x17, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x38, 0x3F, 0xB2, 0xB1, 0x5D, 0xCA, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x29, 0x6C, 0x63, 0xE9, 0xD7, 0x48, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xF1, 0xD7, 0x99, 0x8C, 0xC2, 0x05, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE6, 0x5E, 0x82, 0x6D, 0xE5, 0x7E, 0xD5), -}; -static const mbedtls_mpi_uint secp384r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x61, 0xFA, 0x7D, 0x01, 0xDB, 0xB6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC6, 0x58, 0x39, 0xF4, 0xC6, 0x82, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0x7A, 0x80, 0x08, 0xCD, 0xAA, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x8C, 0xC6, 0x3F, 0x3C, 0xA5, 0x68, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xF5, 0xD5, 0x17, 0xAE, 0x36, 0xD8, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xAD, 0x92, 0xC5, 0x57, 0x6C, 0xDA, 0x91), -}; -static const mbedtls_mpi_uint secp384r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x67, 0x17, 0xC0, 0x40, 0x78, 0x8C, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x9F, 0xF4, 0xAA, 0xDA, 0x5C, 0x7E, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xDB, 0x42, 0x3E, 0x72, 0x64, 0xA0, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xF9, 0x41, 0x17, 0x43, 0xE3, 0xE8, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xDD, 0xCC, 0x43, 0x7E, 0x16, 0x05, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x4B, 0xCF, 0x48, 0x8F, 0x41, 0x90, 0xE5), -}; -static const mbedtls_mpi_uint secp384r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x0C, 0x6B, 0x9D, 0x22, 0x04, 0xBC, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x63, 0x79, 0x2F, 0x6A, 0x0E, 0x8A, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x67, 0x3F, 0x02, 0xB8, 0x91, 0x7F, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x14, 0x64, 0xA0, 0x33, 0xF4, 0x6B, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x44, 0x71, 0x87, 0xB8, 0x88, 0x3F, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x2B, 0x85, 0x05, 0xC5, 0x44, 0x53, 0x15), -}; -static const mbedtls_mpi_uint secp384r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x2B, 0xFE, 0xD1, 0x1C, 0x73, 0xE3, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x33, 0xA1, 0xD3, 0x69, 0x1C, 0x9D, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x5A, 0xBA, 0xB6, 0xAE, 0x1B, 0x94, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x74, 0x90, 0x5C, 0x57, 0xB0, 0x3A, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x2F, 0x93, 0x20, 0x24, 0x54, 0x1D, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x78, 0x9D, 0x71, 0x67, 0x5D, 0x49, 0x98), -}; -static const mbedtls_mpi_uint secp384r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xC8, 0x0E, 0x11, 0x8D, 0xE0, 0x8F, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x7F, 0x79, 0x6C, 0x5F, 0xB7, 0xBC, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xE1, 0x83, 0x3C, 0x12, 0xBB, 0xEE, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC2, 0xC4, 0x1B, 0x41, 0x71, 0xB9, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0xEE, 0xBB, 0x1D, 0x89, 0x50, 0x88, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x1C, 0x55, 0x74, 0xEB, 0xDE, 0x92, 0x3F), -}; -static const mbedtls_mpi_uint secp384r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x38, 0x92, 0x06, 0x19, 0xD0, 0xB3, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x99, 0x26, 0xA3, 0x5F, 0xE2, 0xC1, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xFC, 0xFD, 0xC3, 0xB6, 0x26, 0x24, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xAD, 0xE7, 0x49, 0xB7, 0x64, 0x4B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x4E, 0x95, 0xAD, 0x07, 0xFE, 0xB6, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x15, 0xE7, 0x2D, 0x19, 0xA9, 0x08, 0x10), -}; -static const mbedtls_mpi_uint secp384r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xBD, 0xAC, 0x0A, 0x3F, 0x6B, 0xFF, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xE4, 0x74, 0x14, 0xD9, 0x70, 0x1D, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xB0, 0x71, 0xBB, 0xD8, 0x18, 0x96, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xB8, 0x19, 0x90, 0x80, 0xB5, 0xEE, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x21, 0x20, 0xA6, 0x17, 0x48, 0x03, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0xBB, 0x6D, 0x94, 0x20, 0x34, 0xF1), -}; -static const mbedtls_mpi_uint secp384r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x82, 0x67, 0x4B, 0x8E, 0x4E, 0xBE, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xDA, 0x77, 0xF8, 0x23, 0x55, 0x2B, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x02, 0xDE, 0x25, 0x35, 0x2D, 0x74, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0C, 0xB8, 0x0B, 0x39, 0xBA, 0xAD, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x0E, 0x28, 0x4D, 0xE1, 0x3D, 0xE4, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xEC, 0x0A, 0xD4, 0xB8, 0xC4, 0x8D, 0xB0), -}; -static const mbedtls_mpi_uint secp384r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x68, 0xCE, 0xC2, 0x55, 0x4D, 0x0C, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x20, 0x93, 0x32, 0x90, 0xD6, 0xAE, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x78, 0xAB, 0x43, 0x9E, 0xEB, 0x73, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x97, 0xC3, 0x83, 0xA6, 0x3C, 0xF1, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x25, 0x25, 0x66, 0x08, 0x26, 0xFA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xFB, 0x44, 0x5D, 0x82, 0xEC, 0x3B, 0xAC), -}; -static const mbedtls_mpi_uint secp384r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x90, 0xEA, 0xB5, 0x04, 0x99, 0xD0, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0xF2, 0x22, 0xA0, 0xEB, 0xFD, 0x45, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA4, 0x81, 0x32, 0xFC, 0xFA, 0xEE, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xBB, 0xA4, 0x6A, 0x77, 0x41, 0x5C, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x1E, 0xAA, 0x4F, 0xF0, 0x10, 0xB3, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x74, 0x13, 0x14, 0x9E, 0x90, 0xD7, 0xE6), -}; -static const mbedtls_mpi_uint secp384r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xBD, 0x70, 0x4F, 0xA8, 0xD1, 0x06, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4E, 0x2E, 0x68, 0xFC, 0x35, 0xFA, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x53, 0x75, 0xED, 0xF2, 0x5F, 0xC2, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x87, 0x6B, 0x9F, 0x05, 0xE2, 0x22, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x1A, 0xA8, 0xB7, 0x03, 0x9E, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD0, 0x69, 0x88, 0xA8, 0x39, 0x9E, 0x3A), -}; -static const mbedtls_mpi_uint secp384r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xEF, 0x68, 0xFE, 0xEC, 0x24, 0x08, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x4B, 0x92, 0x0D, 0xB7, 0x34, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF4, 0xDD, 0x1A, 0xA0, 0x4A, 0xE4, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x63, 0x4F, 0x4F, 0xCE, 0xBB, 0xD6, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xEE, 0x8D, 0xDF, 0x3F, 0x73, 0xB7, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x06, 0xB6, 0x80, 0x4D, 0x81, 0xD9, 0x53), -}; -static const mbedtls_mpi_uint secp384r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF5, 0x13, 0xDF, 0x13, 0x19, 0x97, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xF9, 0xB3, 0x33, 0x66, 0x82, 0x21, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xFC, 0x39, 0x16, 0x23, 0x43, 0x76, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x48, 0x25, 0xA1, 0x64, 0x95, 0x1C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xAC, 0x15, 0x57, 0xD9, 0xDE, 0xA0, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x5F, 0xB8, 0x3D, 0x48, 0x91, 0x24, 0xCC), -}; -static const mbedtls_mpi_uint secp384r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xF2, 0xC8, 0x54, 0xD1, 0x32, 0xBD, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x3B, 0xF0, 0xAA, 0x9D, 0xD8, 0xF4, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xC3, 0xBB, 0x6C, 0x66, 0xAC, 0x25, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x25, 0x10, 0xB2, 0xE1, 0x41, 0xDE, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xE8, 0x30, 0xB8, 0x37, 0xBC, 0x2A, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x57, 0x01, 0x4A, 0x1E, 0x78, 0x9F, 0x85), -}; -static const mbedtls_mpi_uint secp384r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x19, 0xCD, 0x12, 0x0B, 0x51, 0x4F, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x4B, 0x3D, 0x24, 0xA4, 0x16, 0x59, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xEB, 0xD3, 0x59, 0x2E, 0x75, 0x7C, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB9, 0xB4, 0xA5, 0xD9, 0x2E, 0x29, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x16, 0x05, 0x75, 0x02, 0xB3, 0x06, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x7C, 0x9F, 0x79, 0x91, 0xF1, 0x4F, 0x23), -}; -static const mbedtls_mpi_uint secp384r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x98, 0x7C, 0x84, 0xE1, 0xFF, 0x30, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE2, 0xC2, 0x5F, 0x55, 0x40, 0xBD, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x65, 0x87, 0x3F, 0xC4, 0xC2, 0x24, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x30, 0x0A, 0x60, 0x15, 0xD1, 0x24, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x99, 0xD9, 0xB6, 0xAE, 0xB1, 0xAF, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x80, 0xEE, 0xA2, 0x0F, 0x74, 0xB9, 0xF3), -}; -static const mbedtls_mpi_uint secp384r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xE6, 0x0F, 0x37, 0xC1, 0x10, 0x99, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xAD, 0x9D, 0x5D, 0x80, 0x01, 0xA6, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x0F, 0x10, 0x2A, 0x9D, 0x20, 0x38, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x60, 0xCB, 0xCE, 0x5A, 0xA0, 0xA7, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xCF, 0x14, 0xDF, 0xBF, 0xE5, 0x74, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x12, 0x1A, 0xDD, 0x59, 0x02, 0x5D, 0xC6), -}; -static const mbedtls_mpi_uint secp384r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0xF8, 0xF5, 0xB6, 0x13, 0x4D, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x45, 0xB1, 0x93, 0xB3, 0xA2, 0x79, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xF6, 0xCF, 0xF7, 0xE6, 0x29, 0x9C, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x50, 0x65, 0x80, 0xBC, 0x59, 0x0A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xF0, 0x24, 0x35, 0xA2, 0x46, 0xF0, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x26, 0xC0, 0x9D, 0x61, 0x56, 0x62, 0x67), -}; -static const mbedtls_mpi_uint secp384r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xBB, 0xC2, 0x24, 0x43, 0x2E, 0x37, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xF7, 0xCE, 0x35, 0xFC, 0x77, 0xF3, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x34, 0x96, 0xD5, 0x4A, 0x76, 0x9D, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x3B, 0x0F, 0xEA, 0xA8, 0x12, 0x0B, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x3F, 0x5D, 0x2D, 0x1C, 0xD4, 0x9E, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x2E, 0xDD, 0xC7, 0x6E, 0xAB, 0xAF, 0xDC), -}; -static const mbedtls_mpi_uint secp384r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB2, 0x7B, 0x0C, 0x9A, 0x83, 0x8E, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x51, 0x90, 0x92, 0x79, 0x32, 0x19, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x89, 0xF9, 0xD0, 0xCF, 0x2C, 0xA5, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x50, 0x21, 0xDE, 0x50, 0x41, 0x9D, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x7D, 0x2B, 0x9E, 0x9D, 0x95, 0xA8, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA5, 0x20, 0x87, 0x88, 0x97, 0x5F, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x59, 0xB4, 0x66, 0x7E, 0xE8, 0x5A, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x5C, 0x7E, 0xB2, 0xAD, 0xD9, 0xC9, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x97, 0x49, 0xA3, 0x13, 0x83, 0x07, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x26, 0xC7, 0x13, 0x35, 0x0D, 0xB0, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x60, 0xAB, 0xFA, 0x4B, 0x93, 0x18, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2D, 0x1C, 0x31, 0x4C, 0xE4, 0x61, 0xAE), -}; -static const mbedtls_mpi_uint secp384r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x4D, 0x1E, 0x51, 0x59, 0x6E, 0x91, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x54, 0x4D, 0x51, 0xED, 0x36, 0xCC, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xA8, 0x56, 0xC7, 0x78, 0x27, 0x33, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB7, 0x95, 0xC9, 0x8B, 0xC8, 0x6A, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xE9, 0x13, 0x96, 0xB3, 0xE1, 0xF9, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x46, 0xB0, 0x5E, 0xC3, 0x94, 0x03, 0x05), -}; -static const mbedtls_mpi_uint secp384r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x5B, 0x29, 0x30, 0x41, 0x1A, 0x9E, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xCA, 0x83, 0x31, 0x5B, 0xA7, 0xCB, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x41, 0x50, 0x44, 0x4D, 0x64, 0x31, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x84, 0xC2, 0x5D, 0x97, 0xA5, 0x3C, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x0F, 0xA5, 0xFD, 0x8E, 0x5A, 0x47, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x58, 0x02, 0x2D, 0x40, 0xB1, 0x0B, 0xBA), -}; -static const mbedtls_mpi_uint secp384r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x33, 0x8C, 0x67, 0xCE, 0x23, 0x43, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x53, 0x47, 0x72, 0x44, 0x1F, 0x5B, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xC1, 0xD9, 0xA4, 0x50, 0x88, 0x63, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xF2, 0x75, 0x69, 0x73, 0x00, 0xC4, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x90, 0x1D, 0xDF, 0x1A, 0x00, 0xD8, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xB1, 0x89, 0x48, 0xA8, 0x70, 0x62, 0xEF), -}; -static const mbedtls_mpi_uint secp384r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x8A, 0x55, 0x50, 0x7B, 0xEF, 0x8A, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1B, 0x23, 0x48, 0x23, 0x63, 0x91, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x04, 0x54, 0x3C, 0x24, 0x9B, 0xC7, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x38, 0xC3, 0x84, 0xFB, 0xFF, 0x9F, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x2A, 0xE0, 0x6D, 0x68, 0x8A, 0x5C, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x93, 0x53, 0x85, 0xA1, 0x0D, 0xAF, 0x63), -}; -static const mbedtls_mpi_uint secp384r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x88, 0x95, 0x4C, 0x0B, 0xD0, 0x06, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xAF, 0x8D, 0x49, 0xA2, 0xC8, 0xB4, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x76, 0x53, 0x09, 0x88, 0x43, 0x87, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA4, 0x77, 0x3F, 0x5E, 0x21, 0xB4, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x9E, 0x86, 0x64, 0xCC, 0x91, 0xC1, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x17, 0x56, 0xCB, 0xC3, 0x7D, 0x5B, 0xB1), -}; -static const mbedtls_mpi_uint secp384r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x74, 0x9F, 0xB5, 0x91, 0x21, 0xB1, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xED, 0xE1, 0x11, 0xEF, 0x45, 0xAF, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x31, 0xBE, 0xB2, 0xBC, 0x72, 0x65, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x4B, 0x8C, 0x77, 0xCE, 0x1E, 0x42, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC9, 0xAA, 0xB9, 0xD9, 0x86, 0x99, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x23, 0x80, 0xC6, 0x4E, 0x35, 0x0B, 0x6D), -}; -static const mbedtls_mpi_uint secp384r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xD8, 0xA2, 0x0A, 0x39, 0x32, 0x1D, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xC8, 0x86, 0xF1, 0x12, 0x9A, 0x4A, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xF1, 0x7C, 0xAA, 0x70, 0x8E, 0xBC, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x01, 0x47, 0x8F, 0xDD, 0x8B, 0xA5, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x08, 0x21, 0xF4, 0xAB, 0xC7, 0xF5, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x76, 0xA5, 0x95, 0xC4, 0x0F, 0x88, 0x1D), -}; -static const mbedtls_mpi_uint secp384r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x42, 0x2A, 0x52, 0xCD, 0x75, 0x51, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x36, 0xE5, 0x04, 0x2B, 0x44, 0xC6, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xEE, 0x16, 0x13, 0x07, 0x83, 0xB5, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x59, 0xC6, 0xA2, 0x19, 0x05, 0xD3, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8B, 0xA8, 0x16, 0x09, 0xB7, 0xEA, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xEE, 0x14, 0xAF, 0xB5, 0xFD, 0xD0, 0xEF), -}; -static const mbedtls_mpi_uint secp384r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x7C, 0xCA, 0x71, 0x3E, 0x6E, 0x66, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x31, 0x0E, 0x3F, 0xE5, 0x91, 0xC4, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x3D, 0xC2, 0x3E, 0x95, 0x37, 0x58, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x1F, 0x02, 0x03, 0xF3, 0xEF, 0xEE, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x5B, 0x1A, 0xFC, 0x38, 0xCD, 0xE8, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x57, 0x42, 0x85, 0xC6, 0x21, 0x68, 0x71), -}; -static const mbedtls_mpi_uint secp384r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA2, 0x4A, 0x66, 0xB1, 0x0A, 0xE6, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x0C, 0x94, 0x9D, 0x5E, 0x99, 0xB2, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x03, 0x40, 0xCA, 0xB2, 0xB3, 0x30, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0x48, 0x27, 0x34, 0x1E, 0xE2, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x72, 0x5B, 0xAC, 0xC1, 0x6D, 0xE3, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAB, 0x46, 0xCB, 0xEA, 0x5E, 0x4B, 0x0B), -}; -static const mbedtls_mpi_uint secp384r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x08, 0xAD, 0x4E, 0x51, 0x9F, 0x2A, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5C, 0x7D, 0x4C, 0xD6, 0xCF, 0xDD, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x76, 0x26, 0xE0, 0x8B, 0x10, 0xD9, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA7, 0x23, 0x4E, 0x5F, 0xD2, 0x42, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xE5, 0xA4, 0xEC, 0x77, 0x21, 0x34, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x14, 0x65, 0xEA, 0x4A, 0x85, 0xC3, 0x2F), -}; -static const mbedtls_mpi_uint secp384r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xD8, 0x40, 0x27, 0x73, 0x15, 0x7E, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xBB, 0x53, 0x7E, 0x0F, 0x40, 0xC8, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x37, 0x19, 0x73, 0xEF, 0x5A, 0x5E, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x73, 0x2B, 0x49, 0x7E, 0xAC, 0x97, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xB2, 0xC3, 0x1E, 0x0E, 0xE7, 0xD2, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x08, 0xD6, 0xDD, 0xAC, 0x21, 0xD6, 0x3E), -}; -static const mbedtls_mpi_uint secp384r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x26, 0xBE, 0x6D, 0x6D, 0xF2, 0x38, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6C, 0x31, 0xA7, 0x49, 0x50, 0x3A, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x99, 0xC6, 0xF5, 0xD2, 0xC2, 0x30, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE4, 0xF6, 0x8B, 0x8B, 0x97, 0xE9, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x21, 0xB7, 0x0D, 0xFC, 0x15, 0x54, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x83, 0x1C, 0xA4, 0xCD, 0x6B, 0x9D, 0xF2), -}; -static const mbedtls_mpi_uint secp384r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE8, 0x4C, 0x48, 0xE4, 0xAA, 0x69, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x7A, 0x27, 0xFC, 0x37, 0x96, 0x1A, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xE7, 0x30, 0xA5, 0xCF, 0x13, 0x46, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xD8, 0xAF, 0x74, 0x23, 0x4D, 0x56, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3D, 0x44, 0x14, 0x1B, 0x97, 0x83, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x47, 0xD7, 0x5F, 0xFD, 0x98, 0x38, 0xF7), -}; -static const mbedtls_mpi_uint secp384r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x73, 0x64, 0x36, 0xFD, 0x7B, 0xC1, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x5D, 0x32, 0xD2, 0x47, 0x94, 0x89, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xE9, 0x30, 0xAC, 0x06, 0xC8, 0x65, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x6C, 0xB9, 0x1B, 0xF7, 0x61, 0x49, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xFF, 0x32, 0x43, 0x80, 0xDA, 0xA6, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF8, 0x04, 0x01, 0x95, 0x35, 0xCE, 0x21), -}; -static const mbedtls_mpi_uint secp384r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x06, 0x46, 0x0D, 0x51, 0xE2, 0xD8, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x57, 0x1D, 0x6F, 0x79, 0xA0, 0xCD, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xFB, 0x36, 0xCA, 0xAD, 0xF5, 0x9E, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x7A, 0x1D, 0x9E, 0x1D, 0x95, 0x48, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x26, 0xA5, 0xB7, 0x15, 0x2C, 0xC2, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x42, 0x72, 0xAA, 0x11, 0xDC, 0xC9, 0xB6), -}; -static const mbedtls_mpi_uint secp384r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x6C, 0x64, 0xA7, 0x62, 0x3C, 0xAB, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x6A, 0x44, 0xD8, 0x60, 0xC0, 0xA8, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x76, 0x58, 0x12, 0x57, 0x3C, 0x89, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x4F, 0x83, 0xCE, 0xCB, 0xB8, 0xD0, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0x04, 0xB0, 0xAD, 0xEB, 0xFA, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA4, 0xC3, 0x41, 0x44, 0x4E, 0x65, 0x3E), -}; -static const mbedtls_mpi_uint secp384r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x16, 0xA9, 0x1C, 0xE7, 0x65, 0x20, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x53, 0x32, 0xF8, 0xC0, 0xA6, 0xBD, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF0, 0xE6, 0x57, 0x31, 0xCC, 0x26, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xE3, 0x54, 0x1C, 0x34, 0xD3, 0x17, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xAE, 0xED, 0xFB, 0xCD, 0xE7, 0x1E, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x16, 0x1C, 0x34, 0x40, 0x00, 0x1F, 0xB6), -}; -static const mbedtls_mpi_uint secp384r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x32, 0x00, 0xC2, 0xD4, 0x3B, 0x1A, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xE0, 0x99, 0x8F, 0x0C, 0x4A, 0x16, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x73, 0x18, 0x1B, 0xD4, 0x94, 0x29, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA4, 0x2D, 0xB1, 0x9D, 0x74, 0x32, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xF4, 0xB1, 0x0C, 0x37, 0x62, 0x8B, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xFF, 0xDA, 0xE2, 0x35, 0xA3, 0xB6, 0x42), -}; -static const mbedtls_mpi_uint secp384r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x49, 0x99, 0x65, 0xC5, 0xED, 0x16, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x42, 0x9A, 0xF3, 0xA7, 0x4E, 0x6F, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x0A, 0x7E, 0xC0, 0xD7, 0x4E, 0x07, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x7A, 0x31, 0x69, 0xA6, 0xB9, 0x15, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xE0, 0x72, 0xA4, 0x3F, 0xB9, 0xF8, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x75, 0x32, 0x85, 0xA2, 0xDE, 0x37, 0x12), -}; -static const mbedtls_mpi_uint secp384r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC0, 0x0D, 0xCF, 0x25, 0x41, 0xA4, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xFC, 0xB2, 0x48, 0xC3, 0x85, 0x83, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBE, 0x0B, 0x58, 0x2D, 0x7A, 0x9A, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xF3, 0x81, 0x18, 0x1B, 0x74, 0x4F, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x43, 0xA3, 0x0A, 0x16, 0x8B, 0xA3, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x18, 0x81, 0x7B, 0x8D, 0xA2, 0x35, 0x77), -}; -static const mbedtls_mpi_uint secp384r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xC4, 0x3F, 0x2C, 0xE7, 0x5F, 0x99, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2B, 0xB7, 0xB6, 0xAD, 0x5A, 0x56, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x00, 0xA4, 0x48, 0xC8, 0xE8, 0xBA, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xA1, 0xB5, 0x13, 0x5A, 0xCD, 0x99, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x95, 0xAD, 0xFC, 0xE2, 0x7E, 0xE7, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x6B, 0xD1, 0x34, 0x99, 0x53, 0x63, 0x0B), -}; -static const mbedtls_mpi_uint secp384r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x8A, 0x77, 0x5D, 0x2B, 0xAB, 0x01, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x85, 0xD0, 0xD5, 0x49, 0x83, 0x4D, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xC6, 0x91, 0x30, 0x3B, 0x00, 0xAF, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x61, 0x07, 0xE1, 0xB6, 0xE2, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x43, 0x41, 0xFE, 0x9B, 0xB6, 0xF0, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x97, 0xAE, 0xAD, 0x89, 0x88, 0x9E, 0x41), -}; -static const mbedtls_ecp_point secp384r1_T[32] = { - ECP_POINT_INIT_XY_Z1(secp384r1_T_0_X, secp384r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_1_X, secp384r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_2_X, secp384r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_3_X, secp384r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_4_X, secp384r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_5_X, secp384r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_6_X, secp384r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_7_X, secp384r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_8_X, secp384r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_9_X, secp384r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_10_X, secp384r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_11_X, secp384r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_12_X, secp384r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_13_X, secp384r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_14_X, secp384r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_15_X, secp384r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_16_X, secp384r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_17_X, secp384r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_18_X, secp384r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_19_X, secp384r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_20_X, secp384r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_21_X, secp384r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_22_X, secp384r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_23_X, secp384r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_24_X, secp384r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_25_X, secp384r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_26_X, secp384r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_27_X, secp384r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_28_X, secp384r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_29_X, secp384r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_30_X, secp384r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_31_X, secp384r1_T_31_Y), -}; -#else -#define secp384r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* - * Domain parameters for secp521r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static const mbedtls_mpi_uint secp521r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), -}; -static const mbedtls_mpi_uint secp521r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95), - MBEDTLS_BYTES_TO_T_UINT_2(0x51, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_2(0xC6, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), - MBEDTLS_BYTES_TO_T_UINT_2(0x18, 0x01), -}; -static const mbedtls_mpi_uint secp521r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp521r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xB1, 0x2D, 0xEB, 0x27, 0x2F, 0xE8, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x4B, 0x44, 0x25, 0xDB, 0x5C, 0x5F, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x85, 0x28, 0x78, 0x2E, 0x75, 0x34, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x57, 0x0F, 0x73, 0x78, 0x7A, 0xE3, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD8, 0xEC, 0xDC, 0xDA, 0x04, 0xAD, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x8A, 0x09, 0xF3, 0x58, 0x79, 0xD8, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x03, 0xCB, 0x50, 0x1A, 0x7F, 0x56, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA6, 0x78, 0x38, 0x85, 0x67, 0x0B, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xD5, 0xD2, 0x22, 0xC4, 0x00, 0x3B, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x93, 0x0E, 0x7B, 0x85, 0x51, 0xC3, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA6, 0x5F, 0x54, 0x49, 0x02, 0x81, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xE9, 0x6B, 0x3A, 0x92, 0xE7, 0x72, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x5F, 0x28, 0x9E, 0x91, 0x27, 0x88, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x28, 0x31, 0xB3, 0x84, 0xCA, 0x12, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xF9, 0xAC, 0x22, 0x10, 0x0A, 0x64, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xC6, 0x33, 0x1F, 0x69, 0x19, 0x18, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x48, 0xB8, 0xC7, 0x37, 0x5A, 0x00, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xCC, 0x32, 0xE0, 0xEE, 0x03, 0xC2, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x29, 0xC2, 0xE4, 0x6E, 0x24, 0x20, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x6B, 0x7F, 0x7B, 0xF9, 0xB0, 0xB8, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x7B, 0x3C, 0xE1, 0x19, 0xA1, 0x23, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE3, 0xC2, 0x53, 0xC0, 0x07, 0x13, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFE, 0x36, 0x35, 0x9F, 0x5E, 0x59, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x55, 0x89, 0x84, 0xBC, 0xEF, 0xA2, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x1A, 0x08, 0x67, 0xB4, 0xE7, 0x22, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x26, 0xDF, 0x81, 0x3C, 0x5F, 0x1C, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x4D, 0xD0, 0x0A, 0x48, 0x06, 0xF4, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x18, 0x39, 0xF7, 0xD1, 0x20, 0x77, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x8F, 0x44, 0x13, 0xCB, 0x78, 0x11, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE2, 0x49, 0xEA, 0x43, 0x79, 0x08, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xD1, 0xD8, 0x73, 0x2C, 0x71, 0x2F, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE5, 0xE7, 0xF4, 0x46, 0xAB, 0x20, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x0B, 0xB9, 0x71, 0x1A, 0x27, 0xB7, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xA2, 0x2C, 0xD1, 0xDA, 0xBC, 0xC1, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xA3, 0x10, 0x1F, 0x90, 0xF2, 0xA5, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xFB, 0x20, 0xF4, 0xC0, 0x70, 0xC0, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xA7, 0x99, 0xF0, 0xA5, 0xD3, 0x09, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xE8, 0x14, 0x39, 0xBE, 0xCB, 0x60, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD6, 0x14, 0xA9, 0xC9, 0x20, 0xC3, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x5B, 0xFD, 0x2D, 0x96, 0xBC, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x04, 0x45, 0xBE, 0xCE, 0x75, 0x95, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xDA, 0x58, 0x49, 0x35, 0x09, 0x8D, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xF0, 0xC0, 0x36, 0xF2, 0xA6, 0x2D, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFC, 0x3D, 0xA8, 0xFB, 0x3C, 0xD2, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x4D, 0x71, 0x09, 0x18, 0x42, 0xF0, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xC1, 0xCE, 0x9E, 0x6A, 0x49, 0x60, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xB1, 0x00, 0xF7, 0xA1, 0x7A, 0x31, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC3, 0x86, 0xCD, 0x20, 0x4A, 0x17, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xAB, 0x8B, 0x47, 0x8D, 0xAA, 0xA6, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x97, 0xF0, 0xBC, 0x2D, 0xDC, 0x9D, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x86, 0xB0, 0x74, 0xB2, 0xF4, 0xF6, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBD, 0xAC, 0xE3, 0x8F, 0x43, 0x5C, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xC3, 0xE2, 0x6E, 0x25, 0x49, 0xCD, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5E, 0x08, 0xB3, 0xB9, 0xAC, 0x5F, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xB7, 0xD1, 0xF4, 0xDC, 0x19, 0xE9, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xE4, 0xFA, 0xE1, 0x36, 0x3E, 0xED, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0x92, 0x84, 0x6E, 0x48, 0x03, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x95, 0xEF, 0x8F, 0xB2, 0x82, 0x6B, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFA, 0xB9, 0x55, 0x23, 0xFE, 0x09, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x79, 0x85, 0x4B, 0x0E, 0xD4, 0x35, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x27, 0x45, 0x81, 0xE0, 0x88, 0x52, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x63, 0xA2, 0x4B, 0xBC, 0x5D, 0xB1, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x8C, 0x83, 0xD9, 0x3E, 0xD3, 0x42, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x03, 0x3A, 0x31, 0xBA, 0xE9, 0x3A, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x10, 0xCD, 0x2D, 0x00, 0xFE, 0x32, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x6E, 0x1F, 0xDA, 0xF8, 0x6F, 0x4D, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x79, 0x7D, 0x09, 0xE5, 0xD3, 0x03, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC3, 0xBE, 0xDF, 0x07, 0x65, 0x49, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0x33, 0xEF, 0xAE, 0x4F, 0x04, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xE9, 0x9B, 0xFE, 0xBF, 0xE6, 0x85, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xBA, 0xAA, 0x06, 0xC4, 0xC6, 0xB8, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x83, 0x01, 0xA9, 0xF6, 0x51, 0xE7, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xA6, 0x15, 0x8E, 0xAB, 0x1F, 0x10, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x08, 0x27, 0x1A, 0xA1, 0x21, 0xAD, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x09, 0x90, 0x6E, 0x50, 0x90, 0x9A, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x9A, 0xFE, 0xD7, 0xA1, 0xF5, 0xA2, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x7D, 0xE3, 0xDC, 0x21, 0xFB, 0xA4, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBF, 0x07, 0xFF, 0x45, 0xDF, 0x51, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x5C, 0x34, 0x02, 0x62, 0x9B, 0x08, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xCE, 0x9A, 0x6A, 0xEC, 0x75, 0xF6, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x59, 0xF4, 0x78, 0x3C, 0x60, 0xB1, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x37, 0x84, 0x6A, 0xDC, 0xF2, 0x9A, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9A, 0x9A, 0x15, 0x36, 0xE0, 0x2B, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x38, 0x9C, 0x50, 0x3D, 0x1E, 0x37, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x79, 0xF0, 0x92, 0xF2, 0x8B, 0x18, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE0, 0x82, 0x1E, 0x80, 0x82, 0x4B, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xBB, 0x59, 0x6B, 0x8A, 0x77, 0x41, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xF9, 0xD4, 0xB8, 0x4A, 0x82, 0xCF, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x8C, 0xC8, 0x9B, 0x72, 0x9E, 0xF7, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xCE, 0xE9, 0x77, 0x0A, 0x19, 0x59, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xA1, 0x41, 0x6A, 0x72, 0x4B, 0xB4, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x35, 0x43, 0xE2, 0x8C, 0xBE, 0x0D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xEB, 0xAD, 0xF3, 0xA9, 0xA6, 0x68, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2F, 0xE2, 0x48, 0x0C, 0xDB, 0x1F, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x1E, 0x60, 0x9B, 0x2A, 0xD2, 0xC1, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x64, 0xB5, 0xD2, 0xF6, 0xF6, 0x6E, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x3D, 0x30, 0x78, 0x10, 0x18, 0x41, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x1D, 0x1C, 0xE0, 0x6D, 0x83, 0xD1, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x03, 0x0B, 0xF5, 0x2F, 0x6C, 0x04, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x3E, 0xD5, 0xFC, 0x31, 0x5B, 0x3A, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x82, 0x2F, 0xFB, 0xFE, 0xF8, 0x76, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x26, 0xDA, 0x9C, 0x36, 0xF5, 0x93, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xE7, 0x6E, 0xD2, 0x7D, 0x81, 0x09, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x03, 0xF9, 0x58, 0x48, 0x24, 0xA2, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x79, 0x0C, 0x8E, 0x6B, 0x95, 0xF3, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x10, 0x5C, 0x87, 0x03, 0x39, 0xCF, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xF0, 0xF7, 0xC1, 0x07, 0xA4, 0xF4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE8, 0x02, 0x89, 0x65, 0xC4, 0x72, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x88, 0xEA, 0x96, 0x67, 0x0B, 0x5D, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x75, 0x60, 0xA8, 0xBD, 0x74, 0xDF, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xE5, 0x71, 0x50, 0x67, 0xD0, 0xD2, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFC, 0xE5, 0xC7, 0x77, 0xB0, 0x7F, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x86, 0x69, 0xCD, 0x0D, 0x9A, 0xBD, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x17, 0xBC, 0xBB, 0x59, 0x85, 0x7D, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA8, 0x76, 0xAC, 0x80, 0xA9, 0x72, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0xC1, 0xE2, 0x4D, 0xAF, 0xF9, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x97, 0x8E, 0x74, 0xC4, 0x4B, 0xB2, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD8, 0xF6, 0xF3, 0xAF, 0x2F, 0x52, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x57, 0xF4, 0xCE, 0xEE, 0x43, 0xED, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x46, 0x38, 0xDE, 0x20, 0xFD, 0x59, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x18, 0xE8, 0x58, 0xB9, 0x76, 0x2C, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x54, 0xE4, 0xFE, 0xC7, 0xBC, 0x31, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF8, 0x89, 0xEE, 0x70, 0xB5, 0xB0, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x22, 0x26, 0x9A, 0x53, 0xB9, 0x38, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xA7, 0x19, 0x8C, 0x74, 0x7E, 0x88, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xDA, 0x0A, 0xE8, 0xDA, 0xA5, 0xBE, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x5C, 0xF7, 0xB1, 0x0C, 0x72, 0xFB, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xE2, 0x23, 0xE7, 0x46, 0xB7, 0xE0, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x36, 0xBC, 0xBD, 0x48, 0x11, 0x8E, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xBB, 0xA1, 0xF7, 0x0B, 0x9E, 0xBF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x28, 0xE1, 0xA2, 0x8F, 0xFC, 0xFC, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xFE, 0x19, 0x0A, 0xE5, 0xE7, 0x69, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xCD, 0x12, 0xF5, 0xBE, 0xD3, 0x04, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA8, 0x0D, 0x81, 0x59, 0xC4, 0x79, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xF3, 0x4B, 0x92, 0x65, 0xC3, 0x31, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xB5, 0x4F, 0x4D, 0x91, 0xD4, 0xE2, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x09, 0x41, 0x79, 0x1D, 0x4D, 0x0D, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x31, 0x18, 0xBA, 0xA0, 0xF2, 0x6E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x5B, 0x4D, 0x4F, 0xAF, 0xC9, 0x8C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x9C, 0x06, 0x68, 0xDE, 0xD8, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x04, 0xE1, 0xB5, 0x9D, 0x00, 0xBC, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x95, 0x92, 0x8D, 0x72, 0xD3, 0x37, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x4B, 0x27, 0xA2, 0xE8, 0xA4, 0x26, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x45, 0x9C, 0xA9, 0xCB, 0x9F, 0xBA, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x7E, 0x1B, 0x64, 0xF4, 0xE8, 0xA5, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x20, 0xA9, 0xCA, 0xF3, 0x89, 0xE5, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xED, 0xFC, 0xAB, 0xD9, 0x0A, 0xB9, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6F, 0x46, 0x7C, 0xCD, 0x78, 0xFF, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAB, 0x71, 0x5A, 0x94, 0xAB, 0x20, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x2E, 0xEE, 0x87, 0x57, 0x1F, 0xAD, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x4C, 0x3D, 0xFB, 0x7E, 0xA1, 0x8B, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xCF, 0x07, 0x86, 0xBA, 0x53, 0x37, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x26, 0xB2, 0xB9, 0xE2, 0x91, 0xE3, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xC9, 0x54, 0x84, 0x08, 0x3D, 0x0B, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x77, 0x2F, 0x64, 0x45, 0x99, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x96, 0x16, 0x1F, 0xDB, 0x96, 0x28, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x2B, 0x8D, 0xFF, 0xA2, 0x4F, 0x55, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE6, 0x48, 0xBD, 0x99, 0x3D, 0x12, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x84, 0x59, 0xDA, 0xB9, 0xB6, 0x66, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x78, 0x41, 0x92, 0xDF, 0xF4, 0x3F, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x86, 0x6F, 0x4F, 0xBF, 0x67, 0xDF, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x2B, 0x1E, 0x5F, 0x00, 0xEA, 0xF6, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xB9, 0x6A, 0x89, 0xD8, 0xC0, 0xD7, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x9A, 0x32, 0x23, 0xA0, 0x02, 0x91, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x7F, 0x6A, 0x15, 0x64, 0x6A, 0x8B, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x57, 0x82, 0x58, 0xA9, 0x56, 0xB5, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x50, 0x92, 0x60, 0xCC, 0x81, 0x24, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x3D, 0xAD, 0xDA, 0xD9, 0x51, 0x3E, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xFE, 0x8F, 0xB0, 0x0B, 0xDE, 0x2E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xD2, 0xBE, 0xEF, 0xAC, 0x76, 0x71, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xE8, 0x72, 0x0B, 0xAC, 0xFE, 0xCA, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0xC7, 0xFC, 0xE3, 0x3C, 0x7C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x04, 0xA7, 0xB9, 0x9B, 0x93, 0xC0, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x48, 0x4B, 0x8E, 0x32, 0xC5, 0xF0, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x42, 0x07, 0xC1, 0xF2, 0xF1, 0x72, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x37, 0x54, 0x9C, 0x88, 0xD2, 0x62, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x19, 0x8A, 0x89, 0x58, 0xA2, 0x0F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xCC, 0x4C, 0x97, 0x30, 0x66, 0x34, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x6A, 0x1E, 0x1F, 0xDB, 0xC9, 0x5E, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x4D, 0x49, 0xFF, 0x9B, 0x9C, 0xAC, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xE4, 0x4B, 0xF2, 0xD4, 0x1A, 0xD2, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xDA, 0xE8, 0x61, 0x9F, 0xC8, 0x49, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xCB, 0xF2, 0x2D, 0x85, 0xF6, 0x8D, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xC5, 0xCD, 0x2C, 0x79, 0xC6, 0x0E, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x1D, 0x55, 0x0F, 0xF8, 0x22, 0x9F, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x56, 0xBA, 0xE7, 0x57, 0x32, 0xEC, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x9A, 0xC6, 0x4C, 0x09, 0xC4, 0x52, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x1E, 0x6F, 0xF4, 0x7D, 0x27, 0xDD, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x11, 0x16, 0xEC, 0x79, 0x83, 0xAD, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x4E, 0x92, 0x1F, 0x19, 0x7D, 0x65, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xFF, 0x78, 0x15, 0x45, 0x63, 0x32, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x91, 0xD0, 0x78, 0x58, 0xDA, 0x50, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xDE, 0x40, 0xF6, 0x41, 0xB4, 0x3B, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x8D, 0xE0, 0xE1, 0xA9, 0xF0, 0x35, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xD4, 0xBA, 0x7B, 0xCC, 0x1B, 0x3A, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x5A, 0x2E, 0x74, 0x47, 0x14, 0xC3, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xF0, 0x8B, 0x06, 0x15, 0x8E, 0x0E, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xD2, 0xEB, 0x97, 0x50, 0x7D, 0x31, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x93, 0x4C, 0xDB, 0x97, 0x79, 0x44, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xA2, 0xA0, 0x0B, 0xC8, 0x3A, 0x8A, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x50, 0x92, 0x9E, 0x24, 0x1F, 0xCB, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x16, 0xC9, 0xC5, 0x3D, 0x5A, 0xAF, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xE3, 0x97, 0xE4, 0xA8, 0x50, 0xF6, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x57, 0x97, 0x42, 0x78, 0x92, 0x49, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEB, 0x62, 0x24, 0xFB, 0x8F, 0x32, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x0C, 0x36, 0x6E, 0x8F, 0xE8, 0xE8, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xD3, 0x7C, 0xC7, 0x8D, 0x3F, 0x5C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x64, 0x6A, 0x73, 0x10, 0x79, 0xB8, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xF9, 0xEF, 0xA5, 0x20, 0x4A, 0x5C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xF3, 0xF4, 0x49, 0x5B, 0x73, 0xAA, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xF2, 0xEA, 0x0F, 0x00, 0xAD, 0x53, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xB8, 0x66, 0xED, 0xC4, 0x2B, 0x4C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x2F, 0xC1, 0x9A, 0x37, 0xD2, 0x7F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA7, 0x81, 0x38, 0x64, 0xC9, 0x37, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x3B, 0x6C, 0x9F, 0x5B, 0xD9, 0x8B, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x14, 0xD9, 0x08, 0xD8, 0xD2, 0x7E, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x71, 0xE6, 0x3D, 0xD1, 0xB0, 0xE7, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x81, 0x23, 0xEC, 0x2D, 0x42, 0x45, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x5B, 0x44, 0x6B, 0x89, 0x03, 0x67, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x27, 0xAE, 0x80, 0x5A, 0x33, 0xBE, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB6, 0x64, 0x1A, 0xDF, 0xD3, 0x85, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x8C, 0x22, 0xBA, 0xD0, 0xBD, 0xCC, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x3C, 0x01, 0x3A, 0xFF, 0x9D, 0xC7, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC7, 0x64, 0xB4, 0x59, 0x4E, 0x9F, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x34, 0x0A, 0x41, 0x94, 0xA8, 0xF2, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD4, 0xE4, 0xF0, 0x97, 0x45, 0x6D, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x1F, 0x4D, 0x6D, 0xFE, 0xA0, 0xC4, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x28, 0x5C, 0x40, 0xBB, 0x65, 0xD4, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xA8, 0x87, 0x35, 0x20, 0x3A, 0x89, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFD, 0x4F, 0xAB, 0x2D, 0xD1, 0xD0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE8, 0x00, 0xFC, 0x69, 0x52, 0xF8, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x9A, 0x99, 0xE1, 0xDC, 0x9C, 0x3F, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x08, 0x98, 0xD9, 0xCA, 0x73, 0xD5, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x2C, 0xE0, 0xA7, 0x3E, 0x91, 0xD7, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x04, 0xB0, 0x54, 0x09, 0xF4, 0x72, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xEE, 0x28, 0xCC, 0xE8, 0x50, 0x78, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x91, 0x03, 0x76, 0xDB, 0x68, 0x24, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xE0, 0x56, 0xB2, 0x5D, 0x12, 0xD3, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x42, 0x59, 0x8B, 0xDF, 0x67, 0xB5, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xCC, 0xE5, 0x31, 0x53, 0x7A, 0x46, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8D, 0x59, 0xB5, 0x1B, 0x0F, 0xF4, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x2F, 0xD1, 0x2C, 0xE0, 0xD8, 0x04, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0xD7, 0xBA, 0xB0, 0xA3, 0x7E, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x08, 0x51, 0x56, 0xA6, 0x76, 0x67, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x17, 0x63, 0xFE, 0x56, 0xD0, 0xD9, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xF6, 0xC3, 0x14, 0x47, 0xC5, 0xA7, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x4C, 0x80, 0xF6, 0xA2, 0x57, 0xA7, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xB3, 0x7B, 0xF8, 0x2F, 0xE1, 0x3E, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xF4, 0xF9, 0x6B, 0x7B, 0x90, 0xDF, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x82, 0xEF, 0x62, 0xA1, 0x4C, 0x53, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x99, 0x76, 0x01, 0xBA, 0x8D, 0x0F, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xF4, 0x58, 0x73, 0x56, 0xFE, 0xDD, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xCE, 0xF9, 0xE8, 0xA1, 0x34, 0xC3, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x5F, 0xDC, 0x6A, 0x3D, 0xD8, 0x7F, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xF4, 0x51, 0xB8, 0xB8, 0xC1, 0xD7, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x7D, 0x58, 0xD1, 0xD4, 0x1B, 0x4D, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x95, 0xDF, 0x00, 0xD8, 0x21, 0xDE, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x47, 0x3C, 0xC3, 0xB2, 0x01, 0x53, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x17, 0x43, 0x23, 0xBD, 0xCA, 0x71, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xBA, 0x0F, 0x4F, 0xDC, 0x41, 0x54, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x39, 0x26, 0x70, 0x53, 0x32, 0x18, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x46, 0x07, 0x97, 0x3A, 0x57, 0xE0, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x92, 0x4F, 0xCE, 0xDF, 0x25, 0x80, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x6F, 0x9A, 0x03, 0x05, 0x4B, 0xD1, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x01, 0x72, 0x30, 0x90, 0x17, 0x51, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xFB, 0x41, 0x65, 0x5C, 0xB4, 0x2D, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xCD, 0xCD, 0xAA, 0x41, 0xCC, 0xBB, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xCE, 0x08, 0x0A, 0x63, 0xE9, 0xA2, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA8, 0x21, 0x7F, 0x7A, 0x5B, 0x9B, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x6B, 0x89, 0x44, 0x0A, 0x7F, 0x85, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xDE, 0x7C, 0x19, 0x5C, 0x65, 0x26, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xAC, 0x62, 0x29, 0x4A, 0xF1, 0xD0, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x00, 0x40, 0x87, 0xEB, 0xA9, 0x58, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x51, 0x0B, 0xFF, 0x56, 0x35, 0x51, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xAC, 0x08, 0x94, 0x71, 0xDA, 0xEC, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x4D, 0xC5, 0x7B, 0x31, 0x8B, 0x8D, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x05, 0xF1, 0x3E, 0x9E, 0x8F, 0x17, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x9C, 0x4B, 0x62, 0x94, 0xAD, 0x49, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC9, 0xC6, 0x8F, 0xFD, 0x33, 0x44, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x96, 0x17, 0x7F, 0x42, 0xBE, 0xF7, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x29, 0x39, 0x13, 0x08, 0x8D, 0x91, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x79, 0xF9, 0x2F, 0xA9, 0x0A, 0xCF, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x87, 0x7A, 0xA3, 0x19, 0xAB, 0x55, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x0B, 0x01, 0xC5, 0x56, 0x19, 0x9D, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xDE, 0x82, 0x3B, 0xEA, 0xD3, 0x0B, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x6B, 0xC7, 0xF3, 0x0F, 0x82, 0x87, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x2E, 0x23, 0xF2, 0x39, 0x9D, 0x49, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xDE, 0xAF, 0x7A, 0xEE, 0xB0, 0xDA, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x4E, 0x2A, 0x50, 0xFD, 0x8E, 0xC0, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x0F, 0x7C, 0x76, 0x63, 0xD8, 0x89, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x2D, 0xB9, 0x4E, 0xF4, 0xEE, 0x85, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x95, 0x5C, 0x96, 0x5D, 0xAA, 0x59, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xDB, 0xD2, 0x68, 0x8E, 0x5A, 0x94, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x02, 0xBF, 0x77, 0x9F, 0xB9, 0x4C, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xDC, 0xC0, 0xCF, 0x81, 0x1E, 0xC4, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xCC, 0x37, 0x86, 0xDC, 0xE2, 0x64, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x30, 0xB1, 0x59, 0x20, 0x9D, 0x98, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x0C, 0x9D, 0xF8, 0x20, 0xDC, 0x90, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xA0, 0xF4, 0xE7, 0x3E, 0x9C, 0x9E, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x25, 0xA2, 0xB0, 0x54, 0xCD, 0x2E, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD9, 0x42, 0xB0, 0x80, 0xB0, 0xA3, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xFE, 0x9D, 0x8D, 0x40, 0xFF, 0x27, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9D, 0xA6, 0x88, 0x3A, 0x8B, 0x6F, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x39, 0xEE, 0x1F, 0x3F, 0xB1, 0x4F, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD7, 0x9E, 0xFF, 0xD2, 0x35, 0x67, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x4F, 0x15, 0x5D, 0xE3, 0xE8, 0x53, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF7, 0x24, 0x98, 0xA2, 0xCB, 0x11, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x2E, 0x25, 0xE1, 0x94, 0xC5, 0xA3, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x82, 0x6E, 0xBA, 0xE7, 0x43, 0x25, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x65, 0xB4, 0x49, 0x73, 0x18, 0x35, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x5B, 0xBC, 0x62, 0x86, 0x4C, 0xC1, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xF2, 0x95, 0xA2, 0xBB, 0xA2, 0x35, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x59, 0x62, 0xB0, 0x4B, 0x1E, 0xB4, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x55, 0xCE, 0xB0, 0x69, 0xBA, 0x63, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x69, 0x86, 0xDB, 0x34, 0x7D, 0x68, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x06, 0xCA, 0x55, 0x44, 0x36, 0x2B, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xD4, 0xC4, 0x3D, 0xCD, 0x9E, 0x69, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x44, 0xE4, 0xBF, 0x31, 0xE6, 0x40, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x4F, 0xFA, 0x75, 0xE3, 0xFB, 0x97, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xC0, 0xBD, 0x1C, 0x48, 0xB0, 0x26, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x7B, 0x32, 0xFA, 0xF2, 0x6D, 0x84, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x21, 0x03, 0x1D, 0x0D, 0x22, 0x55, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xF9, 0x42, 0x03, 0x9C, 0xC2, 0xCB, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xA1, 0x96, 0xD9, 0x9D, 0x11, 0x6F, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x40, 0x57, 0xEB, 0x40, 0x2D, 0xC0, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x96, 0xBB, 0x4F, 0x2F, 0x23, 0xA8, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x29, 0x85, 0x21, 0xA5, 0x50, 0x62, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x7D, 0x92, 0xCF, 0x87, 0x0C, 0x22, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x0E, 0xA5, 0x32, 0x5B, 0xDF, 0x9C, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x96, 0x37, 0x2C, 0x88, 0x35, 0x30, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xB4, 0x69, 0xFF, 0xEB, 0xC6, 0x94, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x55, 0x60, 0xAD, 0xAA, 0x58, 0x14, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xFF, 0xF2, 0xB2, 0xD5, 0xA7, 0xD9, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xAE, 0x54, 0xD2, 0x60, 0x31, 0xF3, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x92, 0x83, 0xE3, 0xF1, 0x42, 0x83, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD2, 0xC8, 0xB7, 0x76, 0x45, 0x7F, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x11, 0xA4, 0xFB, 0x7A, 0x01, 0xBC, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x27, 0x73, 0x8D, 0x02, 0x91, 0x27, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x62, 0xF6, 0xDD, 0x6B, 0xFA, 0x5B, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCA, 0xA2, 0x44, 0x2C, 0xF0, 0x28, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xF1, 0x7A, 0xA2, 0x42, 0x4C, 0x50, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x83, 0x3E, 0x50, 0xAB, 0x9C, 0xF7, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xED, 0x78, 0xCB, 0x76, 0x69, 0xDA, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x1E, 0x43, 0x27, 0x47, 0x6E, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x4F, 0x54, 0xB9, 0x3E, 0xBD, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x40, 0x69, 0x7F, 0x74, 0x9D, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x06, 0x6F, 0x67, 0x68, 0x2B, 0x4D, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x65, 0x41, 0xFC, 0x7C, 0x1E, 0xE8, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x79, 0x37, 0xAF, 0xFD, 0xD2, 0xDA, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xA8, 0x69, 0x56, 0x62, 0xA4, 0xE4, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x71, 0x73, 0x21, 0x8A, 0x17, 0x81, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x55, 0x8F, 0x7B, 0xB8, 0xAF, 0xF7, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xD1, 0xBD, 0xBE, 0x8C, 0xBC, 0x60, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA6, 0x57, 0x8C, 0xAE, 0x5C, 0x19, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x43, 0xE4, 0xD9, 0xD8, 0x7B, 0xE7, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xB9, 0xE4, 0x85, 0x7C, 0x2E, 0xFC, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2E, 0x01, 0x2A, 0x6D, 0x56, 0xBE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x0C, 0x25, 0x9B, 0xAE, 0x86, 0x37, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x22, 0xB3, 0xCB, 0x99, 0x66, 0xB7, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xF7, 0x90, 0xF0, 0x1B, 0x09, 0x27, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x16, 0x08, 0xEF, 0x39, 0x64, 0x49, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA0, 0xE3, 0x97, 0xA9, 0x07, 0x54, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xFF, 0xE2, 0x00, 0x07, 0x21, 0x88, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFD, 0x59, 0x53, 0x05, 0x6C, 0x42, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xF7, 0x39, 0x5C, 0x82, 0x36, 0xE8, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x83, 0xA8, 0xE2, 0xA8, 0x43, 0x07, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xAF, 0x2B, 0x79, 0xED, 0xD8, 0x39, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x20, 0x91, 0x7A, 0xC4, 0x07, 0xEF, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x2F, 0xAA, 0x0C, 0x94, 0x0E, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x81, 0x87, 0x41, 0x23, 0xEB, 0x55, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x53, 0xCC, 0x79, 0xB6, 0xEB, 0x6C, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x77, 0x73, 0x9D, 0xFC, 0x64, 0x6F, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x40, 0xE3, 0x6D, 0x1C, 0x16, 0x71, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xF4, 0x1B, 0xFF, 0x1C, 0x2F, 0xA5, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x0E, 0x0B, 0x11, 0xF4, 0x8D, 0x93, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC5, 0x64, 0x6F, 0x24, 0x19, 0xF2, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xB3, 0xAF, 0xA5, 0x0E, 0x4F, 0x5E, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x77, 0xCA, 0xF2, 0x6D, 0xC5, 0xF6, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x18, 0x8E, 0x33, 0x68, 0x6C, 0xE8, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x8B, 0x80, 0x90, 0x19, 0x7F, 0x90, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x80, 0x6B, 0x68, 0xE2, 0x7D, 0xD4, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC1, 0x67, 0xB3, 0x72, 0xCB, 0xBF, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xD5, 0xD3, 0x1D, 0x14, 0x58, 0x0A, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x7A, 0x65, 0x98, 0xB3, 0x07, 0x4B, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x87, 0x0F, 0x5F, 0xCF, 0xA2, 0x01, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC9, 0xC8, 0x6E, 0x35, 0x87, 0xA5, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x3E, 0x91, 0xA0, 0xAB, 0x24, 0x1E, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBC, 0x02, 0x35, 0x70, 0xC1, 0x5F, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x59, 0xA0, 0x50, 0x04, 0x80, 0x52, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x56, 0x6E, 0x42, 0x8F, 0x8C, 0x91, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xA2, 0xCB, 0xA5, 0xDE, 0x14, 0x24, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xCB, 0x74, 0x28, 0xE6, 0xA7, 0xE7, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x73, 0xA8, 0x8F, 0x9E, 0x0E, 0x63, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x1B, 0x77, 0xC7, 0xC1, 0x38, 0xF9, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x3C, 0xCF, 0xA8, 0x7A, 0xD7, 0xF3, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x5F, 0x9A, 0xC9, 0xAD, 0xE9, 0x1A, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0x2B, 0x5E, 0xD5, 0x81, 0x95, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x88, 0x75, 0x29, 0x1F, 0xC7, 0xC7, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA9, 0x5A, 0x4D, 0x63, 0x95, 0xF9, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xCD, 0x04, 0x8F, 0xCD, 0x91, 0xDE, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xD4, 0xFD, 0x25, 0x11, 0x99, 0x6E, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x83, 0x01, 0x3D, 0xFB, 0x56, 0xA5, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x3A, 0xDC, 0x74, 0xC2, 0xD7, 0xCF, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xBD, 0xF1, 0xDD, 0xA3, 0x07, 0x03, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xBE, 0xE9, 0x2E, 0x58, 0x84, 0x66, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x20, 0x78, 0x37, 0x79, 0x0B, 0xA6, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xF2, 0xAC, 0x65, 0xC8, 0xC9, 0x2F, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x93, 0xE5, 0x0D, 0x0C, 0xC6, 0xB8, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAD, 0x5C, 0x19, 0x12, 0x61, 0x0E, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x4F, 0x0B, 0x1F, 0x49, 0x7E, 0xCD, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2E, 0x30, 0x61, 0xDB, 0x08, 0x68, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x78, 0xAF, 0xB3, 0x08, 0xC1, 0x69, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x5F, 0x5D, 0xC1, 0x57, 0x6F, 0xD8, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xD3, 0x6A, 0xF7, 0xFD, 0x86, 0xE5, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x63, 0xBD, 0x70, 0x7B, 0x47, 0xE8, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x62, 0xC8, 0x7E, 0x9D, 0x11, 0x2B, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x84, 0xFD, 0xD5, 0x9A, 0x56, 0x7F, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBB, 0xA4, 0x6F, 0x12, 0x6E, 0x4D, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x08, 0xA1, 0x82, 0x9C, 0x62, 0x74, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x22, 0x05, 0x1D, 0x15, 0x35, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x88, 0xCF, 0x5C, 0x05, 0x78, 0xFB, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x6B, 0x2F, 0x79, 0x09, 0x73, 0x67, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA0, 0x80, 0xD8, 0xE8, 0xEC, 0xFB, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0B, 0xB7, 0x81, 0x48, 0x7B, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x53, 0xA9, 0xED, 0x61, 0x92, 0xD7, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x49, 0xD9, 0x5D, 0x9B, 0x4E, 0x89, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x12, 0xEB, 0x9A, 0xC9, 0xCB, 0xC1, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xDC, 0x95, 0x16, 0xFE, 0x29, 0x70, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x33, 0xB1, 0xD6, 0x78, 0xB9, 0xE2, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xCE, 0x88, 0xC3, 0xFD, 0x7A, 0x6B, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x1E, 0x50, 0x1E, 0xAF, 0xB1, 0x25, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xE7, 0xD7, 0xD5, 0xBD, 0x7A, 0x12, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xAA, 0xA2, 0x80, 0x5D, 0x8F, 0xCD, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x39, 0x79, 0x64, 0xA1, 0x67, 0x3C, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xC7, 0x49, 0xFF, 0x7F, 0xAC, 0xAB, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x54, 0x3E, 0x83, 0xF0, 0x3D, 0xBC, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x92, 0x4A, 0x38, 0x42, 0x8A, 0xAB, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x0B, 0x4F, 0xEE, 0x9E, 0x92, 0xA5, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xDD, 0x19, 0x96, 0xF2, 0xF0, 0x6B, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xFC, 0xDD, 0xB2, 0x8A, 0xE5, 0x4C, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x06, 0x49, 0xAC, 0x99, 0x7E, 0xF8, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xC8, 0x01, 0x51, 0xEA, 0xF6, 0x52, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x89, 0x66, 0x2B, 0x1F, 0x9B, 0x2A, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x0F, 0x95, 0x07, 0x2B, 0x6C, 0x6E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC3, 0xB4, 0xBB, 0x91, 0x1F, 0xA3, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x6E, 0x54, 0x28, 0x7B, 0x9C, 0x79, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x45, 0xFF, 0xA6, 0xDA, 0xA2, 0x83, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xDE, 0x8F, 0x17, 0x37, 0x82, 0xCB, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x94, 0x3F, 0x26, 0xC9, 0x1D, 0xD9, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x28, 0x20, 0xCD, 0xC1, 0xF3, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC9, 0xB5, 0x60, 0x9B, 0x1E, 0xDC, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xB9, 0x5B, 0x7D, 0xA0, 0xB2, 0x8C, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xD1, 0x42, 0xE6, 0x39, 0x33, 0x6D, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xC0, 0xFC, 0xD2, 0x14, 0x5D, 0x3E, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x4A, 0x3E, 0x40, 0x16, 0x93, 0x15, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x24, 0xC1, 0x27, 0x27, 0xE5, 0x4B, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x50, 0xD8, 0xBC, 0xC1, 0x46, 0x22, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x0E, 0x60, 0xA1, 0xB3, 0x50, 0xD4, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xB1, 0x26, 0xB6, 0x6D, 0x47, 0x5A, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0xAC, 0x11, 0x35, 0x3E, 0xB9, 0xF4, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x97, 0xFA, 0xBB, 0x6B, 0x39, 0x13, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x34, 0x12, 0x75, 0x8E, 0x9B, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x9E, 0xCD, 0x29, 0xB6, 0xEF, 0x8D, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xAC, 0xE9, 0x25, 0x27, 0xBB, 0x78, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x7A, 0xA8, 0xD3, 0xE3, 0x66, 0xE5, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x4C, 0xC4, 0x2C, 0x76, 0x81, 0x50, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x71, 0x08, 0xB8, 0x52, 0x7C, 0xAF, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x59, 0x24, 0xDD, 0xFB, 0x2F, 0xD0, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCD, 0x56, 0xE9, 0xAC, 0x91, 0xE6, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x64, 0x20, 0xC6, 0x9F, 0xE4, 0xEF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x2C, 0x8F, 0x8C, 0x97, 0xF6, 0x22, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0x88, 0xAA, 0xA8, 0xD7, 0xA5, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x6C, 0xAE, 0x83, 0xB1, 0x55, 0x55, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x67, 0x84, 0x47, 0x7C, 0x83, 0x5C, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x10, 0x4D, 0xDD, 0x30, 0x60, 0xB0, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xA7, 0x36, 0x76, 0x24, 0x32, 0x9F, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x42, 0x81, 0xFB, 0xA4, 0x2E, 0x13, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x94, 0x91, 0xFF, 0x99, 0xA0, 0x09, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x83, 0xA1, 0x76, 0xAF, 0x37, 0x5C, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA8, 0x04, 0x86, 0xC4, 0xA9, 0x79, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8C, 0xC2, 0x34, 0xFB, 0x83, 0x28, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x03, 0x7D, 0x5E, 0x9E, 0x0E, 0xB0, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x02, 0x46, 0x7F, 0xB9, 0xAC, 0xBB, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xED, 0x48, 0xC2, 0x96, 0x4D, 0x56, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xC5, 0xD1, 0xE6, 0x1C, 0x7E, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x2E, 0x18, 0x71, 0x2D, 0x7B, 0xD7, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x46, 0x9D, 0xDE, 0xAA, 0x78, 0x8E, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD7, 0x69, 0x2E, 0xE1, 0xD9, 0x48, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFF, 0x9E, 0x09, 0x22, 0x22, 0xE6, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x14, 0x28, 0x13, 0x1B, 0x62, 0x12, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x7F, 0x67, 0x03, 0xB0, 0xC0, 0xF3, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xC3, 0x0F, 0xFB, 0x25, 0x48, 0x3E, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x6E, 0x53, 0x98, 0x36, 0xB3, 0xD3, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x81, 0x54, 0x22, 0xA4, 0xCC, 0xC1, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xBA, 0xFC, 0xA9, 0xDF, 0x68, 0x86, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x92, 0x0E, 0xC3, 0xF2, 0x58, 0xE8, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp521r1_T[32] = { - ECP_POINT_INIT_XY_Z1(secp521r1_T_0_X, secp521r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_1_X, secp521r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_2_X, secp521r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_3_X, secp521r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_4_X, secp521r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_5_X, secp521r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_6_X, secp521r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_7_X, secp521r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_8_X, secp521r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_9_X, secp521r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_10_X, secp521r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_11_X, secp521r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_12_X, secp521r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_13_X, secp521r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_14_X, secp521r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_15_X, secp521r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_16_X, secp521r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_17_X, secp521r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_18_X, secp521r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_19_X, secp521r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_20_X, secp521r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_21_X, secp521r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_22_X, secp521r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_23_X, secp521r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_24_X, secp521r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_25_X, secp521r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_26_X, secp521r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_27_X, secp521r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_28_X, secp521r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_29_X, secp521r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_30_X, secp521r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_31_X, secp521r1_T_31_Y), -}; -#else -#define secp521r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static const mbedtls_mpi_uint secp192k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp192k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp192k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00), -}; -static const mbedtls_mpi_uint secp192k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), -}; -static const mbedtls_mpi_uint secp192k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), -}; -static const mbedtls_mpi_uint secp192k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp192k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), -}; -static const mbedtls_mpi_uint secp192k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), -}; -static const mbedtls_mpi_uint secp192k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x77, 0x3D, 0x0D, 0x85, 0x48, 0xA8, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x07, 0xDF, 0x1D, 0xB3, 0xB3, 0x01, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x86, 0xF6, 0xAF, 0x19, 0x2A, 0x88, 0x2E), -}; -static const mbedtls_mpi_uint secp192k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x90, 0xB6, 0x2F, 0x48, 0x36, 0x4C, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x11, 0x14, 0xA6, 0xCB, 0xBA, 0x15, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB0, 0xF2, 0xD4, 0xC9, 0xDA, 0xBA, 0xD7), -}; -static const mbedtls_mpi_uint secp192k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xC1, 0x9C, 0xE6, 0xBB, 0xFB, 0xCF, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x19, 0xAC, 0x5A, 0xC9, 0x8A, 0x1C, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xF6, 0x76, 0x86, 0x89, 0x27, 0x8D, 0x28), -}; -static const mbedtls_mpi_uint secp192k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xE0, 0x6F, 0x34, 0xBA, 0x5E, 0xD3, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xDC, 0xA6, 0x87, 0xC9, 0x9D, 0xC0, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x11, 0x7E, 0xD6, 0xF7, 0x33, 0xFC, 0xE4), -}; -static const mbedtls_mpi_uint secp192k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x37, 0x3E, 0xC0, 0x7F, 0x62, 0xE7, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3B, 0x69, 0x9D, 0x44, 0xBC, 0x82, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x84, 0xB3, 0x5F, 0x2B, 0xA5, 0x9E, 0x2C), -}; -static const mbedtls_mpi_uint secp192k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x95, 0xEB, 0x4C, 0x04, 0xB4, 0xF4, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAD, 0x4B, 0xD5, 0x9A, 0xEB, 0xC4, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xB1, 0xC5, 0x59, 0xE3, 0xD5, 0x16, 0x2A), -}; -static const mbedtls_mpi_uint secp192k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x2A, 0xCC, 0xAC, 0xD0, 0xEE, 0x50, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x83, 0xE0, 0x5B, 0x14, 0x44, 0x52, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x15, 0x2D, 0x78, 0xF6, 0x51, 0x32, 0xCF), -}; -static const mbedtls_mpi_uint secp192k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x36, 0x9B, 0xDD, 0xF8, 0xDD, 0xEF, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xB1, 0x6A, 0x2B, 0xAF, 0xEB, 0x2B, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x87, 0x7A, 0x66, 0x5D, 0x5B, 0xDF, 0x8F), -}; -static const mbedtls_mpi_uint secp192k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x45, 0xE5, 0x81, 0x9B, 0xEB, 0x37, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x29, 0xE2, 0x20, 0x64, 0x23, 0x6B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1D, 0x41, 0xE1, 0x9B, 0x61, 0x7B, 0xD9), -}; -static const mbedtls_mpi_uint secp192k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x57, 0xA3, 0x0A, 0x13, 0xE4, 0x59, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x6E, 0x4A, 0x48, 0x84, 0x90, 0xAC, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB8, 0xF5, 0xF3, 0xDE, 0xA0, 0xA1, 0x1D), -}; -static const mbedtls_mpi_uint secp192k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x32, 0x81, 0xA9, 0x91, 0x5A, 0x4E, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xA8, 0x90, 0xBE, 0x0F, 0xEC, 0xC0, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x30, 0xD7, 0x08, 0xAE, 0xC4, 0x3A, 0xA5), -}; -static const mbedtls_mpi_uint secp192k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x55, 0xE3, 0x76, 0xB3, 0x64, 0x74, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x75, 0xD4, 0xDB, 0x98, 0xD7, 0x39, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xEB, 0x8A, 0xAB, 0x16, 0xD9, 0xD4, 0x0B), -}; -static const mbedtls_mpi_uint secp192k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xBE, 0xF9, 0xC7, 0xC7, 0xBA, 0xF3, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x85, 0x59, 0xF3, 0x60, 0x41, 0x02, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x1C, 0x4A, 0xA4, 0xC7, 0xED, 0x66, 0xBC), -}; -static const mbedtls_mpi_uint secp192k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x2E, 0x46, 0x52, 0x18, 0x87, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x35, 0x5A, 0x75, 0xAC, 0x4D, 0x75, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x2F, 0xAC, 0xFC, 0xBC, 0xE6, 0x93, 0x5E), -}; -static const mbedtls_mpi_uint secp192k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x4D, 0xC9, 0x18, 0xE9, 0x00, 0xEB, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x69, 0x72, 0x07, 0x5A, 0x59, 0xA8, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x65, 0x83, 0x20, 0x10, 0xF9, 0x69, 0x82), -}; -static const mbedtls_mpi_uint secp192k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x56, 0x7F, 0x9F, 0xBF, 0x46, 0x0C, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0xF0, 0xDC, 0xDF, 0x2D, 0xE6, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xF0, 0x72, 0x3A, 0x7A, 0x03, 0xE5, 0x22), -}; -static const mbedtls_mpi_uint secp192k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xAA, 0x57, 0x13, 0x37, 0xA7, 0x2C, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xAC, 0xA2, 0x23, 0xF9, 0x84, 0x60, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xEB, 0x51, 0x70, 0x64, 0x78, 0xCA, 0x05), -}; -static const mbedtls_mpi_uint secp192k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xCC, 0x30, 0x62, 0x93, 0x46, 0x13, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x26, 0xCC, 0x6C, 0x3D, 0x5C, 0xDA, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xAA, 0xB8, 0x03, 0xA4, 0x1A, 0x00, 0x96), -}; -static const mbedtls_mpi_uint secp192k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x9D, 0xE6, 0xCC, 0x4E, 0x2E, 0xC2, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xC3, 0x8A, 0xAE, 0x6F, 0x40, 0x05, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x8F, 0x4A, 0x4D, 0x35, 0xD3, 0x50, 0x9D), -}; -static const mbedtls_mpi_uint secp192k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xFD, 0x98, 0xAB, 0xC7, 0x03, 0xB4, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x40, 0xD2, 0x9F, 0xCA, 0xD0, 0x53, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x84, 0x00, 0x6F, 0xC8, 0xAD, 0xED, 0x8D), -}; -static const mbedtls_mpi_uint secp192k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xD3, 0x57, 0xD7, 0xC3, 0x07, 0xBD, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xBA, 0x47, 0x1D, 0x3D, 0xEF, 0x98, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC0, 0x6C, 0x7F, 0x12, 0xEE, 0x9F, 0x67), -}; -static const mbedtls_mpi_uint secp192k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x02, 0xDA, 0x79, 0xAA, 0xC9, 0x27, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x79, 0xC7, 0x71, 0x84, 0xCB, 0xE5, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x37, 0x06, 0xBA, 0xB5, 0xD5, 0x18, 0x4C), -}; -static const mbedtls_mpi_uint secp192k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x65, 0x72, 0x6C, 0xF2, 0x63, 0x27, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xBC, 0x71, 0xDF, 0x75, 0xF8, 0x98, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x70, 0x9B, 0xDC, 0xE7, 0x18, 0x71, 0xFF), -}; -static const mbedtls_mpi_uint secp192k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x5B, 0x9F, 0x00, 0x5A, 0xB6, 0x80, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE0, 0xBB, 0xFC, 0x5E, 0x78, 0x9C, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x03, 0x68, 0x83, 0x3D, 0x2E, 0x4C, 0xDD), -}; -static const mbedtls_mpi_uint secp192k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x49, 0x23, 0xA8, 0xCB, 0x3B, 0x1A, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x3D, 0xA7, 0x46, 0xCF, 0x75, 0xB6, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xFD, 0x30, 0x01, 0xB6, 0xEF, 0xF9, 0xE8), -}; -static const mbedtls_mpi_uint secp192k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xFA, 0xDA, 0xB8, 0x29, 0x42, 0xC9, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xD7, 0xA0, 0xE6, 0x6B, 0x86, 0x61, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xE9, 0xD3, 0x37, 0xD8, 0xE7, 0x35, 0xA9), -}; -static const mbedtls_mpi_uint secp192k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC8, 0x8E, 0xB1, 0xCB, 0xB1, 0xB5, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xD7, 0x46, 0x7D, 0xAF, 0xE2, 0xDC, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x46, 0xE7, 0xD8, 0x76, 0x31, 0x90, 0x76), -}; -static const mbedtls_mpi_uint secp192k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD3, 0xF4, 0x74, 0xE1, 0x67, 0xD8, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x70, 0x3C, 0xC8, 0xAF, 0x5F, 0xF4, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x4E, 0xED, 0x5C, 0x43, 0xB3, 0x16, 0x35), -}; -static const mbedtls_mpi_uint secp192k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAE, 0xD1, 0xDD, 0x31, 0x14, 0xD3, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x14, 0x06, 0x13, 0x12, 0x1C, 0x81, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xF9, 0x0C, 0x91, 0xF7, 0x67, 0x59, 0x63), -}; -static const mbedtls_mpi_uint secp192k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x91, 0xE2, 0xF4, 0x9D, 0xEB, 0x88, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x82, 0x30, 0x9C, 0xAE, 0x18, 0x4D, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x79, 0xCF, 0x17, 0xA5, 0x1E, 0xE8, 0xC8), -}; -static const mbedtls_ecp_point secp192k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp192k1_T_0_X, secp192k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_1_X, secp192k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_2_X, secp192k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_3_X, secp192k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_4_X, secp192k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_5_X, secp192k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_6_X, secp192k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_7_X, secp192k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_8_X, secp192k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_9_X, secp192k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_10_X, secp192k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_11_X, secp192k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_12_X, secp192k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_13_X, secp192k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_14_X, secp192k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_15_X, secp192k1_T_15_Y), -}; -#else -#define secp192k1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static const mbedtls_mpi_uint secp224k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp224k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_4(0x33, 0x5B, 0x45, 0xA1), -}; -static const mbedtls_mpi_uint secp224k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_4(0xED, 0x9F, 0x08, 0x7E), -}; -static const mbedtls_mpi_uint secp224k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp224k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x5B, 0x45, 0xA1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x9F, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x6C, 0x22, 0x22, 0x40, 0x89, 0xAE, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x92, 0xE1, 0x87, 0x56, 0x35, 0xAF, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xAF, 0x08, 0x35, 0x27, 0xEA, 0x04, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x53, 0xFD, 0xCF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xD0, 0x9F, 0x8D, 0xF3, 0x63, 0x54, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xDB, 0x0F, 0x61, 0x54, 0x26, 0xD1, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x21, 0xF7, 0x1B, 0xB5, 0x1D, 0xF6, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x05, 0xDA, 0x8F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x26, 0x73, 0xBC, 0xE4, 0x29, 0x62, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x95, 0x17, 0x8B, 0xC3, 0x9B, 0xAC, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xDB, 0x77, 0xDF, 0xDD, 0x13, 0x04, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xFC, 0x22, 0x93, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0xF1, 0x5A, 0x37, 0xEF, 0x79, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x37, 0xAC, 0x9A, 0x5B, 0x51, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x75, 0x13, 0xA9, 0x4A, 0xAD, 0xFE, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x82, 0x6F, 0x66, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x5E, 0xF0, 0x40, 0xC3, 0xA6, 0xE2, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x9A, 0x6F, 0xCF, 0x11, 0x26, 0x66, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x73, 0xA8, 0xCF, 0x2B, 0x12, 0x36, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xB3, 0x0A, 0x58, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x79, 0x00, 0x55, 0x04, 0x34, 0x90, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x54, 0x1C, 0xC2, 0x45, 0x0C, 0x1B, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x19, 0xAB, 0xA8, 0xFC, 0x73, 0xDC, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xFB, 0x93, 0xCE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x75, 0xD0, 0x66, 0x95, 0x86, 0xCA, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xEA, 0x29, 0x16, 0x6A, 0x38, 0xDF, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA2, 0x36, 0x2F, 0xDC, 0xBB, 0x5E, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x89, 0x59, 0x49, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xA3, 0x99, 0x9D, 0xB8, 0x77, 0x9D, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x93, 0x43, 0x47, 0xC6, 0x5C, 0xF9, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x00, 0x79, 0x42, 0x64, 0xB8, 0x25, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x54, 0xB4, 0x33, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x0C, 0x42, 0x90, 0x83, 0x0B, 0x31, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2E, 0xAE, 0xC8, 0xC7, 0x5F, 0xD2, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xBC, 0xAD, 0x41, 0xE7, 0x32, 0x3A, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x97, 0x52, 0x83, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x13, 0x7A, 0xBD, 0xAE, 0x94, 0x60, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x9B, 0x95, 0xB4, 0x6E, 0x68, 0xB2, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x49, 0xBE, 0x51, 0xFE, 0x66, 0x15, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x37, 0xE4, 0xFE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x9B, 0xEE, 0x64, 0xC9, 0x1B, 0xBD, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x5F, 0x34, 0xA9, 0x0B, 0xB7, 0x25, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x13, 0xB1, 0x38, 0xFB, 0x9D, 0x78, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xE7, 0x1B, 0xFA, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xB3, 0xB7, 0x44, 0x92, 0x6B, 0x00, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x82, 0x44, 0x3E, 0x18, 0x1A, 0x58, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF8, 0xC0, 0xE4, 0xEE, 0xC1, 0xBF, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x32, 0x27, 0xB2, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x9A, 0x42, 0x62, 0x8B, 0x26, 0x54, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x85, 0x74, 0xA0, 0x79, 0xA8, 0xEE, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0x60, 0xB3, 0x28, 0x4D, 0x55, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x27, 0x82, 0x29, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xFC, 0x73, 0x77, 0xAF, 0x5C, 0xAC, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xED, 0xE5, 0xF6, 0x1D, 0xA8, 0x67, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xDE, 0x33, 0x1C, 0xF1, 0x80, 0x73, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE2, 0xDE, 0x3C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x3E, 0x6B, 0xFE, 0xF0, 0x04, 0x28, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xB2, 0x14, 0x9D, 0x18, 0x11, 0x7D, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC4, 0xD6, 0x2E, 0x6E, 0x57, 0x4D, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x55, 0x1B, 0xDE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xF7, 0x17, 0xBC, 0x45, 0xAB, 0x16, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xB0, 0xEF, 0x61, 0xE3, 0x20, 0x7C, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x85, 0x41, 0x4D, 0xF1, 0x7E, 0x4D, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC2, 0x9B, 0x5E, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x2E, 0x49, 0x3D, 0x3E, 0x4B, 0xD3, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x2B, 0x9D, 0xD5, 0x27, 0xFA, 0xCA, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xB3, 0x6A, 0xE0, 0x79, 0x14, 0x28, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x1E, 0xDC, 0xF5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x44, 0x56, 0xCD, 0xFC, 0x9F, 0x09, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x8C, 0x59, 0xA4, 0x64, 0x2A, 0x3A, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xA0, 0xB5, 0x86, 0x4E, 0x69, 0xDA, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x8B, 0x11, 0x38, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x17, 0x16, 0x12, 0x17, 0xDC, 0x00, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x76, 0x24, 0x6C, 0x97, 0x2C, 0xB5, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x71, 0xE3, 0xB0, 0xBB, 0x4E, 0x50, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x48, 0x26, 0xD5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x5F, 0x28, 0xF6, 0x01, 0x5A, 0x60, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x95, 0xFE, 0xD0, 0xAD, 0x15, 0xD4, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0x7A, 0xFD, 0x80, 0xF7, 0x9F, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xBC, 0x1B, 0xDF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xE6, 0xDF, 0x14, 0x29, 0xF4, 0xD4, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x12, 0xDD, 0xEC, 0x5B, 0x8A, 0x59, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x92, 0x3E, 0x35, 0x08, 0xE9, 0xCF, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x35, 0x29, 0x97, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xDB, 0xD6, 0x6A, 0xC5, 0x43, 0xA4, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x33, 0x50, 0x61, 0x70, 0xA1, 0xE9, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x15, 0x6E, 0x5F, 0x01, 0x0C, 0x8C, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xA1, 0x9A, 0x9D, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xC6, 0xF7, 0xE2, 0x4A, 0xCD, 0x9B, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x4D, 0x5A, 0xB8, 0xE2, 0x6D, 0xA6, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3F, 0xB6, 0x17, 0xE3, 0x2C, 0x6F, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA4, 0x59, 0x51, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x4F, 0x7C, 0x49, 0xCD, 0x6E, 0xEB, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xC9, 0x1F, 0xB7, 0x4D, 0x98, 0xC7, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xFD, 0x98, 0x20, 0x95, 0xBB, 0x20, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF2, 0x73, 0x92, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xEF, 0xFB, 0x30, 0xFA, 0x12, 0x1A, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x4C, 0x24, 0xB4, 0x5B, 0xC9, 0x4C, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xDD, 0x5E, 0x84, 0x95, 0x4D, 0x26, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xFA, 0xF9, 0x3A, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xA3, 0x2E, 0x7A, 0xDC, 0xA7, 0x53, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x9F, 0x81, 0x84, 0xB2, 0x0D, 0xFE, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x89, 0x1B, 0x77, 0x0C, 0x89, 0x71, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0x7F, 0xB2, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xE9, 0x2C, 0x79, 0xA6, 0x3C, 0xAD, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE0, 0x23, 0x02, 0x86, 0x0F, 0x77, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x93, 0x6D, 0xE9, 0xF9, 0x3C, 0xBE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xE7, 0x24, 0x92, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x3C, 0x5B, 0x4B, 0x1B, 0x25, 0x37, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xE8, 0x38, 0x1B, 0xA1, 0x5A, 0x2E, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x19, 0xFD, 0xF4, 0x78, 0x01, 0x6B, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x69, 0x37, 0x4F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xE2, 0xBF, 0xD3, 0xEC, 0x95, 0x9C, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x7B, 0xFC, 0xD5, 0xD3, 0x25, 0x5E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x55, 0x09, 0xA2, 0x58, 0x6A, 0xC9, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xCC, 0x3B, 0xD9, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x08, 0x65, 0x5E, 0xCB, 0xAB, 0x48, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x79, 0x8B, 0xC0, 0x11, 0xC0, 0x69, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xE8, 0x8C, 0x4C, 0xC5, 0x28, 0xE4, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x1F, 0x34, 0x5C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp224k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp224k1_T_0_X, secp224k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_1_X, secp224k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_2_X, secp224k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_3_X, secp224k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_4_X, secp224k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_5_X, secp224k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_6_X, secp224k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_7_X, secp224k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_8_X, secp224k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_9_X, secp224k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_10_X, secp224k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_11_X, secp224k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_12_X, secp224k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_13_X, secp224k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_14_X, secp224k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_15_X, secp224k1_T_15_Y), -}; -#else -#define secp224k1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static const mbedtls_mpi_uint secp256k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp256k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp256k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00), -}; -static const mbedtls_mpi_uint secp256k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), -}; -static const mbedtls_mpi_uint secp256k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), -}; -static const mbedtls_mpi_uint secp256k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp256k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), -}; -static const mbedtls_mpi_uint secp256k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), -}; -static const mbedtls_mpi_uint secp256k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xEE, 0xD7, 0x1E, 0x67, 0x86, 0x32, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0xB1, 0xA9, 0xD5, 0xCC, 0x27, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0E, 0x11, 0x01, 0x71, 0xFE, 0x92, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x28, 0x63, 0x6D, 0x72, 0x09, 0xA6, 0xC0), -}; -static const mbedtls_mpi_uint secp256k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0x69, 0xDC, 0x3E, 0x2C, 0x75, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xB7, 0x3F, 0x30, 0x26, 0x3C, 0xDF, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBE, 0xB9, 0x5D, 0x0E, 0xE8, 0x5E, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xC3, 0x05, 0xD6, 0xB7, 0xD5, 0x24, 0xFC), -}; -static const mbedtls_mpi_uint secp256k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCF, 0x7B, 0xDC, 0xCD, 0xC3, 0x39, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xDA, 0xB9, 0xE5, 0x64, 0xA7, 0x47, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x46, 0xA8, 0x61, 0xF6, 0x23, 0xEB, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xC1, 0xFF, 0xE4, 0x55, 0xD5, 0xC2, 0xBF), -}; -static const mbedtls_mpi_uint secp256k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xBE, 0xB9, 0x59, 0x24, 0x13, 0x4A, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x45, 0x12, 0xDE, 0xBA, 0x4F, 0xEF, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x08, 0xBF, 0xC1, 0x66, 0xAA, 0x0A, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xFE, 0x30, 0x55, 0x31, 0x86, 0xA7, 0xB4), -}; -static const mbedtls_mpi_uint secp256k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBF, 0x18, 0x81, 0x67, 0x27, 0x42, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x05, 0x83, 0xA4, 0xDD, 0x57, 0xD3, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x63, 0xAB, 0xE4, 0x90, 0x70, 0xD0, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x5D, 0xFD, 0xA0, 0xEF, 0xCF, 0x1C, 0x54), -}; -static const mbedtls_mpi_uint secp256k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x80, 0xE4, 0xF6, 0x09, 0xBC, 0x57, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x9F, 0x6E, 0x88, 0x54, 0x6E, 0x51, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x5F, 0x85, 0xFB, 0x84, 0x3E, 0x4A, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x19, 0xF5, 0x55, 0xC9, 0x07, 0xD8, 0xCE), -}; -static const mbedtls_mpi_uint secp256k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xB4, 0xC3, 0xD9, 0x5C, 0xA0, 0xD4, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x30, 0xAF, 0x59, 0x9B, 0xF8, 0x04, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xA6, 0xFD, 0x66, 0x7B, 0xC3, 0x39, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xBF, 0xF0, 0xC2, 0xE9, 0x71, 0xA4, 0x9E), -}; -static const mbedtls_mpi_uint secp256k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x2D, 0xB9, 0x88, 0x28, 0xF1, 0xBE, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF3, 0x1A, 0x0E, 0xB9, 0x01, 0x66, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0xA4, 0xF4, 0x05, 0xD0, 0xAA, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x39, 0x1E, 0x47, 0xE5, 0x68, 0xC8, 0xC0), -}; -static const mbedtls_mpi_uint secp256k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xB9, 0xFC, 0xE0, 0x33, 0x8A, 0x7D, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x93, 0xA5, 0x53, 0x55, 0x16, 0xB4, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x5F, 0xEA, 0x9B, 0x29, 0x52, 0x71, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xF0, 0x24, 0xB8, 0x7D, 0xB7, 0xA0, 0x9B), -}; -static const mbedtls_mpi_uint secp256k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x00, 0x27, 0xB2, 0xDF, 0x73, 0xA2, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x2E, 0x4D, 0x7C, 0xDE, 0x7A, 0x23, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0x60, 0xC7, 0x97, 0x1E, 0xA4, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x13, 0x5B, 0x77, 0x59, 0xCB, 0x36, 0xE1), -}; -static const mbedtls_mpi_uint secp256k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xBC, 0x9F, 0x9E, 0x2D, 0x53, 0x2A, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x5F, 0x64, 0x9F, 0x1A, 0x19, 0xE6, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x7B, 0x39, 0xD2, 0xDB, 0x85, 0x84, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xC7, 0x0D, 0x58, 0x6E, 0x3F, 0x52, 0x15), -}; -static const mbedtls_mpi_uint secp256k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x68, 0x19, 0x0B, 0x68, 0xC9, 0x1E, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x4E, 0x21, 0x49, 0x3D, 0x55, 0xCC, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF9, 0x25, 0x45, 0x54, 0x45, 0xB1, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xF7, 0xCD, 0x80, 0xA4, 0x04, 0x05), -}; -static const mbedtls_mpi_uint secp256k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x1E, 0x88, 0xC4, 0xAA, 0x18, 0x7E, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xAC, 0xD9, 0xB2, 0xA1, 0xC0, 0x71, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xA2, 0xF1, 0x15, 0xA6, 0x5F, 0x6C, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x5B, 0x05, 0xBC, 0xB7, 0xC6, 0x4E, 0x72), -}; -static const mbedtls_mpi_uint secp256k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x80, 0xF8, 0x5C, 0x20, 0x2A, 0xE1, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x48, 0x2E, 0x68, 0x82, 0x7F, 0xEB, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x3B, 0x25, 0xDB, 0x32, 0x4D, 0x88, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x6E, 0xA6, 0xB6, 0x6D, 0x62, 0x78, 0x22), -}; -static const mbedtls_mpi_uint secp256k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4D, 0x3E, 0x86, 0x58, 0xC3, 0xEB, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x89, 0x33, 0x18, 0x21, 0x1D, 0x9B, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x9D, 0xFF, 0xC3, 0x79, 0xC1, 0x88, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xD4, 0x48, 0x53, 0xE8, 0xAD, 0x21, 0x16), -}; -static const mbedtls_mpi_uint secp256k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x7B, 0xDE, 0xCB, 0xD8, 0x39, 0x17, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xF3, 0x03, 0xF2, 0x5C, 0xBC, 0xC8, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xAE, 0x4C, 0xB0, 0x16, 0xA4, 0x93, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8B, 0x6B, 0xDC, 0xD7, 0x9A, 0x3E, 0x7E), -}; -static const mbedtls_mpi_uint secp256k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x2D, 0x7A, 0xD2, 0x59, 0x05, 0xA2, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x56, 0x09, 0x32, 0xF1, 0xE8, 0xE3, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xCA, 0xE5, 0x2E, 0xF0, 0xFB, 0x18, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x85, 0xA9, 0x23, 0x15, 0x31, 0x1F, 0x0E), -}; -static const mbedtls_mpi_uint secp256k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xE5, 0xB1, 0x86, 0xB9, 0x6E, 0x8D, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x77, 0xFC, 0xC9, 0xA3, 0x3F, 0x89, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x6A, 0xDC, 0x25, 0xB0, 0xC7, 0x41, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x11, 0x6B, 0xA6, 0x11, 0x62, 0xD4, 0x2D), -}; -static const mbedtls_mpi_uint secp256k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7D, 0x34, 0xB3, 0x20, 0x7F, 0x37, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xD4, 0x45, 0xE8, 0xC2, 0xE9, 0xC5, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x32, 0x3B, 0x25, 0x7E, 0x79, 0xAF, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xE4, 0x54, 0x71, 0xBE, 0x35, 0x4E, 0xD0), -}; -static const mbedtls_mpi_uint secp256k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x94, 0xDD, 0x8F, 0xB5, 0xC2, 0xDD, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x49, 0xE9, 0x1C, 0x2F, 0x08, 0x49, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xB6, 0x03, 0x88, 0x6F, 0xB8, 0x15, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xD3, 0x1C, 0xF3, 0xA5, 0xEB, 0x79, 0x01), -}; -static const mbedtls_mpi_uint secp256k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF9, 0x43, 0x88, 0x89, 0x0D, 0x06, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2D, 0xF5, 0x98, 0x32, 0xF6, 0xB1, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0x8F, 0x2B, 0x50, 0x27, 0x0A, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE3, 0xBD, 0x16, 0x05, 0xC8, 0x93, 0x12), -}; -static const mbedtls_mpi_uint secp256k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x6A, 0xF7, 0xE3, 0x3D, 0xDE, 0x5F, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA3, 0x9C, 0x22, 0x3C, 0x33, 0x36, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x24, 0x4C, 0x69, 0x45, 0x78, 0x14, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xF8, 0xD4, 0xBF, 0xB8, 0xC0, 0xA1, 0x25), -}; -static const mbedtls_mpi_uint secp256k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x88, 0xE1, 0x91, 0x03, 0xEB, 0xB3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x11, 0xA1, 0xEF, 0x14, 0x0D, 0xC4, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xD4, 0x0D, 0x1D, 0x96, 0x33, 0x5C, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x45, 0x2A, 0x1A, 0xE6, 0x57, 0x04, 0x9B), -}; -static const mbedtls_mpi_uint secp256k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xB5, 0xA7, 0x80, 0xE9, 0x93, 0x97, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xB9, 0x7C, 0xA0, 0xC9, 0x57, 0x26, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xEF, 0x56, 0xDA, 0x66, 0xF6, 0x1B, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x89, 0x6B, 0x91, 0xE0, 0xA9, 0x65, 0x2B), -}; -static const mbedtls_mpi_uint secp256k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x98, 0x96, 0x9B, 0x06, 0x7D, 0x5E, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xFA, 0xC1, 0x5F, 0x19, 0x37, 0x94, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xBE, 0x6B, 0x1A, 0x05, 0xE4, 0xBF, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xCD, 0x5D, 0x35, 0xB4, 0x51, 0xF7, 0x64), -}; -static const mbedtls_mpi_uint secp256k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xEF, 0x96, 0xDB, 0xF2, 0x61, 0x63, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x04, 0x88, 0xC9, 0x9F, 0x1B, 0x94, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x30, 0x79, 0x7E, 0x24, 0xE7, 0x5F, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xB8, 0x90, 0xB7, 0x94, 0x25, 0xBB, 0x0F), -}; -static const mbedtls_mpi_uint secp256k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x79, 0xEA, 0xAD, 0xC0, 0x6D, 0x18, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xA4, 0x58, 0x2A, 0x8D, 0x95, 0xB3, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC4, 0xC2, 0x12, 0x0D, 0x79, 0xE2, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6F, 0xBE, 0x97, 0x4D, 0xA4, 0x20, 0x07), -}; -static const mbedtls_mpi_uint secp256k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x31, 0x71, 0xC6, 0xA6, 0x91, 0xEB, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x9B, 0xA8, 0x4A, 0xE7, 0x77, 0xE1, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x06, 0xD3, 0x3D, 0x94, 0x30, 0xEF, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xDF, 0xCA, 0xFA, 0xF5, 0x28, 0xF8, 0xC9), -}; -static const mbedtls_mpi_uint secp256k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xE1, 0x32, 0xFD, 0x3E, 0x81, 0xF8, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xF2, 0x4B, 0x1D, 0x19, 0xC9, 0x0F, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB1, 0x8A, 0x22, 0x8B, 0x05, 0x6B, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x21, 0xEF, 0x30, 0xEC, 0x09, 0x2A, 0x89), -}; -static const mbedtls_mpi_uint secp256k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x84, 0x4A, 0x46, 0x07, 0x6C, 0x3C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x18, 0x3A, 0xF4, 0xCC, 0xF5, 0xB2, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x8F, 0xCD, 0x0A, 0x9C, 0xF4, 0xBD, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x89, 0x7F, 0x8A, 0xB1, 0x52, 0x3A, 0xAB), -}; -static const mbedtls_ecp_point secp256k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp256k1_T_0_X, secp256k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_1_X, secp256k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_2_X, secp256k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_3_X, secp256k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_4_X, secp256k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_5_X, secp256k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_6_X, secp256k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_7_X, secp256k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_8_X, secp256k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_9_X, secp256k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_10_X, secp256k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_11_X, secp256k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_12_X, secp256k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_13_X, secp256k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_14_X, secp256k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_15_X, secp256k1_T_15_Y), -}; -#else -#define secp256k1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), -}; -static const mbedtls_mpi_uint brainpoolP256r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP256r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xA2, 0xED, 0x52, 0xC9, 0x8C, 0xE3, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xC9, 0xC4, 0x87, 0x3F, 0x93, 0x7A, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x12, 0x53, 0x61, 0x3E, 0x76, 0x08, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x8C, 0x74, 0xF4, 0x08, 0xC3, 0x76, 0x80), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xDD, 0x09, 0xA6, 0xED, 0xEE, 0xC4, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xD9, 0xBE, 0x4B, 0xA5, 0xB7, 0x2B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x20, 0x12, 0xCA, 0x0A, 0x38, 0x24, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x72, 0x71, 0x90, 0x7A, 0x2E, 0xB7, 0x23), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0xA1, 0x93, 0x10, 0x2A, 0x51, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x10, 0x11, 0x12, 0xBC, 0xB0, 0xB6, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x58, 0xD7, 0x0A, 0x84, 0x05, 0xA3, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x8E, 0x95, 0x61, 0xD3, 0x0B, 0xDF, 0x36), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x92, 0x12, 0x0F, 0x5E, 0x87, 0x70, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xE9, 0x9B, 0xEB, 0x3A, 0xFB, 0xCF, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0x92, 0xB9, 0xF7, 0x45, 0xD3, 0x06, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x28, 0x65, 0xE1, 0xC5, 0x6C, 0x57, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x0E, 0x77, 0x01, 0x81, 0x9E, 0x38, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xF0, 0xD5, 0xA5, 0x91, 0x2B, 0xDF, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xEE, 0xB6, 0x25, 0xD6, 0x98, 0xDE, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0x55, 0x63, 0x39, 0xEB, 0xB5, 0x47), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD6, 0xB8, 0xE3, 0x13, 0xED, 0x7F, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xE8, 0xAE, 0x36, 0xB8, 0xCD, 0x19, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x82, 0x83, 0x7A, 0x7B, 0x46, 0x56, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x60, 0x46, 0x15, 0x5A, 0xAC, 0x99, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x61, 0x50, 0xC6, 0xFF, 0x10, 0x7D, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x51, 0xDF, 0xA9, 0x7D, 0x78, 0x26, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x15, 0x9A, 0xF7, 0x01, 0xC1, 0xBB, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x0F, 0xE6, 0x2A, 0xBD, 0x4A, 0x9E, 0x87), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF8, 0xD1, 0x77, 0xD2, 0x49, 0xB3, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x86, 0xFB, 0x9E, 0x1F, 0x5A, 0x60, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xC4, 0x8D, 0xCD, 0x86, 0x61, 0x2F, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xF6, 0xB9, 0xAC, 0x37, 0x9D, 0xE9, 0x28), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x77, 0xAA, 0x97, 0x9C, 0x0B, 0x04, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xA6, 0x60, 0x81, 0xCE, 0x25, 0x13, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x00, 0xF3, 0xBB, 0x82, 0x99, 0x95, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0xCE, 0x90, 0x71, 0x38, 0x2F, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x1A, 0xC0, 0x84, 0x27, 0xD6, 0x9D, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x37, 0x52, 0x16, 0x13, 0x0E, 0xCE, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBF, 0x5A, 0xDB, 0xDB, 0x6E, 0x1E, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB7, 0x5E, 0xF9, 0x86, 0xDD, 0x8A, 0x5C), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xAB, 0x5C, 0x8D, 0x1D, 0xF2, 0x2D, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC5, 0xF8, 0xF7, 0x1D, 0x96, 0x0B, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x4C, 0xA7, 0x45, 0x20, 0x6A, 0x1E, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x5D, 0xEF, 0xDE, 0xEE, 0x39, 0x44, 0x19), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x2F, 0x6D, 0x52, 0xC9, 0x58, 0x60, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xC9, 0x62, 0xCB, 0x38, 0x3C, 0x55, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xA5, 0x09, 0x10, 0x88, 0xDB, 0xE3, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xE0, 0x3C, 0xCE, 0x06, 0x0B, 0x4B, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x1D, 0xB4, 0x10, 0x76, 0x8F, 0xBA, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x70, 0x5A, 0x07, 0xF5, 0x1A, 0x74, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xE9, 0x94, 0xA8, 0xC0, 0xD5, 0x4A, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x6D, 0xD4, 0xE8, 0x9B, 0xE9, 0x6D, 0x0E), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x00, 0x32, 0x41, 0x57, 0x84, 0x89, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC7, 0x14, 0xEC, 0xE9, 0x27, 0xFF, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x67, 0x9E, 0xFB, 0xB6, 0xB8, 0x96, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x4A, 0xE3, 0x97, 0x4B, 0x58, 0xDE, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x1E, 0x5C, 0xF5, 0x7F, 0xD5, 0xD4, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x08, 0x7A, 0xF1, 0xBD, 0x89, 0xC7, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xF9, 0x11, 0x1B, 0xF5, 0x3C, 0x6D, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x50, 0xE5, 0x69, 0x1D, 0x59, 0xFC, 0x0C), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x2F, 0xF8, 0x3F, 0xEC, 0x55, 0x99, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xA7, 0x29, 0x90, 0x43, 0x81, 0x31, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x18, 0x44, 0x50, 0x5D, 0x76, 0xCB, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xC5, 0x5B, 0x9A, 0x03, 0xE6, 0x17, 0x39), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x89, 0xFC, 0x55, 0x94, 0x91, 0x6A, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x46, 0x35, 0xF2, 0x3A, 0x42, 0x08, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xD2, 0x76, 0x49, 0x42, 0x87, 0xD3, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xEA, 0xA0, 0x52, 0xF1, 0x6A, 0x30, 0x57), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xB2, 0x57, 0xA3, 0x8A, 0x4D, 0x1B, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xA3, 0x99, 0x94, 0xB5, 0x3D, 0x64, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC3, 0xD7, 0x53, 0xF6, 0x49, 0x1C, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x23, 0x41, 0x4D, 0xFB, 0x7A, 0x5C, 0x53), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xB8, 0x15, 0x65, 0x5C, 0x85, 0x94, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x37, 0xC7, 0xF8, 0x7E, 0xAE, 0x6C, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xD8, 0x11, 0x54, 0x98, 0x44, 0xE3, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x4D, 0xA6, 0x4B, 0x28, 0xF2, 0x57, 0x9E), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD0, 0xEB, 0x1E, 0xAA, 0x30, 0xD3, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x9B, 0x4D, 0xA7, 0x73, 0x6E, 0xB6, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x47, 0xF6, 0xED, 0x37, 0xEF, 0x71, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xB5, 0x49, 0x61, 0x5E, 0x45, 0xF6, 0x4A), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x0E, 0xB3, 0x84, 0x3A, 0x63, 0x72, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x53, 0x5C, 0xA7, 0xC6, 0x2E, 0xAB, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x0F, 0x8F, 0x87, 0x50, 0x28, 0xB4, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x98, 0x4A, 0x98, 0x31, 0x86, 0xCA, 0x51), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC9, 0xE2, 0xFD, 0x5D, 0x1F, 0xE8, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x90, 0x91, 0xC4, 0x84, 0xF0, 0xBA, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5A, 0xB3, 0x4E, 0xFB, 0xE0, 0x57, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x0B, 0x90, 0xA6, 0xFD, 0x9D, 0x8E, 0x02), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x41, 0x8F, 0x31, 0xFA, 0x5A, 0xF6, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xE9, 0xE3, 0xF6, 0xE0, 0x4A, 0xE7, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x4E, 0xCD, 0xA2, 0x22, 0x14, 0xD4, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xED, 0x21, 0xB7, 0x0F, 0x53, 0x10, 0x17), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x06, 0x24, 0x2C, 0x4E, 0xD1, 0x1E, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x3F, 0xC1, 0x9F, 0xAB, 0xF0, 0x37, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x5E, 0x12, 0xCE, 0x83, 0x1B, 0x2A, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x65, 0xCF, 0xE8, 0x5C, 0xA5, 0xA2, 0x70), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x86, 0x76, 0x3A, 0x94, 0xF6, 0x1D, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xDA, 0xC9, 0xA6, 0x29, 0x93, 0x15, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x61, 0x6A, 0x7D, 0xC7, 0xA9, 0xF3, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x03, 0x71, 0xA2, 0x15, 0xCE, 0x50, 0x72), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD0, 0xA8, 0x1E, 0x91, 0xC4, 0x4F, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x4B, 0x7E, 0xD7, 0x71, 0x58, 0x7E, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x45, 0xAF, 0x2A, 0x18, 0x93, 0x95, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x8F, 0xC7, 0xFA, 0x4C, 0x7A, 0x86, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xAF, 0x68, 0x3A, 0x23, 0xC1, 0x2E, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x50, 0x11, 0x67, 0x39, 0xB9, 0xAF, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x86, 0xAA, 0x1E, 0x88, 0x21, 0x29, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x28, 0xA4, 0x9D, 0x89, 0xA9, 0x9A, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBA, 0x04, 0x67, 0xB7, 0x01, 0x40, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xE9, 0x09, 0xA3, 0xCA, 0xA6, 0x37, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x97, 0xA8, 0xB6, 0x3C, 0xEE, 0x90, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xED, 0xC4, 0xF7, 0xC3, 0x95, 0xEC, 0x85), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x84, 0xBD, 0xEB, 0xD5, 0x64, 0xBB, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x9B, 0xE2, 0x28, 0x50, 0xC2, 0x72, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xF2, 0x74, 0xD1, 0x26, 0xBF, 0x32, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xCB, 0xAF, 0x72, 0xDB, 0x6D, 0x30, 0x98), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x50, 0x85, 0xF4, 0x2B, 0x48, 0xC1, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x28, 0xBB, 0x11, 0xBA, 0x5B, 0x22, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA1, 0xE5, 0x5C, 0xC9, 0x1D, 0x44, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xE8, 0xE6, 0x6F, 0xBB, 0xC1, 0x81, 0x7F), -}; -static const mbedtls_ecp_point brainpoolP256r1_T[16] = { - ECP_POINT_INIT_XY_Z1(brainpoolP256r1_T_0_X, brainpoolP256r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_1_X, brainpoolP256r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_2_X, brainpoolP256r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_3_X, brainpoolP256r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_4_X, brainpoolP256r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_5_X, brainpoolP256r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_6_X, brainpoolP256r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_7_X, brainpoolP256r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_8_X, brainpoolP256r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_9_X, brainpoolP256r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_10_X, brainpoolP256r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_11_X, brainpoolP256r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_12_X, brainpoolP256r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_13_X, brainpoolP256r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_14_X, brainpoolP256r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_15_X, brainpoolP256r1_T_15_Y), -}; -#else -#define brainpoolP256r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), -}; -static const mbedtls_mpi_uint brainpoolP384r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP384r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xD8, 0x8A, 0x54, 0x41, 0xD6, 0x6B, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x3B, 0xF1, 0x22, 0xFD, 0x2D, 0x4B, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x55, 0xE3, 0x33, 0xF0, 0x73, 0x52, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x3F, 0x30, 0x26, 0xCA, 0x7F, 0x52, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x6E, 0x17, 0x9B, 0xD5, 0x2A, 0x4A, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xDA, 0x6B, 0xE5, 0x03, 0x07, 0x1D, 0x2E), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x7A, 0xAF, 0x98, 0xE3, 0xA4, 0xF6, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x7D, 0xFE, 0x51, 0x40, 0x3B, 0x47, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x88, 0xEC, 0xC4, 0xE2, 0x8F, 0xCB, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xE2, 0x88, 0x2D, 0x4E, 0x50, 0xEB, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x54, 0x94, 0x5E, 0xF4, 0x7F, 0x3A, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x07, 0x1C, 0xE1, 0xBD, 0x0F, 0xF8, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x92, 0x28, 0x2E, 0x32, 0x04, 0xB1, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x82, 0x44, 0x43, 0x76, 0x0D, 0x55, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xE3, 0xFF, 0x89, 0x46, 0xDE, 0x4E, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x22, 0xBB, 0x67, 0x1A, 0x81, 0xEE, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x54, 0xE2, 0x7A, 0xAE, 0xDA, 0x2C, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x9A, 0x90, 0xAA, 0x6E, 0x8B, 0xCC, 0x5F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x40, 0xAC, 0xED, 0x7D, 0x37, 0x87, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xF8, 0xB1, 0x80, 0x4C, 0x8C, 0x04, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x98, 0x2C, 0xAD, 0x30, 0x69, 0x35, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x2E, 0x00, 0x2F, 0x44, 0x8C, 0xF0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x58, 0x07, 0xD7, 0xCD, 0x60, 0xA1, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFB, 0x7B, 0x03, 0x05, 0x5E, 0x79, 0x73), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x17, 0xCE, 0x38, 0x4B, 0x5E, 0x5B, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x0E, 0x0A, 0x61, 0x9D, 0x7C, 0x62, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF0, 0x98, 0x71, 0x7F, 0x17, 0x26, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xD3, 0xFA, 0x3C, 0xF0, 0x70, 0x07, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x47, 0x5C, 0x09, 0x43, 0xB7, 0x65, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xA7, 0x3E, 0xFA, 0xF3, 0xEC, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x78, 0x22, 0x2B, 0x58, 0x71, 0xFA, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x30, 0xCE, 0x6A, 0xB3, 0xB0, 0x4F, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x95, 0x20, 0xA9, 0x23, 0xC2, 0x65, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xCF, 0x03, 0x5B, 0x8A, 0x80, 0x44, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xF8, 0x91, 0xF7, 0xD5, 0xED, 0xEA, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x5B, 0x16, 0x10, 0x25, 0xAC, 0x2A, 0x17), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEC, 0xDC, 0xC4, 0x7B, 0x8C, 0x6B, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBB, 0x1C, 0xD3, 0x5A, 0xEE, 0xD9, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5D, 0x30, 0x5E, 0xF7, 0xB2, 0x41, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xCE, 0x0F, 0x1A, 0xC6, 0x41, 0x64, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x18, 0xE1, 0xE3, 0x82, 0x15, 0x66, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xE2, 0x24, 0x04, 0x72, 0x39, 0xA0, 0x7C), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x51, 0xA2, 0x58, 0x88, 0x62, 0xE1, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xD2, 0x65, 0x14, 0xE9, 0x4C, 0x82, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE1, 0xAC, 0x87, 0xAE, 0x31, 0x1A, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4F, 0x96, 0x1E, 0x85, 0x7A, 0xC3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x86, 0xBB, 0xF0, 0xC0, 0x9D, 0x08, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x53, 0x03, 0x09, 0x80, 0x91, 0xEF, 0x68), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xD7, 0xAF, 0x6F, 0x69, 0x7B, 0x88, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x13, 0xE4, 0x30, 0xA2, 0x47, 0xB5, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD2, 0xC0, 0xDD, 0x8A, 0x1C, 0x3C, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x8C, 0xB3, 0x4C, 0xBA, 0x8B, 0x6D, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xC7, 0xA1, 0xA8, 0x6E, 0x3C, 0x4F, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x4A, 0x97, 0xC8, 0x03, 0x6F, 0x01, 0x82), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x18, 0x12, 0xA9, 0x39, 0xD5, 0x22, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA7, 0xC0, 0xBD, 0x9D, 0x8D, 0x78, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xD0, 0x7F, 0xDF, 0xD0, 0x30, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x73, 0x96, 0xEC, 0xA8, 0x1D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xD1, 0x65, 0x66, 0xDC, 0xD9, 0xCF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xED, 0x7B, 0x37, 0xAD, 0xE2, 0xBE, 0x2D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x79, 0x42, 0x6A, 0x07, 0x66, 0xB1, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x53, 0x62, 0x65, 0x92, 0x09, 0x4C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xAF, 0xC3, 0x03, 0xF6, 0xF4, 0x2D, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xCA, 0x41, 0xD9, 0xA2, 0x69, 0x9B, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xB2, 0xA6, 0x8D, 0xE1, 0xAA, 0x61, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xBA, 0x4D, 0x12, 0xB6, 0xBE, 0xF3, 0x7E), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x92, 0x22, 0x07, 0xCE, 0xC9, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA1, 0x7C, 0x91, 0xDB, 0x32, 0xF7, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x49, 0x4B, 0x6D, 0xFB, 0xD9, 0x70, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xFB, 0x4E, 0x4C, 0x5E, 0x66, 0x81, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xB3, 0xE1, 0x00, 0xB7, 0xD9, 0xCC, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x36, 0x8B, 0xC4, 0x39, 0x20, 0xFD, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x1F, 0x60, 0x03, 0xBB, 0xD7, 0x60, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x3C, 0x62, 0xDD, 0x71, 0x95, 0xE9, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x5B, 0x7A, 0x5F, 0x68, 0x81, 0xC5, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xB5, 0xB9, 0x98, 0x42, 0x28, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x29, 0x8E, 0x11, 0x49, 0xB4, 0xD7, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x3E, 0xD2, 0x30, 0xA1, 0xBA, 0xCA, 0x03), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x37, 0x64, 0x44, 0x2F, 0x03, 0xE5, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x42, 0xBC, 0xFF, 0xA2, 0x1A, 0x5F, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x04, 0xAB, 0x04, 0xE0, 0x24, 0xAD, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x45, 0x17, 0x67, 0x1F, 0x3E, 0x53, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x0F, 0xB3, 0x1B, 0x57, 0x54, 0xC2, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0xF8, 0xC4, 0x1B, 0x9B, 0xFA, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x90, 0xFD, 0xFB, 0xCA, 0x49, 0x38, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xCF, 0xC6, 0xDD, 0xF0, 0xFF, 0x8C, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x69, 0x9D, 0xBD, 0x5F, 0x33, 0xE9, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x19, 0x82, 0x3D, 0xAC, 0x1C, 0x40, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC7, 0x02, 0x46, 0x14, 0x77, 0x00, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x05, 0xF2, 0x77, 0x3A, 0x66, 0x5C, 0x39), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xE6, 0x17, 0xDE, 0xB2, 0xA1, 0xE5, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x71, 0xEC, 0x9D, 0xD8, 0xF5, 0xD4, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xC6, 0x42, 0x5E, 0xE7, 0x18, 0xBA, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x21, 0x68, 0x5A, 0x26, 0xFB, 0xD7, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x00, 0x5C, 0xBA, 0x8A, 0x34, 0xEC, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x3C, 0xAF, 0x53, 0xE8, 0x65, 0x35), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xEF, 0x28, 0xDC, 0x67, 0x05, 0xC8, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x78, 0xC3, 0x85, 0x49, 0xA0, 0xBC, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x3E, 0x2D, 0xA0, 0xCF, 0xD4, 0x7A, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x93, 0xFE, 0x60, 0xB3, 0x6E, 0x99, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xAD, 0x04, 0xE7, 0x49, 0xAF, 0x5E, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x7A, 0xED, 0xA6, 0x9E, 0x18, 0x09, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x05, 0x94, 0x44, 0xDC, 0xB8, 0x85, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xB7, 0x37, 0xC2, 0x50, 0x75, 0x15, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xC6, 0x0F, 0xB2, 0xA9, 0x91, 0x3E, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x81, 0xAD, 0x25, 0xA1, 0x26, 0x73, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xF1, 0xD1, 0x61, 0x7C, 0x76, 0x8F, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xDB, 0x4A, 0xFF, 0x14, 0xA7, 0x48, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x73, 0xC6, 0xC2, 0xCC, 0xF1, 0x57, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xED, 0x73, 0x27, 0x70, 0x82, 0xB6, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xBA, 0xAC, 0x3A, 0xCF, 0xF4, 0xEA, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xD6, 0xB1, 0x8F, 0x0E, 0x08, 0x2C, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE3, 0x8F, 0x2F, 0x0E, 0xA1, 0xF3, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xF5, 0x7C, 0x9B, 0x29, 0x0A, 0xF6, 0x28), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xEE, 0x17, 0x47, 0x34, 0x15, 0xA3, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBE, 0x88, 0x48, 0xE7, 0xA2, 0xBB, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xAD, 0xDC, 0x65, 0x61, 0x37, 0x0F, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x67, 0xAD, 0xA2, 0x3A, 0x1C, 0x91, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x07, 0x0C, 0x3A, 0x41, 0x6E, 0x13, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBD, 0x7E, 0xED, 0xAA, 0x14, 0xDD, 0x61), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xDC, 0x20, 0x01, 0x72, 0x11, 0x48, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xC4, 0x7B, 0xF8, 0x62, 0x3D, 0xF0, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xC2, 0x3D, 0x2E, 0x52, 0xA3, 0x4A, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE2, 0x53, 0x46, 0x5E, 0x21, 0xF8, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xC7, 0x8F, 0xA9, 0x26, 0x42, 0x32, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xA6, 0xA0, 0x8D, 0x4B, 0x9A, 0x19, 0x03), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xAB, 0x6D, 0x1E, 0xFB, 0xEE, 0x60, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x56, 0x3C, 0xC5, 0x5D, 0x10, 0x79, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xBC, 0x41, 0x9F, 0x71, 0xEF, 0x02, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x36, 0xC4, 0xD0, 0x88, 0x9B, 0x32, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xD4, 0x5D, 0x17, 0x39, 0xE6, 0x22, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x26, 0x01, 0xCE, 0xBE, 0x4A, 0x9C, 0x27), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x6D, 0x11, 0xCA, 0x6C, 0x5A, 0x93, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x96, 0x26, 0xAF, 0x2F, 0xE4, 0x30, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC1, 0x4C, 0xC6, 0x30, 0x1F, 0x5C, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB3, 0xE8, 0xFC, 0x35, 0xEB, 0x63, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x1D, 0xCA, 0xFC, 0x50, 0x36, 0x4B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0E, 0x23, 0x5B, 0xAF, 0xEB, 0x2D, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x88, 0xB6, 0xD7, 0x74, 0x4A, 0x23, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x66, 0xE2, 0xBB, 0x29, 0xA6, 0x4F, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x6F, 0x7E, 0x68, 0x6E, 0xA0, 0x14, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x73, 0xD4, 0xE8, 0xAB, 0x5B, 0xF6, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xE0, 0x3C, 0x24, 0x00, 0x95, 0xE9, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x0D, 0x4F, 0x81, 0xD0, 0xF2, 0x3F, 0x00), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x1D, 0xCD, 0x78, 0x39, 0xC4, 0x6B, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x45, 0xC7, 0xB8, 0x2F, 0xAA, 0x5D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x8C, 0x6E, 0xA3, 0x24, 0xB2, 0xDB, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x2D, 0xD9, 0xF1, 0xC7, 0x9B, 0x8A, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xE1, 0x2C, 0xB9, 0x40, 0x37, 0x91, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2C, 0xB5, 0x23, 0x03, 0x2B, 0xAF, 0x2F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x9D, 0x5A, 0x20, 0x10, 0xA9, 0x84, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x30, 0x89, 0x20, 0x13, 0xE9, 0xB2, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x52, 0xEB, 0x03, 0x18, 0x1F, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x9E, 0x1C, 0x35, 0x87, 0x92, 0x69, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xC9, 0x88, 0xAF, 0xC6, 0x6C, 0x83, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD5, 0x7A, 0x54, 0x34, 0x99, 0xB6, 0x6F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xAD, 0x45, 0x9B, 0x4B, 0x41, 0x4D, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x5D, 0xAB, 0x7F, 0x35, 0x34, 0xE9, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBE, 0x78, 0x34, 0x44, 0xF3, 0x4A, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xDE, 0xE3, 0xC4, 0xEE, 0x0B, 0xF9, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x86, 0x16, 0x48, 0x32, 0xB8, 0x74, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEE, 0x7C, 0xBA, 0xBD, 0x81, 0xE3, 0x55), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x6A, 0xFA, 0x84, 0xDA, 0xB8, 0xD5, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x9F, 0x8A, 0xD5, 0x1B, 0x2E, 0x1A, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0C, 0x61, 0xE2, 0xFF, 0x5B, 0xE6, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x62, 0xC1, 0x87, 0x53, 0x1B, 0x92, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x90, 0x00, 0xD1, 0x6A, 0x0C, 0x0E, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x2E, 0xB5, 0x3B, 0x44, 0xB5, 0xA0, 0x78), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5D, 0x02, 0x58, 0xB5, 0xBE, 0x45, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xEF, 0x8E, 0x90, 0x4D, 0x2A, 0x32, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x75, 0x5C, 0x0A, 0x33, 0x8F, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x6C, 0x95, 0xD4, 0x1F, 0xF3, 0xEB, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xE4, 0x4C, 0x91, 0x20, 0xF3, 0x25, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x95, 0xEB, 0x29, 0x6F, 0x20, 0x34, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x15, 0xE5, 0x13, 0x7E, 0x64, 0x8B, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xBC, 0x0D, 0x18, 0x7E, 0x37, 0x9E, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x82, 0x20, 0xF7, 0x2D, 0x7A, 0x77, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x29, 0xA2, 0xDB, 0x7A, 0xE6, 0x6F, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xC6, 0x50, 0x5C, 0xBC, 0xE6, 0x4F, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x9F, 0xD5, 0xE8, 0xC5, 0x3D, 0xB7, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x03, 0x55, 0x10, 0xDB, 0xA6, 0x8B, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x17, 0xAE, 0x78, 0xC9, 0x1D, 0x43, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x35, 0x49, 0xD4, 0x47, 0x84, 0x8D, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x95, 0x2F, 0xEA, 0xBC, 0xB4, 0x18, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x48, 0xAE, 0x89, 0xF5, 0x65, 0x3D, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xF2, 0x2B, 0x20, 0xD1, 0x75, 0x50, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xE6, 0x5C, 0x2C, 0xE0, 0x7D, 0xDF, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x07, 0x3E, 0xCE, 0x9F, 0x18, 0xB6, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xF8, 0xF0, 0xD5, 0xFA, 0x42, 0x1D, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x6C, 0x1D, 0x03, 0xC9, 0x0E, 0x2B, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x52, 0xA5, 0xB4, 0x63, 0xE1, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0xD9, 0xC4, 0xFD, 0x16, 0x60, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x7D, 0xDE, 0xDF, 0x4B, 0x4A, 0xB0, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x4E, 0x8C, 0x94, 0xC1, 0xE2, 0x85, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xF0, 0xEA, 0xB5, 0x9B, 0x70, 0xEF, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xC2, 0x39, 0x5D, 0xF3, 0x2C, 0xD9, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x1C, 0x2E, 0xCC, 0x2F, 0x54, 0x87, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x72, 0xC7, 0xB5, 0x50, 0xA3, 0x84, 0x77), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xD1, 0xAF, 0xA9, 0xB4, 0x8B, 0x5D, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xF6, 0x52, 0x8A, 0xC3, 0x56, 0xA5, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x52, 0xFF, 0xEA, 0x05, 0x42, 0x77, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x08, 0x90, 0x72, 0x86, 0xC4, 0xC3, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x15, 0xF8, 0xF1, 0x16, 0x67, 0xC6, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x87, 0xAC, 0x8F, 0x71, 0xEC, 0x83, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xE1, 0xE6, 0x2D, 0x0E, 0x11, 0xA1, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xE2, 0xA8, 0x32, 0xE6, 0xE3, 0x83, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x56, 0xE5, 0xCD, 0xB7, 0x2B, 0x67, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xED, 0xC9, 0x65, 0x6D, 0x87, 0xE1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xFD, 0x9A, 0x53, 0x0E, 0xFA, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x4C, 0x4A, 0xE2, 0x23, 0x84, 0xFA, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFE, 0x49, 0x81, 0xD1, 0x3E, 0xF4, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x72, 0xE0, 0xEF, 0x0D, 0xB8, 0x3E, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x00, 0x0F, 0x5F, 0xCE, 0x60, 0x72, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCC, 0xD8, 0x03, 0x07, 0x6E, 0x5A, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x3A, 0x35, 0x50, 0x4E, 0x1F, 0xCA, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xEA, 0x88, 0x55, 0xBD, 0x6E, 0x05, 0x7F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x6D, 0xF1, 0x97, 0xA6, 0x69, 0x39, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x41, 0x99, 0xFF, 0x3B, 0xA1, 0x26, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x2F, 0x95, 0x80, 0x12, 0x4A, 0x1B, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xBF, 0x51, 0xAA, 0xAE, 0x2D, 0xDA, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1C, 0xB3, 0x52, 0x36, 0x49, 0xD4, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC1, 0x1F, 0x3A, 0xD3, 0x3E, 0x5C, 0x1A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x51, 0xF7, 0x2B, 0xC8, 0xA9, 0xA7, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x4E, 0x7F, 0x98, 0x41, 0x66, 0xB0, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x1D, 0xC0, 0x42, 0xCD, 0xF8, 0xC3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x41, 0x91, 0x7D, 0xCC, 0x8B, 0xCC, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xAE, 0x76, 0xED, 0x56, 0x18, 0xC5, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x6A, 0x06, 0xA3, 0x7F, 0x65, 0x10, 0x1F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xEC, 0x3C, 0x05, 0x05, 0xCA, 0xF6, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0xCD, 0x02, 0x51, 0x12, 0x16, 0x3C, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xEB, 0xB3, 0x43, 0x7B, 0xDD, 0xB2, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x90, 0x41, 0xDB, 0xE4, 0xF5, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0E, 0x18, 0x2A, 0x5A, 0x83, 0x7C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x37, 0xA1, 0x0D, 0xF1, 0x2F, 0x63, 0x79), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC0, 0xFA, 0x6F, 0x1F, 0x67, 0xCF, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x34, 0x45, 0xBB, 0xF4, 0xF9, 0x9B, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x69, 0xFE, 0x67, 0x1D, 0x64, 0x8F, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x39, 0xBF, 0xD8, 0xB3, 0xC7, 0xAD, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x93, 0xFF, 0xF3, 0x28, 0xFA, 0x39, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF9, 0xC3, 0x85, 0x26, 0x7A, 0x88, 0x89), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD5, 0x79, 0xD8, 0x11, 0xDE, 0xEB, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x46, 0xA4, 0x6A, 0xDA, 0x74, 0x34, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBD, 0xD3, 0xF5, 0x14, 0xEE, 0xFE, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4C, 0xA3, 0x71, 0x43, 0x65, 0xF8, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x6C, 0x35, 0xFA, 0x90, 0x25, 0xD8, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x34, 0x84, 0x96, 0xA1, 0x43, 0x03, 0x4D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x3B, 0x3B, 0x2F, 0xCA, 0x59, 0xF2, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x48, 0x24, 0x74, 0xD8, 0x72, 0x90, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x42, 0x74, 0x8C, 0x6F, 0x52, 0x19, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9E, 0x41, 0x63, 0x68, 0x78, 0x4C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x94, 0xB6, 0x6B, 0x38, 0x52, 0xA8, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x30, 0x25, 0x93, 0xA1, 0x6F, 0x6E, 0x68), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2F, 0x4B, 0x64, 0x79, 0x50, 0xFF, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x36, 0xED, 0x57, 0x39, 0x3B, 0xE7, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x85, 0xEA, 0x35, 0xD6, 0xC0, 0xA0, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x89, 0x3A, 0xCC, 0x22, 0x1C, 0x46, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x7A, 0xB0, 0xA1, 0x1B, 0x69, 0x62, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xB8, 0x8A, 0x6C, 0x18, 0x85, 0x0D, 0x88), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB6, 0x50, 0xE9, 0x4E, 0x7F, 0xE8, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5B, 0x5C, 0xD1, 0x4B, 0x11, 0x9A, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x25, 0x56, 0x74, 0x51, 0x9C, 0xEC, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x7F, 0xB6, 0x8A, 0xCB, 0x3A, 0x10, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x33, 0x07, 0x01, 0xE9, 0x49, 0x59, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xA5, 0x2E, 0xF2, 0xBA, 0x32, 0x63, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x06, 0x0B, 0xA5, 0x44, 0x27, 0x7F, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x74, 0xAC, 0x0F, 0xCC, 0x4F, 0x13, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB1, 0xBF, 0x97, 0x49, 0xA5, 0x1C, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x64, 0x68, 0x7B, 0x0F, 0xCC, 0x77, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x39, 0xF9, 0x4E, 0x84, 0x9C, 0xF6, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xCF, 0x6D, 0xE2, 0xA1, 0x2D, 0xF9, 0x2B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC4, 0x90, 0x57, 0x31, 0x01, 0x05, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x1E, 0xBB, 0xBF, 0x98, 0xA4, 0x7C, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xE3, 0xA0, 0xB2, 0xCD, 0x39, 0x9A, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x34, 0x60, 0x7A, 0x89, 0x98, 0xB5, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x20, 0x3D, 0x3A, 0x04, 0x8F, 0x5A, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x26, 0xB6, 0x49, 0x09, 0x9C, 0x0F, 0x59), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x66, 0xD2, 0x38, 0x2A, 0x62, 0x81, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xC8, 0x20, 0x5E, 0x28, 0xA3, 0x81, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x31, 0xA4, 0xF1, 0xEA, 0x7D, 0x87, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x2C, 0x99, 0x09, 0x6F, 0x63, 0xEB, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x76, 0xDA, 0x1A, 0x06, 0xBE, 0xDE, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x09, 0x2E, 0x75, 0x39, 0x30, 0x2D, 0x42), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x9B, 0xC1, 0x5A, 0x17, 0xC3, 0x8C, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x8D, 0x94, 0x4D, 0x3D, 0xAB, 0x60, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFD, 0x1E, 0x0F, 0x43, 0xAE, 0x9D, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF2, 0xF3, 0x20, 0x1B, 0xAA, 0xB7, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x5B, 0xA4, 0xF4, 0x90, 0x3B, 0xE3, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x78, 0x72, 0xBD, 0x65, 0x09, 0x0B, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x37, 0x2A, 0x6C, 0x16, 0x4F, 0x64, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xCE, 0xA3, 0x90, 0xB4, 0x9A, 0xBC, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x55, 0x63, 0x1D, 0x3A, 0x6E, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xB4, 0xAA, 0x99, 0x22, 0x45, 0x89, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x7C, 0x8C, 0xA6, 0x3D, 0xA7, 0x3E, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x06, 0x42, 0xDC, 0xA6, 0xE3, 0xC6, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8C, 0x3D, 0x5D, 0x47, 0x31, 0x7C, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x85, 0xEE, 0x46, 0x7E, 0x13, 0x04, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x3C, 0x8B, 0x43, 0x2E, 0x74, 0xF5, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x88, 0x8E, 0x07, 0x29, 0x08, 0x03, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x9B, 0x89, 0xEB, 0x08, 0xE8, 0x43, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x07, 0x67, 0xFD, 0xD9, 0x73, 0x6F, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xEB, 0x21, 0x8D, 0x98, 0x43, 0x74, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xCC, 0x14, 0xD8, 0x08, 0xBB, 0xA6, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x98, 0xF2, 0x6A, 0x18, 0xC3, 0xDD, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x38, 0x91, 0xA0, 0x03, 0xF2, 0x04, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xAF, 0xE8, 0xFD, 0xFB, 0x13, 0x70, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x93, 0x87, 0x98, 0x4A, 0xE0, 0x00, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x2E, 0x69, 0x9C, 0xA2, 0x2D, 0x03, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFE, 0xF3, 0xB9, 0xC1, 0x85, 0x2A, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xFD, 0x86, 0xB1, 0xCD, 0xBF, 0x41, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xD8, 0x9A, 0x21, 0xF3, 0xFE, 0xCB, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x78, 0x04, 0x60, 0xB7, 0xA9, 0xA2, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1E, 0x66, 0x2A, 0x54, 0x51, 0xBD, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x16, 0x36, 0xEF, 0x61, 0x2D, 0xEE, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x5F, 0x88, 0xA0, 0x13, 0x12, 0xF7, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xC6, 0xAD, 0x4A, 0x4A, 0x07, 0x01, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x74, 0xB1, 0x4F, 0xEB, 0xBD, 0xD5, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF9, 0x71, 0xA2, 0x06, 0x4F, 0xD7, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x8B, 0x4D, 0x48, 0xE0, 0x98, 0xFB, 0x6A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xBA, 0x10, 0xA3, 0x0D, 0x52, 0xAC, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xD0, 0xE0, 0x36, 0xE6, 0x07, 0x3A, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x80, 0xF0, 0xAA, 0x49, 0x22, 0x4B, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC7, 0xAB, 0x1C, 0x89, 0xCD, 0x24, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x2A, 0xFC, 0xB3, 0x6D, 0x45, 0x96, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xE4, 0xDB, 0x52, 0x3F, 0xC4, 0xB4, 0x19), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xCC, 0xC8, 0x7F, 0xBB, 0x6B, 0x87, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x21, 0x3C, 0x69, 0x7D, 0x38, 0x57, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x4C, 0x18, 0x3C, 0x53, 0xA5, 0x48, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC3, 0x64, 0x45, 0xDB, 0xC4, 0x6D, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCC, 0xD1, 0xBB, 0x17, 0xB8, 0x34, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x69, 0x71, 0xFA, 0xA0, 0x28, 0x4A, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xE8, 0x9E, 0x39, 0xEA, 0x8D, 0x38, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x9C, 0xBB, 0xCD, 0x80, 0x1A, 0xEE, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA0, 0x45, 0xBF, 0xD9, 0x22, 0x11, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7C, 0x5C, 0xD9, 0xC0, 0x9F, 0x69, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x8A, 0xA6, 0x79, 0x4E, 0x35, 0xB9, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8B, 0x9A, 0x3E, 0xA1, 0xB8, 0x28, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x2F, 0xEF, 0xBB, 0xA9, 0x72, 0x7F, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x34, 0xB7, 0x12, 0xB9, 0xE7, 0xC3, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x1D, 0xD9, 0x42, 0x77, 0x0C, 0x71, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x01, 0x59, 0xA7, 0x56, 0x03, 0x91, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x91, 0x99, 0x33, 0x30, 0x3E, 0xEF, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xC9, 0x5A, 0x9A, 0x54, 0x66, 0xF1, 0x70), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x2C, 0xB7, 0x6E, 0x71, 0x7D, 0x35, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x0D, 0xEF, 0xD1, 0x2D, 0x99, 0x63, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x31, 0xAF, 0x2D, 0xC9, 0xC6, 0xC2, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xC0, 0xDF, 0x80, 0x54, 0xC4, 0xAC, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x6B, 0xA0, 0x84, 0x96, 0xF7, 0x31, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xE2, 0x7C, 0x7A, 0x41, 0x45, 0x75, 0x6A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xEE, 0x58, 0x31, 0xE8, 0x68, 0xD6, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x2E, 0x48, 0xB7, 0x09, 0x9F, 0xD4, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA9, 0x5C, 0xE7, 0x64, 0x43, 0x5D, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x9F, 0x50, 0xAB, 0x68, 0xFF, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x88, 0x2D, 0xBA, 0x12, 0xBF, 0x8D, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xDF, 0x6F, 0xB3, 0x75, 0xA4, 0x55, 0x73), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x17, 0x92, 0x39, 0xB7, 0x13, 0x37, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x43, 0x71, 0xA7, 0xCA, 0x17, 0x1B, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xB9, 0xB0, 0x78, 0xEF, 0xA0, 0xDA, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0xF2, 0x0F, 0x85, 0xA2, 0xB6, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x65, 0x2E, 0x6E, 0x45, 0xB9, 0x4C, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x6A, 0x8C, 0x2B, 0x77, 0x96, 0x36, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x7A, 0x13, 0x4A, 0x97, 0x63, 0x02, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x1E, 0x06, 0x03, 0x8F, 0xB9, 0xEE, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0xEE, 0x8B, 0x89, 0xA9, 0x70, 0xDB, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x81, 0xC9, 0x70, 0x8D, 0x62, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xDA, 0x46, 0xF8, 0xF9, 0x3A, 0xBE, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x9C, 0x7A, 0x97, 0x62, 0xEB, 0xFA, 0x0F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x03, 0x3D, 0x3C, 0x46, 0x27, 0x9E, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x08, 0x1C, 0xD5, 0x25, 0xAF, 0xE9, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x69, 0xDC, 0x59, 0xF4, 0x8A, 0x7C, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x9A, 0x7A, 0x99, 0x21, 0x0C, 0x4E, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xCE, 0x85, 0x5F, 0xAC, 0xAA, 0x82, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x57, 0x69, 0x90, 0x76, 0xF3, 0x53, 0x3F), -}; -static const mbedtls_ecp_point brainpoolP384r1_T[32] = { - ECP_POINT_INIT_XY_Z1(brainpoolP384r1_T_0_X, brainpoolP384r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_1_X, brainpoolP384r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_2_X, brainpoolP384r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_3_X, brainpoolP384r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_4_X, brainpoolP384r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_5_X, brainpoolP384r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_6_X, brainpoolP384r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_7_X, brainpoolP384r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_8_X, brainpoolP384r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_9_X, brainpoolP384r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_10_X, brainpoolP384r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_11_X, brainpoolP384r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_12_X, brainpoolP384r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_13_X, brainpoolP384r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_14_X, brainpoolP384r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_15_X, brainpoolP384r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_16_X, brainpoolP384r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_17_X, brainpoolP384r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_18_X, brainpoolP384r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_19_X, brainpoolP384r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_20_X, brainpoolP384r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_21_X, brainpoolP384r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_22_X, brainpoolP384r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_23_X, brainpoolP384r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_24_X, brainpoolP384r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_25_X, brainpoolP384r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_26_X, brainpoolP384r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_27_X, brainpoolP384r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_28_X, brainpoolP384r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_29_X, brainpoolP384r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_30_X, brainpoolP384r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_31_X, brainpoolP384r1_T_31_Y), -}; -#else -#define brainpoolP384r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP512r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), -}; -static const mbedtls_mpi_uint brainpoolP512r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78), -}; -static const mbedtls_mpi_uint brainpoolP512r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP512r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xE9, 0x6B, 0x8C, 0x6F, 0x9D, 0x88, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x4F, 0x86, 0x96, 0xA7, 0x56, 0xD1, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xAB, 0xFA, 0xEE, 0xA7, 0xF5, 0x0E, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x40, 0xEF, 0x9E, 0x6D, 0xD6, 0x32, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xED, 0x56, 0x14, 0x57, 0x1A, 0x8D, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xED, 0x4D, 0x3A, 0xFA, 0x71, 0x75, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xC5, 0x76, 0x1C, 0x14, 0xBE, 0xB5, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x5A, 0xCB, 0xE7, 0x36, 0x1D, 0x52, 0x1C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8D, 0x7A, 0xEB, 0xA3, 0x8B, 0xD5, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xA3, 0x41, 0xF8, 0xAC, 0x9E, 0xAB, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xE3, 0x65, 0x0D, 0x1C, 0xFE, 0x09, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xCA, 0x13, 0x3F, 0xC5, 0xF9, 0x7E, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x5D, 0x63, 0x28, 0xA6, 0x89, 0xD3, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x95, 0x3F, 0x7A, 0x82, 0xD4, 0x77, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xBB, 0x92, 0x32, 0x00, 0xF4, 0x66, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x58, 0x31, 0xD1, 0x17, 0x9F, 0x2A, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x36, 0xA9, 0xCD, 0x80, 0xA5, 0x2D, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x44, 0xAB, 0xCE, 0x71, 0xFF, 0x0C, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x24, 0x58, 0x35, 0x5A, 0x21, 0x32, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xA6, 0x28, 0xF8, 0x7A, 0x97, 0xAE, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xE7, 0x08, 0xFA, 0x47, 0xC9, 0x55, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xAC, 0x2E, 0x84, 0xA4, 0xF5, 0x52, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x58, 0x05, 0x9D, 0xA7, 0xC8, 0x71, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x92, 0xB4, 0x92, 0xC1, 0x92, 0xEC, 0x6B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x48, 0x2D, 0x79, 0x5E, 0x58, 0xE5, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x85, 0x26, 0xEC, 0xE9, 0x6E, 0xD4, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x68, 0x26, 0x87, 0x38, 0xA2, 0xD2, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x17, 0x60, 0xCE, 0x75, 0xF8, 0xA5, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x51, 0xDB, 0xA9, 0xAE, 0x87, 0xF1, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x49, 0x92, 0x3B, 0x19, 0x96, 0xF5, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xD5, 0x52, 0x52, 0x8C, 0xCE, 0xFD, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x18, 0x0A, 0xE6, 0xF6, 0xAE, 0x08, 0x41), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x2B, 0xD8, 0x54, 0xCE, 0xB0, 0x57, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xB0, 0xF8, 0x9E, 0x03, 0x03, 0x3C, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x0E, 0x29, 0x29, 0x00, 0xF3, 0x70, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x33, 0x99, 0x0E, 0x00, 0x5D, 0xFE, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2D, 0xF2, 0x59, 0x32, 0xCF, 0x03, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xC9, 0x72, 0xAE, 0x0C, 0xEF, 0xD1, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x5A, 0x27, 0xBF, 0x2F, 0x45, 0xF9, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xBE, 0xE5, 0x2C, 0xFF, 0x5B, 0x1E, 0x88), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xAC, 0xBB, 0xD8, 0x83, 0xC2, 0x46, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xDC, 0xCE, 0x15, 0xB4, 0xEF, 0xCF, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xDB, 0x5E, 0x94, 0x31, 0x0B, 0xB2, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xB9, 0xE3, 0xE3, 0x11, 0x71, 0x41, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xE3, 0x01, 0xB7, 0x7D, 0xBC, 0x65, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x07, 0x65, 0x87, 0xA7, 0xE8, 0x48, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x48, 0x8F, 0xD4, 0x30, 0x8E, 0xB4, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE0, 0x73, 0xBE, 0x1E, 0xBF, 0x56, 0x36), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x0E, 0x5E, 0x87, 0xC5, 0xAB, 0x0E, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xF9, 0x5F, 0x80, 0x24, 0x4C, 0x2A, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x15, 0x21, 0x54, 0x92, 0x84, 0x8D, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x8A, 0x47, 0x74, 0xDC, 0x42, 0xB1, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xF7, 0x30, 0xFD, 0xC1, 0x9B, 0x0C, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x6C, 0xCC, 0xDF, 0xC5, 0xE3, 0xA9, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x67, 0x59, 0x10, 0x5C, 0x51, 0x54, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x37, 0xFB, 0x6E, 0xB0, 0x78, 0x63, 0x8E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEF, 0xC4, 0x39, 0x20, 0xF1, 0x46, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x62, 0xAE, 0xFF, 0x10, 0xE4, 0xE2, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x5C, 0xF5, 0x2E, 0x22, 0x89, 0xE5, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x0C, 0x29, 0xA8, 0x62, 0xAE, 0xDB, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x9E, 0x0F, 0xCA, 0x87, 0x2A, 0x6F, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xDC, 0x9B, 0x9F, 0x65, 0xD4, 0xAD, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xC3, 0x08, 0x0F, 0xCF, 0x67, 0xE9, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5C, 0xD7, 0xFF, 0x41, 0x9C, 0xCB, 0x26), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x05, 0x12, 0xAD, 0x73, 0x63, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x99, 0x07, 0x86, 0x57, 0xE7, 0x94, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x4B, 0xA5, 0xBF, 0x18, 0xA9, 0xEF, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x4C, 0xC4, 0x09, 0xF2, 0x2F, 0x0C, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x3A, 0x04, 0xEA, 0x89, 0x6C, 0x91, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0x3A, 0xE7, 0xA3, 0xEC, 0x24, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xA1, 0x26, 0x21, 0x04, 0xE3, 0xB9, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x71, 0x4B, 0x7B, 0xC2, 0x89, 0xCD, 0xA2), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xB9, 0xA8, 0x9D, 0xFD, 0x00, 0x3A, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x41, 0x6C, 0xBB, 0x5A, 0xCA, 0x1F, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xD7, 0xE2, 0x6C, 0x6B, 0xA7, 0x48, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x19, 0xAD, 0xA7, 0xC1, 0x7E, 0x4F, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF7, 0x19, 0x3C, 0x06, 0x74, 0x2C, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x23, 0x4F, 0x0C, 0x09, 0xB0, 0x80, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x74, 0x34, 0x08, 0x44, 0x7E, 0xA3, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xCC, 0x8D, 0x12, 0x6E, 0xE1, 0x3D, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x18, 0xB1, 0x71, 0x02, 0x93, 0xC2, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x89, 0x40, 0xE2, 0x1F, 0xE7, 0x5E, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xAE, 0x89, 0x01, 0xD4, 0x0C, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xDA, 0x58, 0x70, 0x24, 0xF2, 0xE4, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xC7, 0x1D, 0xD6, 0x4A, 0x6F, 0x66, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x1D, 0x7E, 0x4A, 0x2C, 0xCA, 0xEC, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x7F, 0xA8, 0x99, 0xE4, 0xD3, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x1D, 0x5A, 0xDF, 0x5E, 0x58, 0x36, 0x49), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB9, 0x32, 0x69, 0x1F, 0x72, 0x2A, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x73, 0xE2, 0x03, 0x39, 0x35, 0xAA, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x5E, 0x5D, 0x48, 0xEF, 0xAE, 0x30, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x7F, 0x60, 0x19, 0xAF, 0xEC, 0x9D, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x19, 0xE4, 0x1B, 0x56, 0x15, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xD7, 0x33, 0x59, 0x1F, 0x43, 0x59, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xCE, 0xEE, 0xCA, 0xA4, 0x7F, 0x63, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x40, 0xC0, 0xF6, 0x19, 0x89, 0x43, 0x20), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x92, 0xEA, 0x07, 0x65, 0x79, 0x86, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xB7, 0x13, 0x75, 0xD3, 0xC5, 0x0A, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x9E, 0xFA, 0xE1, 0x1F, 0x0C, 0xF9, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x8C, 0xED, 0x5C, 0x21, 0xE9, 0x09, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x4D, 0xD8, 0x18, 0xC4, 0xF6, 0x36, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xC9, 0xAC, 0x5C, 0xFA, 0x69, 0xA4, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8C, 0x94, 0x1C, 0x7B, 0x71, 0x36, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBD, 0x46, 0xCE, 0xB7, 0x1D, 0x9C, 0x5E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD6, 0x96, 0x4B, 0xA6, 0x47, 0xEB, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xF1, 0x5F, 0x15, 0xDE, 0x99, 0x6F, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xBD, 0xE5, 0x04, 0xB8, 0xE6, 0xC0, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD3, 0xF0, 0x04, 0x00, 0xE4, 0x05, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xF3, 0x06, 0xA3, 0x1A, 0xFF, 0xEA, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x32, 0xAA, 0x99, 0x33, 0x09, 0xB6, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xEF, 0xFC, 0x61, 0x10, 0x42, 0x31, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF1, 0xF4, 0x33, 0xCF, 0x28, 0x90, 0x9C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xDE, 0xF9, 0x88, 0x87, 0x7B, 0xEB, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xB8, 0xDA, 0xFA, 0xDA, 0x3D, 0xA6, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF0, 0x62, 0x82, 0x53, 0x32, 0x55, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA5, 0x32, 0x4A, 0x19, 0x11, 0x9C, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xB3, 0x27, 0xE9, 0x75, 0x90, 0x05, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x1C, 0x90, 0x48, 0x77, 0x01, 0x85, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD6, 0x9B, 0x84, 0xA8, 0xD7, 0xC5, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x7A, 0xCB, 0xB3, 0x11, 0x46, 0xD7, 0x99), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x23, 0xBF, 0x75, 0x75, 0xA1, 0x95, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x66, 0x5D, 0x34, 0x13, 0xA9, 0x03, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x80, 0x9D, 0x5F, 0xD2, 0x44, 0xE1, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x5D, 0xBD, 0xA8, 0xBF, 0xB4, 0x25, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x99, 0x1F, 0x53, 0xF1, 0x57, 0xDB, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x7C, 0xE5, 0xC5, 0x51, 0x0B, 0x4C, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xB0, 0x1A, 0x9C, 0x16, 0xB0, 0x32, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xE3, 0xCF, 0xDD, 0x48, 0xB4, 0x7B, 0x33), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xDD, 0x9E, 0x3C, 0x98, 0x0E, 0x77, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xAB, 0x01, 0xD3, 0x87, 0x74, 0x25, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xA3, 0xE3, 0x76, 0x43, 0x87, 0x12, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0xB1, 0x3B, 0x60, 0x66, 0xEB, 0x98, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x78, 0xC8, 0xD7, 0x4E, 0x75, 0xCA, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xDF, 0x71, 0x19, 0xE7, 0x07, 0x36, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC9, 0xA8, 0x5F, 0x91, 0xBF, 0x47, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x96, 0x58, 0x96, 0x18, 0xB6, 0xFA, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x2D, 0xA9, 0x9B, 0x86, 0xDB, 0x0C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0B, 0x2D, 0x56, 0x4A, 0xD3, 0x93, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x15, 0xE2, 0x65, 0x12, 0x86, 0x0E, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x41, 0x4D, 0xC1, 0xCB, 0xE4, 0xC3, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x53, 0x10, 0xCA, 0xA3, 0xAC, 0x83, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x01, 0x22, 0x96, 0x10, 0xAD, 0x69, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x46, 0x4E, 0xD8, 0xEA, 0xD6, 0x9D, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x2F, 0x7F, 0x62, 0x62, 0x80, 0xD0, 0x14), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xDA, 0x00, 0x63, 0x09, 0xBD, 0x6A, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD4, 0x6E, 0x48, 0x05, 0xB7, 0xF7, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x4D, 0xD7, 0x00, 0x4A, 0x15, 0x27, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x15, 0xAA, 0x37, 0x27, 0x34, 0x18, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x20, 0x2C, 0x84, 0x1B, 0x88, 0xBA, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x09, 0xD6, 0x04, 0xA2, 0x60, 0x84, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x04, 0x94, 0x08, 0xD4, 0xED, 0x47, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xF3, 0xE4, 0x3E, 0xB9, 0x5B, 0x35, 0x42), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xD8, 0xB6, 0x80, 0xD6, 0xF1, 0x30, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x14, 0xA6, 0x85, 0xEE, 0xA7, 0xD8, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x49, 0x2A, 0x1E, 0x7C, 0xE9, 0x2D, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x87, 0x56, 0x91, 0x03, 0x77, 0x4D, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x52, 0xD4, 0xAA, 0xF7, 0xFA, 0xB0, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x11, 0x39, 0xB1, 0xE7, 0x76, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x13, 0xBC, 0x37, 0x5D, 0x74, 0xCD, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x48, 0x14, 0x23, 0x30, 0xF8, 0x46, 0x37), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x27, 0xB0, 0xD9, 0xB2, 0x74, 0xB4, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xA6, 0xB9, 0x6F, 0x9F, 0x64, 0x36, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x2B, 0x78, 0x40, 0x05, 0x2B, 0x7B, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x68, 0x3A, 0xB6, 0x4A, 0xE2, 0xDB, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x33, 0xD7, 0x34, 0x8B, 0x25, 0x45, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xCE, 0xA8, 0xC9, 0x01, 0xFB, 0x0E, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF9, 0x51, 0x4C, 0x12, 0x9F, 0x60, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x85, 0xBD, 0x30, 0x37, 0x84, 0x39, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x33, 0xAF, 0x2E, 0xB8, 0x2E, 0xCC, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xB1, 0x73, 0x59, 0x4E, 0x0C, 0x09, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x24, 0x89, 0x81, 0x12, 0xFF, 0xBB, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0x1A, 0x66, 0xEE, 0xED, 0xB6, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xBD, 0x04, 0x20, 0x5D, 0xFB, 0xBF, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF8, 0x34, 0xA3, 0xFF, 0x45, 0xDE, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x18, 0x73, 0xF1, 0x32, 0x25, 0x58, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xC1, 0x14, 0xE3, 0x9E, 0x40, 0x0F, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0x9D, 0x9C, 0x00, 0xF7, 0x56, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBA, 0x87, 0xF9, 0x15, 0x0C, 0x66, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x1F, 0xC1, 0x28, 0xB0, 0x47, 0x0D, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xCA, 0x27, 0xEE, 0x4B, 0x23, 0x2B, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB5, 0x68, 0xC8, 0x17, 0x5D, 0xC3, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x02, 0x08, 0xEE, 0x20, 0x9D, 0xEA, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x14, 0x50, 0xD4, 0x7D, 0x5F, 0xCF, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFA, 0xF8, 0xA7, 0xC6, 0xDC, 0x14, 0x8C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xBD, 0x0A, 0x1A, 0x18, 0x98, 0xDC, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x63, 0x02, 0xB7, 0xD5, 0x5B, 0x5A, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB1, 0xD7, 0x4B, 0x15, 0x39, 0x61, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x32, 0xE1, 0x9E, 0x70, 0x1B, 0xCE, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD8, 0x18, 0x83, 0x52, 0x9B, 0x6D, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x55, 0x56, 0x19, 0x34, 0xA4, 0xEA, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA9, 0x55, 0x80, 0xE3, 0x15, 0x36, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x06, 0xC8, 0x1D, 0x17, 0x0D, 0xAD, 0x16), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xD6, 0xF0, 0xCC, 0xF3, 0x63, 0x53, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x5A, 0xDC, 0x46, 0xBD, 0x0D, 0xAD, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x2F, 0x11, 0x60, 0x15, 0x51, 0x4A, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE3, 0x93, 0x38, 0xD5, 0x83, 0xAA, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA6, 0xCC, 0xB1, 0xFD, 0xBB, 0x1A, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x54, 0xC8, 0x54, 0x6F, 0x79, 0x1A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4A, 0xDA, 0x28, 0x92, 0x97, 0x9D, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x4B, 0xDB, 0xC7, 0x52, 0xC5, 0x66, 0x34), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7E, 0x92, 0x53, 0x30, 0x93, 0xFD, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0x6A, 0xB1, 0x91, 0x0A, 0xB4, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x9D, 0x40, 0x3F, 0xE3, 0xF1, 0x01, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x0E, 0xD8, 0xED, 0x11, 0x8E, 0x4C, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x4A, 0x1B, 0x88, 0xDF, 0x8D, 0x29, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x23, 0x21, 0x11, 0xAB, 0x77, 0x81, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xAF, 0x11, 0xFA, 0xBA, 0x40, 0x63, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x6F, 0x8D, 0x80, 0xDF, 0x67, 0xF5, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x8B, 0xB7, 0x08, 0xF4, 0xD7, 0x2D, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x2B, 0x30, 0x02, 0x45, 0x71, 0x08, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x3A, 0xCA, 0x50, 0xF6, 0xC2, 0x19, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xB9, 0x9B, 0x3E, 0x73, 0x95, 0x1D, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x60, 0x59, 0x48, 0xCB, 0xD8, 0xD6, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x6C, 0x89, 0xAB, 0x99, 0xA8, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xA1, 0x8B, 0x4E, 0x06, 0x19, 0xEC, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x95, 0x04, 0xCF, 0xD5, 0x94, 0xB3, 0x02), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x35, 0x93, 0x7C, 0xB3, 0xB8, 0x9E, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x45, 0x5C, 0x7E, 0xBF, 0x75, 0x81, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE8, 0x24, 0xDF, 0xEC, 0x2F, 0x7D, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x8B, 0xD5, 0x6A, 0x9B, 0xA0, 0xE0, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE3, 0x27, 0x82, 0xDE, 0xDD, 0xCA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x57, 0x56, 0x46, 0x05, 0x06, 0x01, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x35, 0xA7, 0x47, 0xE2, 0x6B, 0x2C, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x9D, 0x4C, 0xEC, 0x1F, 0x11, 0x75, 0x2B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xAA, 0x41, 0xC1, 0xE9, 0x0E, 0xE9, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xCF, 0x9C, 0x4B, 0xE8, 0xED, 0x0A, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x73, 0xCA, 0x0C, 0x46, 0x0A, 0x9C, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE1, 0x9E, 0xBC, 0xFE, 0x44, 0x63, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x43, 0x71, 0xEE, 0xF8, 0xC1, 0x8C, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x4B, 0xF0, 0x69, 0x25, 0xBD, 0x71, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x9A, 0xFE, 0x82, 0xE7, 0xC1, 0xC1, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x5A, 0x6E, 0x5E, 0x97, 0x6A, 0x35, 0x8D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x18, 0x6C, 0x7E, 0xB8, 0x9E, 0x57, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xB9, 0xC1, 0xD0, 0xFE, 0x78, 0xFB, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x08, 0xAE, 0x46, 0x34, 0xEA, 0x7A, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1C, 0x56, 0xA9, 0x18, 0x37, 0xD4, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x63, 0xE9, 0x0A, 0xB6, 0x38, 0x3C, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x4F, 0xA4, 0x6E, 0x85, 0x31, 0x23, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xAD, 0xC4, 0xC3, 0xB1, 0x4B, 0x1C, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x56, 0x4A, 0x38, 0xB3, 0x6B, 0x6F, 0x2C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xC7, 0x19, 0xDE, 0x21, 0xED, 0x89, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xBE, 0xA6, 0xAE, 0xEB, 0x9D, 0xA7, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x0E, 0x13, 0x1E, 0x86, 0x57, 0xC3, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4B, 0x30, 0x46, 0x52, 0xC1, 0xEC, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xD5, 0x44, 0x31, 0x96, 0x3B, 0x26, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x68, 0xA8, 0x67, 0x78, 0x39, 0xE8, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x78, 0xB7, 0xDD, 0xF2, 0x58, 0xB6, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x3C, 0xB3, 0x26, 0xC4, 0x2C, 0x8C, 0xA5), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x24, 0xE5, 0x73, 0xEE, 0x9A, 0x02, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x6A, 0x65, 0x60, 0xF3, 0x62, 0xE3, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x07, 0x84, 0xE6, 0x3B, 0x46, 0x65, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x8F, 0x0C, 0xB0, 0xE1, 0x04, 0x82, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x13, 0xBF, 0x3D, 0xA0, 0x48, 0xA2, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x26, 0x76, 0x74, 0xAB, 0x0B, 0x29, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x6E, 0x5F, 0x03, 0x34, 0x7C, 0x38, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x72, 0xF9, 0x3B, 0x3C, 0xA4, 0xBC, 0x7C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xCE, 0x18, 0x80, 0xB8, 0x24, 0x45, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x09, 0x03, 0xB8, 0x06, 0x64, 0xF7, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x26, 0xB1, 0x10, 0x6D, 0x71, 0x12, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x12, 0xC6, 0x6E, 0x1E, 0x6A, 0xC3, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xD3, 0x0A, 0xDE, 0xD8, 0x6B, 0x04, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x87, 0x5B, 0xAE, 0xDB, 0x3C, 0xC0, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF5, 0xF9, 0xC1, 0x9A, 0x89, 0xBB, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x69, 0x72, 0x8B, 0xAE, 0x32, 0x13, 0x11), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x16, 0x07, 0x50, 0xFA, 0x4C, 0xCF, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x50, 0x21, 0xE9, 0xDE, 0xEC, 0x7E, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x2F, 0xE8, 0x83, 0x30, 0x0B, 0x65, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x0B, 0x99, 0xAC, 0xC9, 0xBA, 0x6C, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x59, 0x5A, 0x0D, 0x7B, 0x9E, 0x08, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x91, 0xB2, 0xDC, 0x90, 0xCE, 0x67, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x93, 0x60, 0x0C, 0xD7, 0x1F, 0x2F, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7F, 0x9D, 0x40, 0xF8, 0x78, 0x7A, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x22, 0x95, 0xE8, 0xEF, 0x31, 0x57, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x88, 0x53, 0xFE, 0xAF, 0x7C, 0x47, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xCE, 0xCC, 0x79, 0xE8, 0x9F, 0x8C, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x16, 0xDD, 0x77, 0x6E, 0x8A, 0x73, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x07, 0x97, 0x21, 0x3B, 0xF8, 0x5F, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xB5, 0xD2, 0x81, 0x84, 0xF0, 0xE7, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x8F, 0x75, 0x09, 0x6A, 0x0E, 0x53, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x4F, 0x70, 0x97, 0xC7, 0xAC, 0x7D, 0x3F), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x3C, 0x6A, 0xB4, 0x10, 0xA9, 0xC8, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC5, 0xD6, 0x69, 0x16, 0xB8, 0xAC, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x44, 0xDC, 0xEB, 0x48, 0x54, 0x5D, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x48, 0x9B, 0xD7, 0x72, 0x69, 0xA4, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x0D, 0x36, 0x9A, 0x66, 0x0B, 0xEC, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC6, 0xD4, 0xB6, 0x60, 0xE5, 0xC3, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x29, 0x42, 0xE0, 0x9D, 0xFD, 0x7C, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x10, 0xBA, 0x55, 0xBC, 0x3B, 0x38, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x66, 0xFA, 0x05, 0x73, 0x03, 0x1B, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xA4, 0x66, 0x12, 0x96, 0x7B, 0x02, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xDE, 0x6D, 0x98, 0xD1, 0xD5, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF5, 0x44, 0xB8, 0x8E, 0xF6, 0x8C, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x15, 0x2B, 0x72, 0xBC, 0x49, 0xE5, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x44, 0xD7, 0xDF, 0x8F, 0xEB, 0x8D, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x64, 0x88, 0xAA, 0xB7, 0xE4, 0x70, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x14, 0xBB, 0xE9, 0x9B, 0xB9, 0x65, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x8E, 0x88, 0xF5, 0xF1, 0xC1, 0x89, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x30, 0x53, 0xE6, 0xFB, 0x2D, 0x82, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE4, 0xFF, 0xBA, 0x31, 0x79, 0xAB, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x09, 0xF7, 0xB7, 0x09, 0x78, 0x4C, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xAE, 0xC2, 0x44, 0xDC, 0x17, 0x78, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD4, 0x17, 0x43, 0x19, 0x74, 0x9E, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x64, 0x3B, 0x73, 0xA2, 0x99, 0x27, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0x36, 0x5F, 0xD3, 0x14, 0xB1, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x07, 0xAB, 0xFD, 0x9B, 0x03, 0xC5, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xBE, 0xB0, 0x1D, 0xF2, 0x0C, 0x73, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE7, 0x7B, 0x87, 0xD3, 0x34, 0xFD, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x25, 0x3D, 0xC7, 0x36, 0x83, 0x53, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x7C, 0xCF, 0x63, 0x55, 0x12, 0x11, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x34, 0x4D, 0x27, 0x92, 0xAC, 0x18, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x42, 0x61, 0x9D, 0x2E, 0xFF, 0x13, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xDE, 0x92, 0x65, 0x57, 0x0D, 0xBC, 0x0A), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x7B, 0x6E, 0xC6, 0x2A, 0x21, 0x74, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xA7, 0x53, 0x4D, 0x29, 0x36, 0xEF, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xD6, 0x41, 0xC7, 0x99, 0xAD, 0x50, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xAC, 0x41, 0x9F, 0xFB, 0x4C, 0x86, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xBB, 0xE6, 0x25, 0x28, 0xAA, 0xEB, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x04, 0xA2, 0xC3, 0xAA, 0x08, 0x8A, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x2B, 0x5B, 0xE2, 0x8D, 0x76, 0xEA, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x33, 0xD2, 0x21, 0x4D, 0x62, 0xE3, 0x8E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x06, 0x8B, 0x2B, 0xC2, 0xC4, 0xB1, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF5, 0xA1, 0xC0, 0x03, 0x6A, 0x29, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA9, 0xEF, 0x55, 0xB6, 0x1A, 0x9F, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x54, 0x32, 0xBE, 0x06, 0x43, 0xB5, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xD6, 0xD9, 0x20, 0x89, 0xBE, 0xD4, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x26, 0x95, 0x10, 0xCE, 0xB4, 0x88, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xA6, 0x27, 0xAC, 0x32, 0xBA, 0xBD, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xA6, 0xAE, 0x9C, 0x7B, 0xBE, 0xA1, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xCD, 0x4D, 0x3D, 0xDF, 0x96, 0xBB, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0x11, 0x06, 0xCC, 0x0E, 0x31, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xE4, 0xF4, 0xAD, 0x7B, 0x5F, 0xF1, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x54, 0xBE, 0xF4, 0x8A, 0x03, 0x47, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x53, 0x00, 0x7F, 0xB0, 0x8A, 0x68, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0xB1, 0x73, 0x6F, 0x5B, 0x0E, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x32, 0xE3, 0x43, 0x64, 0x75, 0xFB, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x18, 0x55, 0x8A, 0x4E, 0x6E, 0x35, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x97, 0x15, 0x1E, 0xCB, 0xF2, 0x9C, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xD1, 0xBB, 0xF3, 0x70, 0xAD, 0x13, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x96, 0xA4, 0xC5, 0x5E, 0xDA, 0xD5, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x81, 0xE9, 0x65, 0x66, 0x76, 0x47, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x87, 0x06, 0x73, 0xCF, 0x34, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x81, 0x15, 0x42, 0xA2, 0x79, 0x5B, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA2, 0x7D, 0x09, 0x14, 0x64, 0xC6, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x6D, 0xC4, 0xED, 0xF1, 0xD6, 0xE9, 0x24), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xD5, 0xBB, 0x25, 0xA3, 0xDD, 0xA3, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xF2, 0x68, 0x67, 0x39, 0x8F, 0x73, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x76, 0x28, 0x89, 0xAD, 0x32, 0xE0, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x90, 0xCC, 0x57, 0x58, 0xAA, 0xC9, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD7, 0x43, 0xD2, 0xCE, 0x5E, 0xA0, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xB0, 0xB8, 0xA4, 0x9E, 0x96, 0x26, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x61, 0x1D, 0xF3, 0x65, 0x5E, 0x60, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x1E, 0x65, 0xED, 0xCF, 0x07, 0x60, 0x20), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x30, 0x17, 0x8A, 0x91, 0x88, 0x0A, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7D, 0x18, 0xA4, 0xAC, 0x59, 0xFC, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x31, 0x8B, 0x25, 0x65, 0x39, 0x9A, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x16, 0x4B, 0x68, 0xBA, 0x59, 0x13, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xD3, 0xC5, 0x56, 0xC9, 0x8C, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC6, 0x9F, 0xF4, 0xE6, 0xF7, 0xB4, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x7C, 0x03, 0x00, 0x26, 0x9F, 0xD8, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x1D, 0x6E, 0x00, 0xB9, 0x00, 0x6E, 0x93), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x63, 0xDA, 0x03, 0x2B, 0xD5, 0x0B, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xFC, 0xE2, 0xC8, 0x47, 0xF0, 0xAE, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x4C, 0xF7, 0x50, 0x0C, 0x48, 0x06, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2B, 0x32, 0x98, 0x0E, 0x7E, 0x61, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x02, 0x27, 0xFE, 0x75, 0x86, 0xDF, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x30, 0xB1, 0x22, 0x32, 0x1B, 0xFE, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x27, 0xF7, 0x78, 0x6F, 0xD7, 0xFD, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x78, 0xCC, 0xEA, 0xC0, 0x50, 0x24, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x2B, 0x4F, 0x7F, 0x58, 0xE6, 0xC2, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x43, 0xD5, 0xA7, 0x35, 0x3C, 0x80, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x6D, 0x4B, 0x12, 0x00, 0x7B, 0xE6, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x15, 0xBD, 0xD0, 0x9B, 0xCA, 0xAA, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xCE, 0x9C, 0xE3, 0x8B, 0x60, 0x7A, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xDA, 0x4B, 0x03, 0xA7, 0x8D, 0x43, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAF, 0x00, 0x2B, 0x32, 0xF0, 0x22, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xD9, 0x99, 0x99, 0xBE, 0x43, 0x99, 0x3E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x71, 0x41, 0xF4, 0xB5, 0xFD, 0xDD, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xE2, 0x20, 0x4C, 0xD1, 0x2E, 0x1F, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x43, 0x48, 0x76, 0x8A, 0x49, 0xAC, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1A, 0x55, 0xA8, 0xA3, 0xD4, 0x57, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xA6, 0x84, 0x39, 0xC9, 0x13, 0xBB, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xFA, 0xA9, 0x70, 0xDE, 0x83, 0xDD, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xC9, 0xD9, 0x3E, 0x44, 0x91, 0x68, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x9F, 0x85, 0x6D, 0xF7, 0x54, 0x36, 0x82), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x6B, 0xA6, 0xA3, 0xE5, 0xD4, 0x46, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x3E, 0xDC, 0x84, 0x7C, 0x7B, 0x24, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xED, 0x7F, 0x86, 0x07, 0x6C, 0x57, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x06, 0xFE, 0x52, 0x12, 0x79, 0x69, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xD1, 0x44, 0x5F, 0x21, 0x3A, 0xC3, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD9, 0x4A, 0xC0, 0x75, 0xAB, 0x17, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x81, 0x94, 0xB6, 0x80, 0x6B, 0x6F, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBE, 0x8E, 0xA5, 0xAA, 0xBC, 0x1E, 0x3E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xC7, 0x85, 0xA6, 0x59, 0x9B, 0xB1, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xCE, 0x40, 0xD1, 0xFB, 0xDF, 0x94, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xB8, 0x5E, 0xBF, 0x45, 0xA8, 0x2D, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9C, 0x06, 0x1B, 0xA9, 0x57, 0xB9, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xE9, 0xCE, 0xA2, 0xD3, 0x74, 0xA1, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x5F, 0x34, 0x78, 0xDB, 0xAE, 0x3A, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x32, 0x84, 0x3E, 0x68, 0x6A, 0x43, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xBC, 0x39, 0x36, 0xA4, 0xC5, 0xBB, 0x11), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x07, 0xA2, 0xB5, 0xC9, 0x0F, 0x4D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0x67, 0xE6, 0xF1, 0x46, 0xEB, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x41, 0x23, 0x95, 0xE7, 0xE0, 0x10, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x69, 0xFE, 0x68, 0x8C, 0xC6, 0x5F, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB9, 0x2B, 0x3D, 0xD2, 0x4F, 0xD8, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x09, 0xF5, 0x5F, 0xCF, 0xF6, 0x91, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x15, 0x42, 0x6B, 0x6D, 0xB5, 0xF3, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x56, 0x9D, 0xC5, 0xFF, 0xCA, 0x13, 0x9B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x38, 0xE6, 0x23, 0x63, 0x48, 0x3C, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x68, 0x3C, 0xD1, 0x3B, 0xE9, 0x3B, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x08, 0x54, 0x49, 0xD1, 0x46, 0x45, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x70, 0x52, 0x6E, 0x79, 0xC4, 0x5E, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xDF, 0xE8, 0x5A, 0x32, 0x81, 0xDA, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x2D, 0x94, 0x5B, 0xB5, 0x35, 0x9F, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x12, 0x8D, 0xC3, 0x36, 0x36, 0xB2, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x2F, 0x22, 0x38, 0x5B, 0x18, 0x4C, 0x35), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC1, 0x22, 0x0E, 0xF0, 0x73, 0x11, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xAE, 0xA4, 0x56, 0x18, 0x61, 0x66, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFB, 0x72, 0x08, 0x84, 0x38, 0x51, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x86, 0xA8, 0xB9, 0x31, 0x99, 0x29, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xFB, 0xC3, 0x42, 0xB3, 0xC7, 0x6F, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xF8, 0xE1, 0x09, 0xBE, 0x75, 0xB0, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x7D, 0xFF, 0xF4, 0x99, 0xFC, 0x13, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x1B, 0x84, 0x81, 0x42, 0x22, 0xC6, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE0, 0x37, 0xA4, 0xA0, 0x2F, 0x38, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x3D, 0xB7, 0x40, 0x2F, 0x39, 0x3C, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x3B, 0x8A, 0x51, 0xAE, 0x40, 0x49, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x20, 0x9F, 0xDD, 0xA9, 0xD0, 0x77, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x1D, 0x64, 0xDA, 0xA0, 0x53, 0xC7, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x7B, 0x66, 0x55, 0x94, 0xD1, 0x51, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xB5, 0x5B, 0x38, 0x35, 0x40, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0x0F, 0xF0, 0x73, 0x79, 0x43, 0x61), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x47, 0x45, 0x69, 0x80, 0x72, 0x72, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x11, 0x99, 0x59, 0xDB, 0x48, 0x80, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x6E, 0x3D, 0xFC, 0x37, 0x15, 0xF4, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xBB, 0x5B, 0xA6, 0x35, 0x8D, 0x28, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x1A, 0x3B, 0x2C, 0x8F, 0xD3, 0xAA, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x1C, 0x1A, 0xF8, 0x02, 0xD9, 0x7B, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x69, 0xAC, 0xF8, 0x54, 0x31, 0x14, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x8A, 0xE6, 0xDE, 0x58, 0xB9, 0xC4, 0x7A), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x83, 0x52, 0xFE, 0xF9, 0x7B, 0xE9, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xA2, 0x55, 0x46, 0x15, 0x49, 0xC1, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBC, 0x5C, 0x91, 0xBD, 0xB9, 0x9C, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xFD, 0xB1, 0x4E, 0x5F, 0x74, 0xEE, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x8B, 0xD8, 0x8B, 0x17, 0x73, 0x1B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x92, 0xD7, 0x67, 0x06, 0xAD, 0x25, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0x80, 0x24, 0xE2, 0x27, 0x5F, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x1C, 0xCE, 0xD0, 0x67, 0xCA, 0xD4, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xF1, 0xDD, 0x33, 0x66, 0xF9, 0x05, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xE5, 0x6B, 0x79, 0xBD, 0x48, 0x42, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x14, 0x52, 0xE3, 0x53, 0xB4, 0x50, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x84, 0x6C, 0xCF, 0xDA, 0xB2, 0x20, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xD6, 0x1A, 0xE5, 0xE2, 0x29, 0x70, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x61, 0xFE, 0xBB, 0x21, 0x82, 0xD1, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0xF0, 0x9C, 0x8B, 0x1A, 0x42, 0x30, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xD6, 0x49, 0x81, 0x92, 0xF1, 0xD0, 0x90), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x91, 0x93, 0x6A, 0xA6, 0x22, 0xE9, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xDC, 0xC3, 0x69, 0x11, 0x95, 0x7D, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xA3, 0x9D, 0x87, 0x5E, 0x64, 0x41, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x87, 0x5A, 0x15, 0xBD, 0x6E, 0x3C, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x8D, 0x50, 0xCC, 0xCF, 0xB7, 0x8F, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x65, 0xCD, 0x31, 0x30, 0xF1, 0x68, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x5C, 0x66, 0x67, 0x92, 0x30, 0x57, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x9B, 0x01, 0x3D, 0x20, 0x8B, 0xD1, 0x0D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC0, 0xE6, 0x4F, 0xDE, 0x62, 0xAB, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x48, 0xB3, 0x1C, 0x0F, 0x16, 0x93, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x63, 0xBD, 0x1F, 0x16, 0x50, 0x56, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x06, 0xBC, 0xE9, 0x27, 0x1C, 0x9A, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xFE, 0x21, 0xC5, 0x39, 0x55, 0xE1, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA8, 0xD0, 0x96, 0x0E, 0xB5, 0xB2, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xE7, 0x4B, 0xF3, 0x11, 0x0C, 0xC9, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x3A, 0xC4, 0x87, 0x71, 0xEE, 0xFA, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x77, 0xEE, 0x81, 0x5E, 0x96, 0xEA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xDF, 0xA9, 0xF4, 0x4F, 0x7C, 0xB2, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD4, 0xDF, 0x35, 0x63, 0x47, 0x25, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3D, 0xFF, 0xA4, 0x02, 0xC3, 0x95, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x10, 0x78, 0xD1, 0x2B, 0xB7, 0xBE, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE9, 0x57, 0xF9, 0xE0, 0xD8, 0xFC, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xC4, 0x01, 0xD6, 0xB4, 0xE7, 0x78, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6C, 0xB9, 0x13, 0xA4, 0xE8, 0x6D, 0x6F), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xB0, 0xC9, 0xCD, 0xBF, 0xA2, 0x1E, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x4F, 0x86, 0x22, 0x9B, 0xEA, 0xE8, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x46, 0xDF, 0x43, 0xB9, 0x82, 0x2D, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x32, 0xF1, 0x4E, 0x95, 0x41, 0xAE, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x93, 0x26, 0xFC, 0xD3, 0x90, 0xDC, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x05, 0x45, 0xCA, 0xF9, 0x5A, 0x89, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x82, 0x63, 0x4E, 0x55, 0x1D, 0x3A, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x69, 0x52, 0x49, 0xE9, 0xED, 0x57, 0x34), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x64, 0xE9, 0xAC, 0x4C, 0x4A, 0xEA, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xE9, 0x0B, 0x99, 0xE7, 0xF9, 0xA9, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x0C, 0xC1, 0xF4, 0x8D, 0x07, 0xB6, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x68, 0xFA, 0x35, 0xE4, 0x9E, 0xAE, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2D, 0x1A, 0x13, 0x8E, 0x02, 0xE2, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x28, 0x86, 0x46, 0x7B, 0x3A, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4C, 0x64, 0x59, 0x0A, 0xF9, 0x02, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x4F, 0x23, 0xA2, 0xC3, 0xD5, 0xEF, 0x42), -}; -static const mbedtls_ecp_point brainpoolP512r1_T[32] = { - ECP_POINT_INIT_XY_Z1(brainpoolP512r1_T_0_X, brainpoolP512r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_1_X, brainpoolP512r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_2_X, brainpoolP512r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_3_X, brainpoolP512r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_4_X, brainpoolP512r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_5_X, brainpoolP512r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_6_X, brainpoolP512r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_7_X, brainpoolP512r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_8_X, brainpoolP512r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_9_X, brainpoolP512r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_10_X, brainpoolP512r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_11_X, brainpoolP512r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_12_X, brainpoolP512r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_13_X, brainpoolP512r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_14_X, brainpoolP512r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_15_X, brainpoolP512r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_16_X, brainpoolP512r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_17_X, brainpoolP512r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_18_X, brainpoolP512r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_19_X, brainpoolP512r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_20_X, brainpoolP512r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_21_X, brainpoolP512r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_22_X, brainpoolP512r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_23_X, brainpoolP512r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_24_X, brainpoolP512r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_25_X, brainpoolP512r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_26_X, brainpoolP512r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_27_X, brainpoolP512r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_28_X, brainpoolP512r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_29_X, brainpoolP512r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_30_X, brainpoolP512r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_31_X, brainpoolP512r1_T_31_Y), -}; -#else -#define brainpoolP512r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - - -#if defined(ECP_LOAD_GROUP) || defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ - defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* - * Create an MPI from embedded constants - * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint) and - * len < 1048576) - */ -static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len) -{ - X->s = 1; - X->n = (unsigned short) (len / sizeof(mbedtls_mpi_uint)); - X->p = (mbedtls_mpi_uint *) p; -} -#endif - -#if defined(ECP_LOAD_GROUP) -/* - * Set an MPI to static value 1 - */ -static inline void ecp_mpi_set1(mbedtls_mpi *X) -{ - X->s = 1; - X->n = 1; - X->p = mpi_one; -} - -/* - * Make group available from embedded constants - */ -static int ecp_group_load(mbedtls_ecp_group *grp, - const mbedtls_mpi_uint *p, size_t plen, - const mbedtls_mpi_uint *a, size_t alen, - const mbedtls_mpi_uint *b, size_t blen, - const mbedtls_mpi_uint *gx, size_t gxlen, - const mbedtls_mpi_uint *gy, size_t gylen, - const mbedtls_mpi_uint *n, size_t nlen, - const mbedtls_ecp_point *T) -{ - ecp_mpi_load(&grp->P, p, plen); - if (a != NULL) { - ecp_mpi_load(&grp->A, a, alen); - } - ecp_mpi_load(&grp->B, b, blen); - ecp_mpi_load(&grp->N, n, nlen); - - ecp_mpi_load(&grp->G.X, gx, gxlen); - ecp_mpi_load(&grp->G.Y, gy, gylen); - ecp_mpi_set1(&grp->G.Z); - - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - grp->nbits = mbedtls_mpi_bitlen(&grp->N); - - grp->h = 1; - - grp->T = (mbedtls_ecp_point *) T; - /* - * Set T_size to 0 to prevent T free by mbedtls_ecp_group_free. - */ - grp->T_size = 0; - - return 0; -} -#endif /* ECP_LOAD_GROUP */ - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* Forward declarations */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static int ecp_mod_p192(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static int ecp_mod_p224(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static int ecp_mod_p256(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static int ecp_mod_p384(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static int ecp_mod_p521(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); -#endif - -#define NIST_MODP(P) grp->modp = ecp_mod_ ## P; -#else -#define NIST_MODP(P) -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -/* Additional forward declarations */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -static int ecp_mod_p255(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -static int ecp_mod_p448(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *, size_t); -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static int ecp_mod_p192k1(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static int ecp_mod_p224k1(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static int ecp_mod_p256k1(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif - -#if defined(ECP_LOAD_GROUP) -#define LOAD_GROUP_A(G) ecp_group_load(grp, \ - G ## _p, sizeof(G ## _p), \ - G ## _a, sizeof(G ## _a), \ - G ## _b, sizeof(G ## _b), \ - G ## _gx, sizeof(G ## _gx), \ - G ## _gy, sizeof(G ## _gy), \ - G ## _n, sizeof(G ## _n), \ - G ## _T \ - ) - -#define LOAD_GROUP(G) ecp_group_load(grp, \ - G ## _p, sizeof(G ## _p), \ - NULL, 0, \ - G ## _b, sizeof(G ## _b), \ - G ## _gx, sizeof(G ## _gx), \ - G ## _gy, sizeof(G ## _gy), \ - G ## _n, sizeof(G ## _n), \ - G ## _T \ - ) -#endif /* ECP_LOAD_GROUP */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -/* Constants used by ecp_use_curve25519() */ -static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42; - -/* P = 2^255 - 19 */ -static const mbedtls_mpi_uint curve25519_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7F) -}; - -/* N = 2^252 + 27742317777372353535851937790883648493 */ -static const mbedtls_mpi_uint curve25519_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0XED, 0XD3, 0XF5, 0X5C, 0X1A, 0X63, 0X12, 0X58), - MBEDTLS_BYTES_TO_T_UINT_8(0XD6, 0X9C, 0XF7, 0XA2, 0XDE, 0XF9, 0XDE, 0X14), - MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10) -}; - -/* - * Specialized function for creating the Curve25519 group - */ -static int ecp_use_curve25519(mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24)); - - ecp_mpi_load(&grp->P, curve25519_p, sizeof(curve25519_p)); - - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - ecp_mpi_load(&grp->N, curve25519_n, sizeof(curve25519_n)); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 9)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); - mbedtls_mpi_free(&grp->G.Y); - - /* Actually, the required msb for private keys */ - grp->nbits = 254; - -cleanup: - if (ret != 0) { - mbedtls_ecp_group_free(grp); - } - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* Constants used by ecp_use_curve448() */ -static const mbedtls_mpi_sint curve448_a24 = 0x98AA; - -/* P = 2^448 - 2^224 - 1 */ -static const mbedtls_mpi_uint curve448_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFE, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00) -}; - -/* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ -static const mbedtls_mpi_uint curve448_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0XF3, 0X44, 0X58, 0XAB, 0X92, 0XC2, 0X78, 0X23), - MBEDTLS_BYTES_TO_T_UINT_8(0X55, 0X8F, 0XC5, 0X8D, 0X72, 0XC2, 0X6C, 0X21), - MBEDTLS_BYTES_TO_T_UINT_8(0X90, 0X36, 0XD6, 0XAE, 0X49, 0XDB, 0X4E, 0XC4), - MBEDTLS_BYTES_TO_T_UINT_8(0XE9, 0X23, 0XCA, 0X7C, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3F), - MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00) -}; - -/* - * Specialized function for creating the Curve448 group - */ -static int ecp_use_curve448(mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24)); - - ecp_mpi_load(&grp->P, curve448_p, sizeof(curve448_p)); - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 5)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); - mbedtls_mpi_free(&grp->G.Y); - - ecp_mpi_load(&grp->N, curve448_n, sizeof(curve448_n)); - - /* Actually, the required msb for private keys */ - grp->nbits = 447; - -cleanup: - if (ret != 0) { - mbedtls_ecp_group_free(grp); - } - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -/* - * Set a group using well-known domain parameters - */ -int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id) -{ - mbedtls_ecp_group_free(grp); - - mbedtls_ecp_group_init(grp); - - grp->id = id; - - switch (id) { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - NIST_MODP(p192); - return LOAD_GROUP(secp192r1); -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - NIST_MODP(p224); - return LOAD_GROUP(secp224r1); -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - NIST_MODP(p256); - return LOAD_GROUP(secp256r1); -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - NIST_MODP(p384); - return LOAD_GROUP(secp384r1); -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - NIST_MODP(p521); - return LOAD_GROUP(secp521r1); -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - grp->modp = ecp_mod_p192k1; - return LOAD_GROUP_A(secp192k1); -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - grp->modp = ecp_mod_p224k1; - return LOAD_GROUP_A(secp224k1); -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - grp->modp = ecp_mod_p256k1; - return LOAD_GROUP_A(secp256k1); -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - return LOAD_GROUP_A(brainpoolP256r1); -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - return LOAD_GROUP_A(brainpoolP384r1); -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - return LOAD_GROUP_A(brainpoolP512r1); -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - grp->modp = ecp_mod_p255; - return ecp_use_curve25519(grp); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - grp->modp = ecp_mod_p448; - return ecp_use_curve448(grp); -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - - default: - grp->id = MBEDTLS_ECP_DP_NONE; - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* - * Fast reduction modulo the primes used by the NIST curves. - * - * These functions are critical for speed, but not needed for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. - * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic mbedtls_mpi_uint, we can - * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. - */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry) -{ - unsigned char i; - mbedtls_mpi_uint c = 0; - for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) { - *dst += c; c = (*dst < c); - *dst += *src; c += (*dst < *src); - } - *carry += c; -} - -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry) -{ - unsigned char i; - for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) { - *dst += *carry; - *carry = (*dst < *carry); - } -} - -#define WIDTH 8 / sizeof(mbedtls_mpi_uint) -#define A(i) Np + (i) * WIDTH -#define ADD(i) add64(p, A(i), &c) -#define NEXT p += WIDTH; carry64(p, &c) -#define LAST p += WIDTH; do *p = 0; while (++p < end) -#define RESET last_carry[0] = c; c = 0; p = Np -#define ADD_LAST add64(p, last_carry, &c) - -/* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - */ -static int ecp_mod_p192(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(192) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p192_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn) -{ - mbedtls_mpi_uint c = 0, last_carry[WIDTH] = { 0 }; - mbedtls_mpi_uint *p, *end; - - if (Nn != BITS_TO_LIMBS(192) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - p = Np; - end = p + Nn; - - ADD(3); ADD(5); NEXT; // A0 += A3 + A5 - ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5 - ADD(4); ADD(5); // A2 += A4 + A5 - - RESET; - - /* Use the reduction for the carry as well: - * 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192 - * It can generate a carry. */ - ADD_LAST; NEXT; // A0 += last_carry - ADD_LAST; NEXT; // A1 += last_carry - // A2 += carry - - RESET; - - /* Use the reduction for the carry as well: - * 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192 - */ - ADD_LAST; NEXT; // A0 += last_carry - ADD_LAST; NEXT; // A1 += last_carry - // A2 += carry - - LAST; - - return 0; -} - -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#undef RESET -#undef ADD_LAST -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A(i); - -#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ - -#define MAX32 X_limbs -#define A(j) X[j] -#define STORE32 X[i] = (mbedtls_mpi_uint) cur; -#define STORE0 X[i] = 0; - -#else /* 64 bit */ - -#define MAX32 X_limbs * 2 -#define A(j) \ - (j) % 2 ? \ - (uint32_t) (X[(j) / 2] >> 32) : \ - (uint32_t) (X[(j) / 2]) -#define STORE32 \ - if (i % 2) { \ - X[i/2] &= 0x00000000FFFFFFFF; \ - X[i/2] |= (uint64_t) (cur) << 32; \ - } else { \ - X[i/2] &= 0xFFFFFFFF00000000; \ - X[i/2] |= (uint32_t) cur; \ - } - -#define STORE0 \ - if (i % 2) { \ - X[i/2] &= 0x00000000FFFFFFFF; \ - } else { \ - X[i/2] &= 0xFFFFFFFF00000000; \ - } - -#endif - -static inline int8_t extract_carry(int64_t cur) -{ - return (int8_t) (cur >> 32); -} - -#define ADD(j) cur += A(j) -#define SUB(j) cur -= A(j) - -#define ADD_CARRY(cc) cur += (cc) -#define SUB_CARRY(cc) cur -= (cc) - -#define ADD_LAST ADD_CARRY(last_c) -#define SUB_LAST SUB_CARRY(last_c) - -/* - * Helpers for the main 'loop' - */ -#define INIT(b) \ - int8_t c = 0, last_c; \ - int64_t cur; \ - size_t i = 0; \ - LOAD32; - -#define NEXT \ - c = extract_carry(cur); \ - STORE32; i++; LOAD32; \ - ADD_CARRY(c); - -#define RESET \ - c = extract_carry(cur); \ - last_c = c; \ - STORE32; i = 0; LOAD32; \ - c = 0; \ - -#define LAST \ - c = extract_carry(cur); \ - STORE32; i++; \ - if (c != 0) \ - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; \ - while (i < MAX32) { STORE0; i++; } - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(224) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p224_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - if (X_limbs != BITS_TO_LIMBS(224) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - INIT(224); - - SUB(7); SUB(11); NEXT; // A0 += -A7 - A11 - SUB(8); SUB(12); NEXT; // A1 += -A8 - A12 - SUB(9); SUB(13); NEXT; // A2 += -A9 - A13 - SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11 - SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12 - SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13 - SUB(13); ADD(10); // A6 += -A13 + A10 - - RESET; - - /* Use 2^224 = P + 2^96 - 1 to modulo reduce the final carry */ - SUB_LAST; NEXT; // A0 -= last_c - ; NEXT; // A1 - ; NEXT; // A2 - ADD_LAST; NEXT; // A3 += last_c - ; NEXT; // A4 - ; NEXT; // A5 - // A6 - - /* The carry reduction cannot generate a carry - * (see commit 73e8553 for details)*/ - - LAST; - - return 0; -} - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - -/* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - */ -static int ecp_mod_p256(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(256) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p256_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - if (X_limbs != BITS_TO_LIMBS(256) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - INIT(256); - - ADD(8); ADD(9); - SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0 - - ADD(9); ADD(10); - SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1 - - ADD(10); ADD(11); - SUB(13); SUB(14); SUB(15); NEXT; // A2 - - ADD(11); ADD(11); ADD(12); ADD(12); ADD(13); - SUB(15); SUB(8); SUB(9); NEXT; // A3 - - ADD(12); ADD(12); ADD(13); ADD(13); ADD(14); - SUB(9); SUB(10); NEXT; // A4 - - ADD(13); ADD(13); ADD(14); ADD(14); ADD(15); - SUB(10); SUB(11); NEXT; // A5 - - ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13); - SUB(8); SUB(9); NEXT; // A6 - - ADD(15); ADD(15); ADD(15); ADD(8); - SUB(10); SUB(11); SUB(12); SUB(13); // A7 - - RESET; - - /* Use 2^224 * (2^32 - 1) + 2^192 + 2^96 - 1 - * to modulo reduce the final carry. */ - ADD_LAST; NEXT; // A0 - ; NEXT; // A1 - ; NEXT; // A2 - SUB_LAST; NEXT; // A3 - ; NEXT; // A4 - ; NEXT; // A5 - SUB_LAST; NEXT; // A6 - ADD_LAST; // A7 - - RESET; - - /* Use 2^224 * (2^32 - 1) + 2^192 + 2^96 - 1 - * to modulo reduce the carry generated by the previous reduction. */ - ADD_LAST; NEXT; // A0 - ; NEXT; // A1 - ; NEXT; // A2 - SUB_LAST; NEXT; // A3 - ; NEXT; // A4 - ; NEXT; // A5 - SUB_LAST; NEXT; // A6 - ADD_LAST; // A7 - - LAST; - - return 0; -} - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - */ -static int ecp_mod_p384(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(384) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p384_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - if (X_limbs != BITS_TO_LIMBS(384) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - INIT(384); - - ADD(12); ADD(21); ADD(20); - SUB(23); NEXT; // A0 - - ADD(13); ADD(22); ADD(23); - SUB(12); SUB(20); NEXT; // A1 - - ADD(14); ADD(23); - SUB(13); SUB(21); NEXT; // A2 - - ADD(15); ADD(12); ADD(20); ADD(21); - SUB(14); SUB(22); SUB(23); NEXT; // A3 - - ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22); - SUB(15); SUB(23); SUB(23); NEXT; // A4 - - ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23); - SUB(16); NEXT; // A5 - - ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22); - SUB(17); NEXT; // A6 - - ADD(19); ADD(16); ADD(15); ADD(23); - SUB(18); NEXT; // A7 - - ADD(20); ADD(17); ADD(16); - SUB(19); NEXT; // A8 - - ADD(21); ADD(18); ADD(17); - SUB(20); NEXT; // A9 - - ADD(22); ADD(19); ADD(18); - SUB(21); NEXT; // A10 - - ADD(23); ADD(20); ADD(19); - SUB(22); // A11 - - RESET; - - /* Use 2^384 = P + 2^128 + 2^96 - 2^32 + 1 to modulo reduce the final carry */ - ADD_LAST; NEXT; // A0 - SUB_LAST; NEXT; // A1 - ; NEXT; // A2 - ADD_LAST; NEXT; // A3 - ADD_LAST; NEXT; // A4 - ; NEXT; // A5 - ; NEXT; // A6 - ; NEXT; // A7 - ; NEXT; // A8 - ; NEXT; // A9 - ; NEXT; // A10 - // A11 - - RESET; - - ADD_LAST; NEXT; // A0 - SUB_LAST; NEXT; // A1 - ; NEXT; // A2 - ADD_LAST; NEXT; // A3 - ADD_LAST; NEXT; // A4 - ; NEXT; // A5 - ; NEXT; // A6 - ; NEXT; // A7 - ; NEXT; // A8 - ; NEXT; // A9 - ; NEXT; // A10 - // A11 - - LAST; - - return 0; -} -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#undef LOAD32 -#undef MAX32 -#undef A -#undef STORE32 -#undef STORE0 -#undef ADD -#undef SUB -#undef ADD_CARRY -#undef SUB_CARRY -#undef ADD_LAST -#undef SUB_LAST -#undef INIT -#undef NEXT -#undef RESET -#undef LAST - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || - MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* Size of p521 in terms of mbedtls_mpi_uint */ -#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1) - -/* Bits to keep in the most significant mbedtls_mpi_uint */ -#define P521_MASK 0x01FF - -/* - * Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) - */ -static int ecp_mod_p521(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(521) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - mbedtls_mpi_uint carry = 0; - - if (X_limbs != BITS_TO_LIMBS(521) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Step 1: Reduction to P521_WIDTH limbs */ - /* Helper references for bottom part of X */ - mbedtls_mpi_uint *X0 = X; - size_t X0_limbs = P521_WIDTH; - /* Helper references for top part of X */ - mbedtls_mpi_uint *X1 = X + X0_limbs; - size_t X1_limbs = X_limbs - X0_limbs; - /* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1. - * (We are using that 2^P521_WIDTH = 2^(512 + biL) and that - * 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.) - * The high order limb of the result will be held in carry and the rest - * in X0 (that is the result will be represented as - * 2^P521_WIDTH carry + X0). - * - * Also, note that the resulting carry is either 0 or 1: - * X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512 - * therefore - * X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9) - * which in turn is less than 2 * 2^(512 + biL). - */ - mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); - carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); - /* Set X to X0 (by clearing the top part). */ - memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); - - /* Step 2: Reduction modulo P521 - * - * At this point X is reduced to P521_WIDTH limbs. What remains is to add - * the carry (that is 2^P521_WIDTH carry) and to reduce mod P521. */ - - /* 2^P521_WIDTH carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521. - * Also, recall that carry is either 0 or 1. */ - mbedtls_mpi_uint addend = carry << (biL - 9); - /* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */ - addend += (X[P521_WIDTH - 1] >> 9); - X[P521_WIDTH - 1] &= P521_MASK; - - /* Reuse the top part of X (already zeroed) as a helper array for - * carrying out the addition. */ - mbedtls_mpi_uint *addend_arr = X + P521_WIDTH; - addend_arr[0] = addend; - (void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH); - /* Both addends were less than P521 therefore X < 2 * P521. (This also means - * that the result fit in P521_WIDTH limbs and there won't be any carry.) */ - - /* Clear the reused part of X. */ - addend_arr[0] = 0; - - return 0; -} - -#undef P521_WIDTH -#undef P521_MASK - -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - -/* Size of p255 in terms of mbedtls_mpi_uint */ -#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1) - -/* - * Fast quasi-reduction modulo p255 = 2^255 - 19 - * Write N as A0 + 2^256 A1, return A0 + 38 * A1 - */ -static int ecp_mod_p255(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(255) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) -{ - - if (X_Limbs != BITS_TO_LIMBS(255) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL); - if (carry == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - /* Step 1: Reduction to P255_WIDTH limbs */ - if (X_Limbs > P255_WIDTH) { - /* Helper references for top part of X */ - mbedtls_mpi_uint * const A1 = X + P255_WIDTH; - const size_t A1_limbs = X_Limbs - P255_WIDTH; - - /* X = A0 + 38 * A1, capture carry out */ - *carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38); - /* Clear top part */ - memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs); - } - - /* Step 2: Reduce to <2p - * Split as A0 + 2^255*c, with c a scalar, and compute A0 + 19*c */ - *carry <<= 1; - *carry += (X[P255_WIDTH - 1] >> (biL - 1)); - *carry *= 19; - - /* Clear top bit */ - X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1; - /* Since the top bit for X has been cleared 0 + 0 + Carry - * will not overflow. - * - * Furthermore for 2p = 2^256-38. When a carry propagation on the highest - * limb occurs, X > 2^255 and all the remaining bits on the limb are zero. - * - If X < 2^255 ==> X < 2p - * - If X > 2^255 ==> X < 2^256 - 2^255 < 2p */ - (void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH); - - mbedtls_free(carry); - return 0; -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - -/* Size of p448 in terms of mbedtls_mpi_uint */ -#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint)) - -/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ -#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y)) -#define P224_SIZE (224 / 8) -#define P224_WIDTH_MIN (P224_SIZE / sizeof(mbedtls_mpi_uint)) -#define P224_WIDTH_MAX DIV_ROUND_UP(P224_SIZE, sizeof(mbedtls_mpi_uint)) -#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224) - -static int ecp_mod_p448(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(448) * 2; - - /* This is required as some tests and use cases do not pass in a Bignum of - * the correct size, and expect the growth to be done automatically, which - * will no longer happen. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - - ret = mbedtls_ecp_mod_p448_raw(N->p, N->n); - -cleanup: - return ret; -} - -/* - * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 - * Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 + - * (B0 + B1) * 2^224. This is different to the reference implementation of - * Curve448, which uses its own special 56-bit limbs rather than a generic - * bignum library. We could squeeze some extra speed out on 32-bit machines by - * splitting N up into 32-bit limbs and doing the arithmetic using the limbs - * directly as we do for the NIST primes above, but for 64-bit targets it should - * use half the number of operations if we do the reduction with 224-bit limbs, - * since mpi_core_add will then use 64-bit adds. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - size_t round; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (X_limbs != BITS_TO_LIMBS(448) * 2) { - return 0; - } - - size_t M_limbs = X_limbs - (P448_WIDTH); - - if (M_limbs > P448_WIDTH) { - /* Shouldn't be called with X larger than 2^896! */ - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Both M and Q require an extra limb to catch carries. */ - M_limbs++; - - const size_t Q_limbs = M_limbs; - mbedtls_mpi_uint *M = NULL; - mbedtls_mpi_uint *Q = NULL; - - M = mbedtls_calloc(M_limbs, ciL); - - if (M == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - Q = mbedtls_calloc(Q_limbs, ciL); - - if (Q == NULL) { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - /* M = A1 */ - memset(M, 0, (M_limbs * ciL)); - /* Do not copy into the overflow limb, as this would read past the end of - * X. */ - memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL)); - - /* X = A0 */ - memset(X + P448_WIDTH, 0, ((M_limbs - 1) * ciL)); - - /* X = X + M = A0 + A1 */ - /* Carry here fits in oversize X. Oversize M means it will get - * added in, not returned as carry. */ - (void) mbedtls_mpi_core_add(X, X, M, M_limbs); - - /* Q = B1 = M >> 224 */ - memcpy(Q, (char *) M + P224_SIZE, P224_SIZE); - memset((char *) Q + P224_SIZE, 0, P224_SIZE); - - /* X = X + Q = (A0 + A1) + B1 - * Oversize Q catches potential carry here when X is already max 448 bits. - */ - (void) mbedtls_mpi_core_add(X, X, Q, Q_limbs); - - /* M = B0 */ -#ifdef MBEDTLS_HAVE_INT64 - M[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS); - #endif - memset(M + P224_WIDTH_MAX, 0, ((M_limbs - P224_WIDTH_MAX) * ciL)); - - /* M = M + Q = B0 + B1 */ - (void) mbedtls_mpi_core_add(M, M, Q, Q_limbs); - - /* M = (B0 + B1) * 2^224 */ - /* Shifted carry bit from the addition fits in oversize M. */ - memmove((char *) M + P224_SIZE, M, P224_SIZE + ciL); - memset(M, 0, P224_SIZE); - - /* X = X + M = (A0 + A1 + B1) + (B0 + B1) * 2^224 */ - (void) mbedtls_mpi_core_add(X, X, M, M_limbs); - - /* In the second and third rounds A1 and B0 have at most 1 non-zero limb and - * B1=0. - * Using this we need to calculate: - * A0 + A1 + B1 + (B0 + B1) * 2^224 = A0 + A1 + B0 * 2^224. */ - for (round = 0; round < 2; ++round) { - - /* M = A1 */ - memset(M, 0, (M_limbs * ciL)); - memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL)); - - /* X = A0 */ - memset(X + P448_WIDTH, 0, ((M_limbs - 1) * ciL)); - - /* M = A1 + B0 * 2^224 - * We know that only one limb of A1 will be non-zero and that it will be - * limb 0. We also know that B0 is the bottom 224 bits of A1 (which is - * then shifted up 224 bits), so, given M is currently A1 this turns - * into: - * M = M + (M << 224) - * As the single non-zero limb in B0 will be A1 limb 0 shifted up by 224 - * bits, we can just move that into the right place, shifted up - * accordingly.*/ - M[P224_WIDTH_MIN] = M[0] << (224 & (biL - 1)); - - /* X = A0 + (A1 + B0 * 2^224) */ - (void) mbedtls_mpi_core_add(X, X, M, M_limbs); - } - - ret = 0; - -cleanup: - mbedtls_free(M); - mbedtls_free(Q); - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - -/* - * Fast quasi-reduction modulo P = 2^s - R, - * with R about 33 bits, used by the Koblitz curves. - * - * Write X as A0 + 2^224 A1, return A0 + R * A1. - */ -#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R - -static inline int ecp_mod_koblitz(mbedtls_mpi_uint *X, - size_t X_limbs, - mbedtls_mpi_uint *R, - size_t bits) -{ - int ret = 0; - - /* Determine if A1 is aligned to limb bitsize. If not then the used limbs - * of P, A0 and A1 must be set accordingly and there is a middle limb - * which is shared by A0 and A1 and need to handle accordingly. - */ - size_t shift = bits % biL; - size_t adjust = (shift + biL - 1) / biL; - size_t P_limbs = bits / biL + adjust; - - mbedtls_mpi_uint *A1 = mbedtls_calloc(P_limbs, ciL); - if (A1 == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - /* Create a buffer to store the value of `R * A1` */ - size_t R_limbs = P_KOBLITZ_R; - size_t M_limbs = P_limbs + R_limbs; - mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL); - if (M == NULL) { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - mbedtls_mpi_uint mask = 0; - if (adjust != 0) { - mask = ((mbedtls_mpi_uint) 1 << shift) - 1; - } - - /* Two passes are needed to reduce the value of `A0 + R * A1` and then - * we need an additional one to reduce the possible overflow during - * the addition. - */ - for (size_t pass = 0; pass < 3; pass++) { - /* Copy A1 */ - memcpy(A1, X + P_limbs - adjust, P_limbs * ciL); - - /* Shift A1 to be aligned */ - if (shift != 0) { - mbedtls_mpi_core_shift_r(A1, P_limbs, shift); - } - - /* Zeroize the A1 part of the shared limb */ - if (mask != 0) { - X[P_limbs - 1] &= mask; - } - - /* X = A0 - * Zeroize the A1 part of X to keep only the A0 part. - */ - for (size_t i = P_limbs; i < X_limbs; i++) { - X[i] = 0; - } - - /* X = A0 + R * A1 */ - mbedtls_mpi_core_mul(M, A1, P_limbs, R, R_limbs); - (void) mbedtls_mpi_core_add(X, X, M, P_limbs + R_limbs); - - /* Carry can not be generated since R is a 33-bit value and stored in - * 64 bits. The result value of the multiplication is at most - * P length + 33 bits in length and the result value of the addition - * is at most P length + 34 bits in length. So the result of the - * addition always fits in P length + 64 bits. - */ - } - -cleanup: - mbedtls_free(M); - mbedtls_free(A1); - - return ret; -} - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || - MBEDTLS_ECP_DP_SECP224K1_ENABLED) || - MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - -/* - * Fast quasi-reduction modulo p192k1 = 2^192 - R, - * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9 - */ -static int ecp_mod_p192k1(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(192) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p192k1_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00) - }; - - if (X_limbs != BITS_TO_LIMBS(192) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mod_koblitz(X, X_limbs, Rp, 192); -} - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - -/* - * Fast quasi-reduction modulo p224k1 = 2^224 - R, - * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 - */ -static int ecp_mod_p224k1(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(224) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p224k1_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00) - }; - - if (X_limbs != BITS_TO_LIMBS(224) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mod_koblitz(X, X_limbs, Rp, 224); -} - -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - -/* - * Fast quasi-reduction modulo p256k1 = 2^256 - R, - * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 - */ -static int ecp_mod_p256k1(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(256) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p256k1_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00) - }; - - if (X_limbs != BITS_TO_LIMBS(256) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mod_koblitz(X, X_limbs, Rp, 256); -} - -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_TEST_HOOKS) -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_ecp_group_id id, - const mbedtls_ecp_modulus_type ctype) -{ - mbedtls_mpi_modp_fn modp = NULL; - mbedtls_mpi_uint *p = NULL; - size_t p_limbs; - - if (!(ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE || \ - ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_SCALAR)) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - switch (id) { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p192_raw; -#endif - p = (mbedtls_mpi_uint *) secp192r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp192r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p224_raw; -#endif - p = (mbedtls_mpi_uint *) secp224r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp224r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p256_raw; -#endif - p = (mbedtls_mpi_uint *) secp256r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp256r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p384_raw; -#endif - p = (mbedtls_mpi_uint *) secp384r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp384r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p521_raw; -#endif - p = (mbedtls_mpi_uint *) secp521r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp521r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - p = (mbedtls_mpi_uint *) brainpoolP256r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_p)); - } else { - p = (mbedtls_mpi_uint *) brainpoolP256r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - p = (mbedtls_mpi_uint *) brainpoolP384r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_p)); - } else { - p = (mbedtls_mpi_uint *) brainpoolP384r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - p = (mbedtls_mpi_uint *) brainpoolP512r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_p)); - } else { - p = (mbedtls_mpi_uint *) brainpoolP512r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p255_raw; - p = (mbedtls_mpi_uint *) curve25519_p; - p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_p)); - } else { - p = (mbedtls_mpi_uint *) curve25519_n; - p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p192k1_raw; - p = (mbedtls_mpi_uint *) secp192k1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_p)); - } else { - p = (mbedtls_mpi_uint *) secp192k1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p224k1_raw; - p = (mbedtls_mpi_uint *) secp224k1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_p)); - } else { - p = (mbedtls_mpi_uint *) secp224k1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p256k1_raw; - p = (mbedtls_mpi_uint *) secp256k1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_p)); - } else { - p = (mbedtls_mpi_uint *) secp256k1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p448_raw; - p = (mbedtls_mpi_uint *) curve448_p; - p_limbs = CHARS_TO_LIMBS(sizeof(curve448_p)); - } else { - p = (mbedtls_mpi_uint *) curve448_n; - p_limbs = CHARS_TO_LIMBS(sizeof(curve448_n)); - } - break; -#endif - - default: - case MBEDTLS_ECP_DP_NONE: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - if (modp != NULL) { - if (mbedtls_mpi_mod_optred_modulus_setup(N, p, p_limbs, modp)) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - } else { - if (mbedtls_mpi_mod_modulus_setup(N, p, p_limbs)) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - } - return 0; -} -#endif /* MBEDTLS_TEST_HOOKS */ - -#if defined(MBEDTLS_TEST_HOOKS) - -MBEDTLS_STATIC_TESTABLE -mbedtls_ecp_variant mbedtls_ecp_get_variant(void) -{ - return MBEDTLS_ECP_VARIANT_WITH_MPI_UINT; -} - -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* !MBEDTLS_ECP_ALT */ -#endif /* MBEDTLS_ECP_LIGHT */ -#endif /* MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/thirdparty/mbedtls/library/lmots.c b/thirdparty/mbedtls/library/lmots.c deleted file mode 100644 index c51cb41ece..0000000000 --- a/thirdparty/mbedtls/library/lmots.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * The LM-OTS one-time public-key signature scheme - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following sources were referenced in the design of this implementation - * of the LM-OTS algorithm: - * - * [1] IETF RFC8554 - * D. McGrew, M. Curcio, S.Fluhrer - * https://datatracker.ietf.org/doc/html/rfc8554 - * - * [2] NIST Special Publication 800-208 - * David A. Cooper et. al. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_LMS_C) - -#include <string.h> - -#include "lmots.h" - -#include "mbedtls/lms.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "psa_util_internal.h" - -#include "psa/crypto.h" - -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_lms_errors, - ARRAY_LENGTH(psa_to_lms_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -#define PUBLIC_KEY_TYPE_OFFSET (0) -#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \ - MBEDTLS_LMOTS_TYPE_LEN) -#define PUBLIC_KEY_Q_LEAF_ID_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \ - MBEDTLS_LMOTS_I_KEY_ID_LEN) -#define PUBLIC_KEY_KEY_HASH_OFFSET (PUBLIC_KEY_Q_LEAF_ID_OFFSET + \ - MBEDTLS_LMOTS_Q_LEAF_ID_LEN) - -/* We only support parameter sets that use 8-bit digits, as it does not require - * translation logic between digits and bytes */ -#define W_WINTERNITZ_PARAMETER (8u) -#define CHECKSUM_LEN (2) -#define I_DIGIT_IDX_LEN (2) -#define J_HASH_IDX_LEN (1) -#define D_CONST_LEN (2) - -#define DIGIT_MAX_VALUE ((1u << W_WINTERNITZ_PARAMETER) - 1u) - -#define D_CONST_LEN (2) -static const unsigned char D_PUBLIC_CONSTANT_BYTES[D_CONST_LEN] = { 0x80, 0x80 }; -static const unsigned char D_MESSAGE_CONSTANT_BYTES[D_CONST_LEN] = { 0x81, 0x81 }; - -#if defined(MBEDTLS_TEST_HOOKS) -int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *) = NULL; -#endif /* defined(MBEDTLS_TEST_HOOKS) */ - -/* Calculate the checksum digits that are appended to the end of the LMOTS digit - * string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of - * the checksum algorithm. - * - * params The LMOTS parameter set, I and q values which - * describe the key being used. - * - * digest The digit string to create the digest from. As - * this does not contain a checksum, it is the same - * size as a hash output. - */ -static unsigned short lmots_checksum_calculate(const mbedtls_lmots_parameters_t *params, - const unsigned char *digest) -{ - size_t idx; - unsigned sum = 0; - - for (idx = 0; idx < MBEDTLS_LMOTS_N_HASH_LEN(params->type); idx++) { - sum += DIGIT_MAX_VALUE - digest[idx]; - } - - return sum; -} - -/* Create the string of digest digits (in the base determined by the Winternitz - * parameter with the checksum appended to the end (Q || cksm(Q)). See NIST - * SP800-208 section 3.1 or RFC8554 Algorithm 3 step 5 (also used in Algorithm - * 4b step 3) for details. - * - * params The LMOTS parameter set, I and q values which - * describe the key being used. - * - * msg The message that will be hashed to create the - * digest. - * - * msg_size The size of the message. - * - * C_random_value The random value that will be combined with the - * message digest. This is always the same size as a - * hash output for whichever hash algorithm is - * determined by the parameter set. - * - * output An output containing the digit string (+ - * checksum) of length P digits (in the case of - * MBEDTLS_LMOTS_SHA256_N32_W8, this means it is of - * size P bytes). - */ -static int create_digit_array_with_checksum(const mbedtls_lmots_parameters_t *params, - const unsigned char *msg, - size_t msg_len, - const unsigned char *C_random_value, - unsigned char *out) -{ - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned short checksum; - - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_MESSAGE_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, C_random_value, - MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, msg, msg_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, out, - MBEDTLS_LMOTS_N_HASH_LEN(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - checksum = lmots_checksum_calculate(params, out); - MBEDTLS_PUT_UINT16_BE(checksum, out, MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -/* Hash each element of the string of digits (+ checksum), producing a hash - * output for each element. This is used in several places (by varying the - * hash_idx_min/max_values) in order to calculate a public key from a private - * key (RFC8554 Algorithm 1 step 4), in order to sign a message (RFC8554 - * Algorithm 3 step 5), and to calculate a public key candidate from a - * signature and message (RFC8554 Algorithm 4b step 3). - * - * params The LMOTS parameter set, I and q values which - * describe the key being used. - * - * x_digit_array The array of digits (of size P, 34 in the case of - * MBEDTLS_LMOTS_SHA256_N32_W8). - * - * hash_idx_min_values An array of the starting values of the j iterator - * for each of the members of the digit array. If - * this value in NULL, then all iterators will start - * at 0. - * - * hash_idx_max_values An array of the upper bound values of the j - * iterator for each of the members of the digit - * array. If this value in NULL, then iterator is - * bounded to be less than 2^w - 1 (255 in the case - * of MBEDTLS_LMOTS_SHA256_N32_W8) - * - * output An array containing a hash output for each member - * of the digit string P. In the case of - * MBEDTLS_LMOTS_SHA256_N32_W8, this is of size 32 * - * 34. - */ -static int hash_digit_array(const mbedtls_lmots_parameters_t *params, - const unsigned char *x_digit_array, - const unsigned char *hash_idx_min_values, - const unsigned char *hash_idx_max_values, - unsigned char *output) -{ - unsigned int i_digit_idx; - unsigned char i_digit_idx_bytes[I_DIGIT_IDX_LEN]; - unsigned int j_hash_idx; - unsigned char j_hash_idx_bytes[J_HASH_IDX_LEN]; - unsigned int j_hash_idx_min; - unsigned int j_hash_idx_max; - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned char tmp_hash[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - - for (i_digit_idx = 0; - i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type); - i_digit_idx++) { - - memcpy(tmp_hash, - &x_digit_array[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)], - MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - - j_hash_idx_min = hash_idx_min_values != NULL ? - hash_idx_min_values[i_digit_idx] : 0; - j_hash_idx_max = hash_idx_max_values != NULL ? - hash_idx_max_values[i_digit_idx] : DIGIT_MAX_VALUE; - - for (j_hash_idx = j_hash_idx_min; - j_hash_idx < j_hash_idx_max; - j_hash_idx++) { - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - params->q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0); - status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - j_hash_idx_bytes[0] = (uint8_t) j_hash_idx; - status = psa_hash_update(&op, j_hash_idx_bytes, J_HASH_IDX_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, tmp_hash, - MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, tmp_hash, sizeof(tmp_hash), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - psa_hash_abort(&op); - } - - memcpy(&output[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)], - tmp_hash, MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - } - -exit: - psa_hash_abort(&op); - mbedtls_platform_zeroize(tmp_hash, sizeof(tmp_hash)); - - return PSA_TO_MBEDTLS_ERR(status); -} - -/* Combine the hashes of the digit array into a public key. This is used in - * in order to calculate a public key from a private key (RFC8554 Algorithm 1 - * step 4), and to calculate a public key candidate from a signature and message - * (RFC8554 Algorithm 4b step 3). - * - * params The LMOTS parameter set, I and q values which describe - * the key being used. - * y_hashed_digits The array of hashes, one hash for each digit of the - * symbol array (which is of size P, 34 in the case of - * MBEDTLS_LMOTS_SHA256_N32_W8) - * - * pub_key The output public key (or candidate public key in - * case this is being run as part of signature - * verification), in the form of a hash output. - */ -static int public_key_from_hashed_digit_array(const mbedtls_lmots_parameters_t *params, - const unsigned char *y_hashed_digits, - unsigned char *pub_key) -{ - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_PUBLIC_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, y_hashed_digits, - MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type) * - MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, pub_key, - MBEDTLS_LMOTS_N_HASH_LEN(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - -exit: - psa_hash_abort(&op); - } - - return PSA_TO_MBEDTLS_ERR(status); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_lms_error_from_psa(psa_status_t status) -{ - switch (status) { - case PSA_SUCCESS: - return 0; - case PSA_ERROR_HARDWARE_FAILURE: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - case PSA_ERROR_INVALID_ARGUMENT: - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - default: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(*ctx)); -} - -int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx, - const unsigned char *key, size_t key_len) -{ - if (key_len < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ctx->params.type = (mbedtls_lmots_algorithm_type_t) - MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); - - if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - memcpy(ctx->params.I_key_identifier, - key + PUBLIC_KEY_I_KEY_ID_OFFSET, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - - memcpy(ctx->params.q_leaf_identifier, - key + PUBLIC_KEY_Q_LEAF_ID_OFFSET, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - - memcpy(ctx->public_key, - key + PUBLIC_KEY_KEY_HASH_OFFSET, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - - ctx->have_public_key = 1; - - return 0; -} - -int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx, - unsigned char *key, size_t key_size, - size_t *key_len) -{ - if (key_size < MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); - - memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - - memcpy(key + PUBLIC_KEY_Q_LEAF_ID_OFFSET, - ctx->params.q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - - memcpy(key + PUBLIC_KEY_KEY_HASH_OFFSET, ctx->public_key, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - - if (key_len != NULL) { - *key_len = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type); - } - - return 0; -} - -int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params, - const unsigned char *msg, - size_t msg_size, - const unsigned char *sig, - size_t sig_size, - unsigned char *out, - size_t out_size, - size_t *out_len) -{ - unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX]; - unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (msg == NULL && msg_size != 0) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size != MBEDTLS_LMOTS_SIG_LEN(params->type) || - out_size < MBEDTLS_LMOTS_N_HASH_LEN(params->type)) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = create_digit_array_with_checksum(params, msg, msg_size, - sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, - tmp_digit_array); - if (ret) { - return ret; - } - - ret = hash_digit_array(params, - sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(params->type), - tmp_digit_array, NULL, (unsigned char *) y_hashed_digits); - if (ret) { - return ret; - } - - ret = public_key_from_hashed_digit_array(params, - (unsigned char *) y_hashed_digits, - out); - if (ret) { - return ret; - } - - if (out_len != NULL) { - *out_len = MBEDTLS_LMOTS_N_HASH_LEN(params->type); - } - - return 0; -} - -int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx, - const unsigned char *msg, size_t msg_size, - const unsigned char *sig, size_t sig_size) -{ - unsigned char Kc_public_key_candidate[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (msg == NULL && msg_size != 0) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.type != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (MBEDTLS_GET_UINT32_BE(sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET) != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - ret = mbedtls_lmots_calculate_public_key_candidate(&ctx->params, - msg, msg_size, sig, sig_size, - Kc_public_key_candidate, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type), - NULL); - if (ret) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (memcmp(&Kc_public_key_candidate, ctx->public_key, - sizeof(ctx->public_key))) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - return 0; -} - -#if defined(MBEDTLS_LMS_PRIVATE) - -void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, - sizeof(*ctx)); -} - -int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx, - mbedtls_lmots_algorithm_type_t type, - const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN], - uint32_t q_leaf_identifier, - const unsigned char *seed, - size_t seed_size) -{ - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned int i_digit_idx; - unsigned char i_digit_idx_bytes[2]; - unsigned char const_bytes[1] = { 0xFF }; - - if (ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (type != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ctx->params.type = type; - - memcpy(ctx->params.I_key_identifier, - I_key_identifier, - sizeof(ctx->params.I_key_identifier)); - - MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ctx->params.q_leaf_identifier, 0); - - for (i_digit_idx = 0; - i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type); - i_digit_idx++) { - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - ctx->params.I_key_identifier, - sizeof(ctx->params.I_key_identifier)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - ctx->params.q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0); - status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, const_bytes, sizeof(const_bytes)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, seed, seed_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, - ctx->private_key[i_digit_idx], - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - psa_hash_abort(&op); - } - - ctx->have_private_key = 1; - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx, - const mbedtls_lmots_private_t *priv_ctx) -{ - unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Check that a private key is loaded */ - if (!priv_ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = hash_digit_array(&priv_ctx->params, - (unsigned char *) priv_ctx->private_key, NULL, - NULL, (unsigned char *) y_hashed_digits); - if (ret) { - goto exit; - } - - ret = public_key_from_hashed_digit_array(&priv_ctx->params, - (unsigned char *) y_hashed_digits, - ctx->public_key); - if (ret) { - goto exit; - } - - memcpy(&ctx->params, &priv_ctx->params, - sizeof(ctx->params)); - - ctx->have_public_key = 1; - -exit: - mbedtls_platform_zeroize(y_hashed_digits, sizeof(y_hashed_digits)); - - return ret; -} - -int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *msg, size_t msg_size, - unsigned char *sig, size_t sig_size, size_t *sig_len) -{ - unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX]; - /* Create a temporary buffer to prepare the signature in. This allows us to - * finish creating a signature (ensuring the process doesn't fail), and then - * erase the private key **before** writing any data into the sig parameter - * buffer. If data were directly written into the sig buffer, it might leak - * a partial signature on failure, which effectively compromises the private - * key. - */ - unsigned char tmp_sig[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - unsigned char tmp_c_random[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (msg == NULL && msg_size != 0) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size < MBEDTLS_LMOTS_SIG_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - /* Check that a private key is loaded */ - if (!ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = f_rng(p_rng, tmp_c_random, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - if (ret) { - return ret; - } - - ret = create_digit_array_with_checksum(&ctx->params, - msg, msg_size, - tmp_c_random, - tmp_digit_array); - if (ret) { - goto exit; - } - - ret = hash_digit_array(&ctx->params, (unsigned char *) ctx->private_key, - NULL, tmp_digit_array, (unsigned char *) tmp_sig); - if (ret) { - goto exit; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); - - /* Test hook to check if sig is being written to before we invalidate the - * private key. - */ -#if defined(MBEDTLS_TEST_HOOKS) - if (mbedtls_lmots_sign_private_key_invalidated_hook != NULL) { - ret = (*mbedtls_lmots_sign_private_key_invalidated_hook)(sig); - if (ret != 0) { - return ret; - } - } -#endif /* defined(MBEDTLS_TEST_HOOKS) */ - - /* We've got a valid signature now, so it's time to make sure the private - * key can't be reused. - */ - ctx->have_private_key = 0; - mbedtls_platform_zeroize(ctx->private_key, - sizeof(ctx->private_key)); - - memcpy(sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, tmp_c_random, - MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(ctx->params.type)); - - memcpy(sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(ctx->params.type), tmp_sig, - MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type) - * MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - - if (sig_len != NULL) { - *sig_len = MBEDTLS_LMOTS_SIG_LEN(ctx->params.type); - } - - ret = 0; - -exit: - mbedtls_platform_zeroize(tmp_digit_array, sizeof(tmp_digit_array)); - mbedtls_platform_zeroize(tmp_sig, sizeof(tmp_sig)); - - return ret; -} - -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ -#endif /* defined(MBEDTLS_LMS_C) */ diff --git a/thirdparty/mbedtls/library/lms.c b/thirdparty/mbedtls/library/lms.c deleted file mode 100644 index 7f7bec068b..0000000000 --- a/thirdparty/mbedtls/library/lms.c +++ /dev/null @@ -1,769 +0,0 @@ -/* - * The LMS stateful-hash public-key signature scheme - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following sources were referenced in the design of this implementation - * of the LMS algorithm: - * - * [1] IETF RFC8554 - * D. McGrew, M. Curcio, S.Fluhrer - * https://datatracker.ietf.org/doc/html/rfc8554 - * - * [2] NIST Special Publication 800-208 - * David A. Cooper et. al. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_LMS_C) - -#include <string.h> - -#include "lmots.h" - -#include "psa/crypto.h" -#include "psa_util_internal.h" -#include "mbedtls/lms.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" - -#include "mbedtls/platform.h" - -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_lms_errors, - ARRAY_LENGTH(psa_to_lms_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -#define SIG_Q_LEAF_ID_OFFSET (0) -#define SIG_OTS_SIG_OFFSET (SIG_Q_LEAF_ID_OFFSET + \ - MBEDTLS_LMOTS_Q_LEAF_ID_LEN) -#define SIG_TYPE_OFFSET(otstype) (SIG_OTS_SIG_OFFSET + \ - MBEDTLS_LMOTS_SIG_LEN(otstype)) -#define SIG_PATH_OFFSET(otstype) (SIG_TYPE_OFFSET(otstype) + \ - MBEDTLS_LMS_TYPE_LEN) - -#define PUBLIC_KEY_TYPE_OFFSET (0) -#define PUBLIC_KEY_OTSTYPE_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \ - MBEDTLS_LMS_TYPE_LEN) -#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_OTSTYPE_OFFSET + \ - MBEDTLS_LMOTS_TYPE_LEN) -#define PUBLIC_KEY_ROOT_NODE_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \ - MBEDTLS_LMOTS_I_KEY_ID_LEN) - - -/* Currently only support H=10 */ -#define H_TREE_HEIGHT_MAX 10 -#define MERKLE_TREE_NODE_AM(type) ((size_t) 1 << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u)) -#define MERKLE_TREE_LEAF_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type)) -#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((unsigned int) \ - (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type))) - -#define D_CONST_LEN (2) -static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = { 0x82, 0x82 }; -static const unsigned char D_INTR_CONSTANT_BYTES[D_CONST_LEN] = { 0x83, 0x83 }; - - -/* Calculate the value of a leaf node of the Merkle tree (which is a hash of a - * public key and some other parameters like the leaf index). This function - * implements RFC8554 section 5.3, in the case where r >= 2^h. - * - * params The LMS parameter set, the underlying LMOTS - * parameter set, and I value which describe the key - * being used. - * - * pub_key The public key of the private whose index - * corresponds to the index of this leaf node. This - * is a hash output. - * - * r_node_idx The index of this node in the Merkle tree. Note - * that the root node of the Merkle tree is - * 1-indexed. - * - * out The output node value, which is a hash output. - */ -static int create_merkle_leaf_value(const mbedtls_lms_parameters_t *params, - unsigned char *pub_key, - unsigned int r_node_idx, - unsigned char *out) -{ - psa_hash_operation_t op; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned char r_node_idx_bytes[4]; - - op = psa_hash_operation_init(); - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0); - status = psa_hash_update(&op, r_node_idx_bytes, 4); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_LEAF_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, pub_key, - MBEDTLS_LMOTS_N_HASH_LEN(params->otstype)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -/* Calculate the value of an internal node of the Merkle tree (which is a hash - * of a public key and some other parameters like the node index). This function - * implements RFC8554 section 5.3, in the case where r < 2^h. - * - * params The LMS parameter set, the underlying LMOTS - * parameter set, and I value which describe the key - * being used. - * - * left_node The value of the child of this node which is on - * the left-hand side. As with all nodes on the - * Merkle tree, this is a hash output. - * - * right_node The value of the child of this node which is on - * the right-hand side. As with all nodes on the - * Merkle tree, this is a hash output. - * - * r_node_idx The index of this node in the Merkle tree. Note - * that the root node of the Merkle tree is - * 1-indexed. - * - * out The output node value, which is a hash output. - */ -static int create_merkle_internal_value(const mbedtls_lms_parameters_t *params, - const unsigned char *left_node, - const unsigned char *right_node, - unsigned int r_node_idx, - unsigned char *out) -{ - psa_hash_operation_t op; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned char r_node_idx_bytes[4]; - - op = psa_hash_operation_init(); - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0); - status = psa_hash_update(&op, r_node_idx_bytes, 4); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_INTR_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, left_node, - MBEDTLS_LMS_M_NODE_BYTES(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, right_node, - MBEDTLS_LMS_M_NODE_BYTES(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(*ctx)); -} - -int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx, - const unsigned char *key, size_t key_size) -{ - mbedtls_lms_algorithm_type_t type; - mbedtls_lmots_algorithm_type_t otstype; - - type = (mbedtls_lms_algorithm_type_t) MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET); - if (type != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - ctx->params.type = type; - - if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - otstype = (mbedtls_lmots_algorithm_type_t) - MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET); - if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - ctx->params.otstype = otstype; - - memcpy(ctx->params.I_key_identifier, - key + PUBLIC_KEY_I_KEY_ID_OFFSET, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - memcpy(ctx->T_1_pub_key, key + PUBLIC_KEY_ROOT_NODE_OFFSET, - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)); - - ctx->have_public_key = 1; - - return 0; -} - -int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx, - unsigned char *key, - size_t key_size, size_t *key_len) -{ - if (key_size < MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, PUBLIC_KEY_TYPE_OFFSET); - MBEDTLS_PUT_UINT32_BE(ctx->params.otstype, key, PUBLIC_KEY_OTSTYPE_OFFSET); - memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - memcpy(key +PUBLIC_KEY_ROOT_NODE_OFFSET, - ctx->T_1_pub_key, - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)); - - if (key_len != NULL) { - *key_len = MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type); - } - - return 0; -} - -int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx, - const unsigned char *msg, size_t msg_size, - const unsigned char *sig, size_t sig_size) -{ - unsigned int q_leaf_identifier; - unsigned char Kc_candidate_ots_pub_key[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - unsigned char Tc_candidate_root_node[MBEDTLS_LMS_M_NODE_BYTES_MAX]; - unsigned int height; - unsigned int curr_node_id; - unsigned int parent_node_id; - const unsigned char *left_node; - const unsigned char *right_node; - mbedtls_lmots_parameters_t ots_params; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.type - != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.otstype - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size != MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (sig_size < SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (MBEDTLS_GET_UINT32_BE(sig, SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_TYPE_OFFSET) - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (sig_size < SIG_TYPE_OFFSET(ctx->params.otstype) + MBEDTLS_LMS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (MBEDTLS_GET_UINT32_BE(sig, SIG_TYPE_OFFSET(ctx->params.otstype)) - != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - - q_leaf_identifier = MBEDTLS_GET_UINT32_BE(sig, SIG_Q_LEAF_ID_OFFSET); - - if (q_leaf_identifier >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - memcpy(ots_params.I_key_identifier, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ots_params.q_leaf_identifier, 0); - ots_params.type = ctx->params.otstype; - - ret = mbedtls_lmots_calculate_public_key_candidate(&ots_params, - msg, - msg_size, - sig + SIG_OTS_SIG_OFFSET, - MBEDTLS_LMOTS_SIG_LEN(ctx->params.otstype), - Kc_candidate_ots_pub_key, - sizeof(Kc_candidate_ots_pub_key), - NULL); - if (ret != 0) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - create_merkle_leaf_value( - &ctx->params, - Kc_candidate_ots_pub_key, - MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier, - Tc_candidate_root_node); - - curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + - q_leaf_identifier; - - for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type); - height++) { - parent_node_id = curr_node_id / 2; - - /* Left/right node ordering matters for the hash */ - if (curr_node_id & 1) { - left_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) + - height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); - right_node = Tc_candidate_root_node; - } else { - left_node = Tc_candidate_root_node; - right_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) + - height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); - } - - create_merkle_internal_value(&ctx->params, left_node, right_node, - parent_node_id, Tc_candidate_root_node); - - curr_node_id /= 2; - } - - if (memcmp(Tc_candidate_root_node, ctx->T_1_pub_key, - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type))) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - return 0; -} - -#if defined(MBEDTLS_LMS_PRIVATE) - -/* Calculate a full Merkle tree based on a private key. This function - * implements RFC8554 section 5.3, and is used to generate a public key (as the - * public key is the root node of the Merkle tree). - * - * ctx The LMS private context, containing a parameter - * set and private key material consisting of both - * public and private OTS. - * - * tree The output tree, which is 2^(H + 1) hash outputs. - * In the case of H=10 we have 2048 tree nodes (of - * which 1024 of them are leaf nodes). Note that - * because the Merkle tree root is 1-indexed, the 0 - * index tree node is never used. - */ -static int calculate_merkle_tree(const mbedtls_lms_private_t *ctx, - unsigned char *tree) -{ - unsigned int priv_key_idx; - unsigned int r_node_idx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* First create the leaf nodes, in ascending order */ - for (priv_key_idx = 0; - priv_key_idx < MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type); - priv_key_idx++) { - r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + priv_key_idx; - - ret = create_merkle_leaf_value(&ctx->params, - ctx->ots_public_keys[priv_key_idx].public_key, - r_node_idx, - &tree[r_node_idx * MBEDTLS_LMS_M_NODE_BYTES( - ctx->params.type)]); - if (ret != 0) { - return ret; - } - } - - /* Then the internal nodes, in reverse order so that we can guarantee the - * parent has been created */ - for (r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) - 1; - r_node_idx > 0; - r_node_idx--) { - ret = create_merkle_internal_value(&ctx->params, - &tree[(r_node_idx * 2) * - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)], - &tree[(r_node_idx * 2 + 1) * - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)], - r_node_idx, - &tree[r_node_idx * - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)]); - if (ret != 0) { - return ret; - } - } - - return 0; -} - -/* Calculate a path from a leaf node of the Merkle tree to the root of the tree, - * and return the full path. This function implements RFC8554 section 5.4.1, as - * the Merkle path is the main component of an LMS signature. - * - * ctx The LMS private context, containing a parameter - * set and private key material consisting of both - * public and private OTS. - * - * leaf_node_id Which leaf node to calculate the path from. - * - * path The output path, which is H hash outputs. - */ -static int get_merkle_path(mbedtls_lms_private_t *ctx, - unsigned int leaf_node_id, - unsigned char *path) -{ - const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); - unsigned int curr_node_id = leaf_node_id; - unsigned int adjacent_node_id; - unsigned char *tree = NULL; - unsigned int height; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(ctx->params.type), - node_bytes); - if (tree == NULL) { - return MBEDTLS_ERR_LMS_ALLOC_FAILED; - } - - ret = calculate_merkle_tree(ctx, tree); - if (ret != 0) { - goto exit; - } - - for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type); - height++) { - adjacent_node_id = curr_node_id ^ 1; - - memcpy(&path[height * node_bytes], - &tree[adjacent_node_id * node_bytes], node_bytes); - - curr_node_id >>= 1; - } - - ret = 0; - -exit: - mbedtls_zeroize_and_free(tree, node_bytes * - (size_t) MERKLE_TREE_NODE_AM(ctx->params.type)); - - return ret; -} - -void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx) -{ - if (ctx == NULL) { - return; - } - - unsigned int idx; - - if (ctx->have_private_key) { - if (ctx->ots_private_keys != NULL) { - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - mbedtls_lmots_private_free(&ctx->ots_private_keys[idx]); - } - } - - if (ctx->ots_public_keys != NULL) { - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - mbedtls_lmots_public_free(&ctx->ots_public_keys[idx]); - } - } - - mbedtls_free(ctx->ots_private_keys); - mbedtls_free(ctx->ots_public_keys); - } - - mbedtls_platform_zeroize(ctx, sizeof(*ctx)); -} - - -int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, - mbedtls_lms_algorithm_type_t type, - mbedtls_lmots_algorithm_type_t otstype, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *seed, - size_t seed_size) -{ - unsigned int idx = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (type != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ctx->params.type = type; - ctx->params.otstype = otstype; - ctx->have_private_key = 1; - - ret = f_rng(p_rng, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (ret != 0) { - goto exit; - } - - /* Requires a cast to size_t to avoid an implicit cast warning on certain - * platforms (particularly Windows) */ - ctx->ots_private_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type), - sizeof(*ctx->ots_private_keys)); - if (ctx->ots_private_keys == NULL) { - ret = MBEDTLS_ERR_LMS_ALLOC_FAILED; - goto exit; - } - - /* Requires a cast to size_t to avoid an implicit cast warning on certain - * platforms (particularly Windows) */ - ctx->ots_public_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type), - sizeof(*ctx->ots_public_keys)); - if (ctx->ots_public_keys == NULL) { - ret = MBEDTLS_ERR_LMS_ALLOC_FAILED; - goto exit; - } - - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - mbedtls_lmots_private_init(&ctx->ots_private_keys[idx]); - mbedtls_lmots_public_init(&ctx->ots_public_keys[idx]); - } - - - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - ret = mbedtls_lmots_generate_private_key(&ctx->ots_private_keys[idx], - otstype, - ctx->params.I_key_identifier, - idx, seed, seed_size); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_lmots_calculate_public_key(&ctx->ots_public_keys[idx], - &ctx->ots_private_keys[idx]); - if (ret != 0) { - goto exit; - } - } - - ctx->q_next_usable_key = 0; - -exit: - if (ret != 0) { - mbedtls_lms_private_free(ctx); - } - - return ret; -} - -int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx, - const mbedtls_lms_private_t *priv_ctx) -{ - const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(priv_ctx->params.type); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *tree = NULL; - - if (!priv_ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (priv_ctx->params.type - != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (priv_ctx->params.otstype - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type), - node_bytes); - if (tree == NULL) { - return MBEDTLS_ERR_LMS_ALLOC_FAILED; - } - - memcpy(&ctx->params, &priv_ctx->params, - sizeof(mbedtls_lmots_parameters_t)); - - ret = calculate_merkle_tree(priv_ctx, tree); - if (ret != 0) { - goto exit; - } - - /* Root node is always at position 1, due to 1-based indexing */ - memcpy(ctx->T_1_pub_key, &tree[node_bytes], node_bytes); - - ctx->have_public_key = 1; - - ret = 0; - -exit: - mbedtls_zeroize_and_free(tree, node_bytes * - (size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type)); - - return ret; -} - - -int mbedtls_lms_sign(mbedtls_lms_private_t *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *msg, - unsigned int msg_size, unsigned char *sig, size_t sig_size, - size_t *sig_len) -{ - uint32_t q_leaf_identifier; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (!ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size < MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - if (ctx->params.type != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.otstype - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->q_next_usable_key >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) { - return MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS; - } - - - q_leaf_identifier = ctx->q_next_usable_key; - /* This new value must _always_ be written back to the disk before the - * signature is returned. - */ - ctx->q_next_usable_key += 1; - - if (MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype) - < SIG_OTS_SIG_OFFSET) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = mbedtls_lmots_sign(&ctx->ots_private_keys[q_leaf_identifier], - f_rng, - p_rng, - msg, - msg_size, - sig + SIG_OTS_SIG_OFFSET, - MBEDTLS_LMS_SIG_LEN(ctx->params.type, - ctx->params.otstype) - SIG_OTS_SIG_OFFSET, - NULL); - if (ret != 0) { - return ret; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, SIG_TYPE_OFFSET(ctx->params.otstype)); - MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, sig, SIG_Q_LEAF_ID_OFFSET); - - ret = get_merkle_path(ctx, - MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier, - sig + SIG_PATH_OFFSET(ctx->params.otstype)); - if (ret != 0) { - return ret; - } - - if (sig_len != NULL) { - *sig_len = MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype); - } - - - return 0; -} - -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ -#endif /* defined(MBEDTLS_LMS_C) */ diff --git a/thirdparty/misc/smolv.cpp b/thirdparty/misc/smolv.cpp index 26ed7294f9..67b914606c 100644 --- a/thirdparty/misc/smolv.cpp +++ b/thirdparty/misc/smolv.cpp @@ -1,5 +1,5 @@ // smol-v - public domain - https://github.com/aras-p/smol-v -// authored 2016-2020 by Aras Pranckevicius +// authored 2016-2024 by Aras Pranckevicius // no warranty implied; use at your own risk // See end of file for license information. @@ -1197,8 +1197,8 @@ static bool smolv_CheckGenericHeader(const uint32_t* words, size_t wordCount, ui if (headerMagic != expectedMagic) return false; uint32_t headerVersion = words[1] & versionMask; - if (headerVersion < 0x00010000 || headerVersion > 0x00010500) - return false; // only support 1.0 through 1.5 + if (headerVersion < 0x00010000 || headerVersion > 0x00010600) + return false; // only support 1.0 through 1.6 return true; } @@ -2071,7 +2071,7 @@ void smolv::StatsPrint(const Stats* stats) // This software is available under 2 licenses -- choose whichever you prefer. // ------------------------------------------------------------------------------ // ALTERNATIVE A - MIT License -// Copyright (c) 2016-2020 Aras Pranckevicius +// Copyright (c) 2016-2024 Aras Pranckevicius // 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 diff --git a/thirdparty/misc/smolv.h b/thirdparty/misc/smolv.h index 798ee4126f..231dfc6f30 100644 --- a/thirdparty/misc/smolv.h +++ b/thirdparty/misc/smolv.h @@ -1,5 +1,5 @@ // smol-v - public domain - https://github.com/aras-p/smol-v -// authored 2016-2020 by Aras Pranckevicius +// authored 2016-2024 by Aras Pranckevicius // no warranty implied; use at your own risk // See end of file for license information. // @@ -132,7 +132,7 @@ namespace smolv // This software is available under 2 licenses -- choose whichever you prefer. // ------------------------------------------------------------------------------ // ALTERNATIVE A - MIT License -// Copyright (c) 2016-2020 Aras Pranckevicius +// Copyright (c) 2016-2024 Aras Pranckevicius // 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 diff --git a/thirdparty/openxr/patches/use-egl-from-glad.diff b/thirdparty/openxr/patches/use-egl-from-glad.diff new file mode 100644 index 0000000000..29c746d5c7 --- /dev/null +++ b/thirdparty/openxr/patches/use-egl-from-glad.diff @@ -0,0 +1,27 @@ +diff -Nur openxr-orig/src/common/xr_dependencies.h openxr/src/common/xr_dependencies.h +--- openxr-orig/src/common/xr_dependencies.h 2024-11-04 10:38:11.940682727 -0600 ++++ openxr/src/common/xr_dependencies.h 2024-11-04 10:38:46.351415476 -0600 +@@ -65,7 +65,11 @@ + #endif // XR_USE_GRAPHICS_API_OPENGL + + #ifdef XR_USE_GRAPHICS_API_OPENGL_ES ++#ifdef GLAD_ENABLED ++#include "thirdparty/glad/glad/egl.h" ++#else + #include <EGL/egl.h> ++#endif + #endif // XR_USE_GRAPHICS_API_OPENGL_ES + + #ifdef XR_USE_GRAPHICS_API_VULKAN +@@ -77,7 +81,11 @@ + #endif // XR_USE_PLATFORM_WAYLAND + + #ifdef XR_USE_PLATFORM_EGL ++#ifdef GLAD_ENABLED ++#include "thirdparty/glad/glad/egl.h" ++#else + #include <EGL/egl.h> ++#endif + #endif // XR_USE_PLATFORM_EGL + + #if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) diff --git a/thirdparty/openxr/src/common/xr_dependencies.h b/thirdparty/openxr/src/common/xr_dependencies.h index 55d93bfbac..a192a2ec6d 100644 --- a/thirdparty/openxr/src/common/xr_dependencies.h +++ b/thirdparty/openxr/src/common/xr_dependencies.h @@ -65,7 +65,11 @@ #endif // XR_USE_GRAPHICS_API_OPENGL #ifdef XR_USE_GRAPHICS_API_OPENGL_ES +#ifdef GLAD_ENABLED +#include "thirdparty/glad/glad/egl.h" +#else #include <EGL/egl.h> +#endif #endif // XR_USE_GRAPHICS_API_OPENGL_ES #ifdef XR_USE_GRAPHICS_API_VULKAN @@ -77,7 +81,11 @@ #endif // XR_USE_PLATFORM_WAYLAND #ifdef XR_USE_PLATFORM_EGL +#ifdef GLAD_ENABLED +#include "thirdparty/glad/glad/egl.h" +#else #include <EGL/egl.h> +#endif #endif // XR_USE_PLATFORM_EGL #if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) diff --git a/thirdparty/zlib/gzclose.c b/thirdparty/zlib/gzclose.c deleted file mode 100644 index 48d6a86f04..0000000000 --- a/thirdparty/zlib/gzclose.c +++ /dev/null @@ -1,23 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(gzFile file) { -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/thirdparty/zlib/gzlib.c b/thirdparty/zlib/gzlib.c deleted file mode 100644 index 983153cc8e..0000000000 --- a/thirdparty/zlib/gzlib.c +++ /dev/null @@ -1,582 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2024 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_WIN32) && !defined(__BORLANDC__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(gz_statep state) { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - else /* for writing ... */ - state->reset = 0; /* no deflateReset pending */ - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(const void *path, int fd, const char *mode) { - gz_statep state; - z_size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ -#ifdef WIDECHAR - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (z_size_t)-1) - len = 0; - } - else -#endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef WIDECHAR - if (fd == -2) - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - else -#endif -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->path, len + 1, "%s", (const char *)path); -#else - strcpy(state->path, path); -#endif - - /* compute the flags for open() */ - oflag = -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( -#ifdef WIDECHAR - fd == -2 ? _wopen(path, oflag, 0666) : -#endif - open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) { - LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ - state->mode = GZ_WRITE; /* simplify later checks */ - } - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(int fd, const char *mode) { - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); -#else - sprintf(path, "<fd:%d>", fd); /* for debugging */ -#endif - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(gzFile file, unsigned size) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if ((size << 1) < size) - return -1; /* need to be able to double it */ - if (size < 8) - size = 8; /* needed to behave well with flushing */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(gzFile file) { - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(gzFile file) { - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(gzFile file) { - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(gzFile file, int *errnum) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; - - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == - NULL) { - state->err = Z_MEM_ERROR; - return; - } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); -#else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); -#endif -} - -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax(void) { -#ifdef INT_MAX - return INT_MAX; -#else - unsigned p = 1, q; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -#endif -} diff --git a/thirdparty/zlib/gzread.c b/thirdparty/zlib/gzread.c deleted file mode 100644 index 4168cbc887..0000000000 --- a/thirdparty/zlib/gzread.c +++ /dev/null @@ -1,602 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(gz_statep state, unsigned char *buf, unsigned len, - unsigned *have) { - int ret; - unsigned get, max = ((unsigned)-1 >> 2) + 1; - - *have = 0; - do { - get = len - *have; - if (get > max) - get = max; - ret = read(state->fd, buf + *have, get); - if (ret <= 0) - break; - *have += (unsigned)ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(gz_statep state) { - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(gz_statep state) { - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(gz_statep state) { - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(gz_statep state) { - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(gz_statep state, z_off64_t len) { - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* Read len bytes into buf from file, or less than len up to the end of the - input. Return the number of bytes read. If zero is returned, either the - end of file was reached, or there was an error. state->err must be - consulted in that case to determine which. */ -local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { - z_size_t got; - unsigned n; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return 0; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* set n to the maximum amount of len that fits in an unsigned int */ - n = (unsigned)-1; - if (n > len) - n = (unsigned)len; - - /* first just try copying data from the output buffer */ - if (state->x.have) { - if (state->x.have < n) - n = state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || n < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return 0; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, n, &n) == -1) - return 0; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - state->strm.avail_out = n; - state->strm.next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return 0; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer */ - return got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); - return -1; - } - - /* read len or fewer bytes to buf */ - len = (unsigned)gz_read(state, buf, len); - - /* check for an error */ - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* return the number of bytes read (this is assured to fit in an int) */ - return (int)len; -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* read len or fewer bytes to buf, return the number of full items read */ - return len ? gz_read(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -#else -# undef gzgetc -#endif -int ZEXPORT gzgetc(gzFile file) { - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gz_read() */ - return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(gzFile file) { - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(int c, gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* in case this was just opened, set up the input buffer */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(gzFile file, char *buf, int len) { - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(gzFile file) { - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/thirdparty/zlib/gzwrite.c b/thirdparty/zlib/gzwrite.c deleted file mode 100644 index 435b4621b5..0000000000 --- a/thirdparty/zlib/gzwrite.c +++ /dev/null @@ -1,631 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004-2019 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on a memory allocation failure, or 0 on - success. */ -local int gz_init(gz_statep state) { - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer (double size for gzprintf) */ - state->in = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - strm->next_in = NULL; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file or if gz_init() - fails to allocate memory, otherwise 0. flush is assumed to be a valid - deflate() flush value. If flush is Z_FINISH, then the deflate() state is - reset to start a new gzip stream. If gz->direct is true, then simply write - to the output file without compressing, and ignore flush. */ -local int gz_comp(gz_statep state, int flush) { - int ret, writ; - unsigned have, put, max = ((unsigned)-1 >> 2) + 1; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - while (strm->avail_in) { - put = strm->avail_in > max ? max : strm->avail_in; - writ = write(state->fd, strm->next_in, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in -= (unsigned)writ; - strm->next_in += writ; - } - return 0; - } - - /* check for a pending reset */ - if (state->reset) { - /* don't start a new gzip member unless there is data to write */ - if (strm->avail_in == 0) - return 0; - deflateReset(strm); - state->reset = 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - while (strm->next_out > state->x.next) { - put = strm->next_out - state->x.next > (int)max ? max : - (unsigned)(strm->next_out - state->x.next); - writ = write(state->fd, state->x.next, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - state->x.next += writ; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = state->out; - } - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - state->reset = 1; - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on a write error or memory - allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(gz_statep state, z_off64_t len) { - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* Write len bytes from buf to file. Return the number of bytes written. If - the returned value is less than len, then there was an error. */ -local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { - z_size_t put = len; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - unsigned have, copy; - - if (state->strm.avail_in == 0) - state->strm.next_in = state->in; - have = (unsigned)((state->strm.next_in + state->strm.avail_in) - - state->in); - copy = state->size - have; - if (copy > len) - copy = (unsigned)len; - memcpy(state->in + have, buf, copy); - state->strm.avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - state->strm.next_in = (z_const Bytef *)buf; - do { - unsigned n = (unsigned)-1; - if (n > len) - n = (unsigned)len; - state->strm.avail_in = n; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - len -= n; - } while (len); - } - - /* input was all buffered or compressed */ - return put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* write len bytes from buf (the return value will fit in an int) */ - return (int)gz_write(state, buf, len); -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, - gzFile file) { - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* write len bytes to buf, return the number of full items written */ - return len ? gz_write(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(gzFile file, int c) { - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = (unsigned char)c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = (unsigned char)c; - if (gz_write(state, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(gzFile file, const char *s) { - z_size_t len, put; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* write string */ - len = strlen(s); - if ((int)len < 0 || (unsigned)len != len) { - gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); - return -1; - } - put = gz_write(state, s, len); - return put < len ? -1 : (int)len; -} - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include <stdarg.h> - -/* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { - int len; - unsigned left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->err; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(next, format, va); - for (len = 0; len < state->size; len++) - if (next[len] == 0) break; -# else - len = vsprintf(next, format, va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(next, state->size, format, va); - len = strlen(next); -# else - len = vsnprintf(next, state->size, format, va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += (unsigned)len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memmove(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return len; -} - -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, - int a4, int a5, int a6, int a7, int a8, int a9, int a10, - int a11, int a12, int a13, int a14, int a15, int a16, - int a17, int a18, int a19, int a20) { - unsigned len, left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return Z_STREAM_ERROR; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->error; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->error; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(strm->next_in + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, - a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (next[len] == 0) - break; -# else - len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, - a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(next); -# else - len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memmove(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return (int)len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(gzFile file, int flush) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* compress remaining data with requested flush */ - (void)gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(gzFile file) { - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} |